Hi, 

Please review the attached patch. It does not discard the full 'if' statement 
if the condition is invalid.

This is quite useful for IDE's or other tools which would like to recover as 
much as possible even if there are a few errors in the code, and discarding 
the full 'if' bodies is unfortunate.

Thanks.
-- 
Olivier


P.S: For the same reason, i'm also trying to fix the fact that if there is any 
typo in an expression statement, the full statement is discarded. The reason 
is i believe that Sema::CorrectDelayedTyposInExpr just return null if any typo 
could not be corrected. That's unrelated to this patch, but i still would 
welcome hint on how to fix it.  Should CorrectDelayedTyposInExpr somehow 
replace the TypoExpr instead of removing them? Or should it create a new node 
(some kind of error ErrorExpr)? Or should the caller of 
CorrectDelayedTyposInExpr be changed to keep the original?
>From 8f5f74755cfa0c6165caff65dcc07b0d2543f481 Mon Sep 17 00:00:00 2001
From: Olivier Goffart <ogoff...@woboq.com>
Date: Sat, 12 Sep 2015 16:09:34 +0200
Subject: [PATCH] Keep the IfStmt node even if the condition is invalid

This is important to keep the information in IDE or other tools
even if the code contains a few errors
---
 lib/Sema/SemaStmt.cpp          | 22 +++++++---------------
 test/Misc/ast-dump-invalid.cpp | 23 +++++++++++++++++++++++
 2 files changed, 30 insertions(+), 15 deletions(-)

diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index c39c80d..97a1160 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -483,13 +483,6 @@ StmtResult
 Sema::ActOnIfStmt(SourceLocation IfLoc, FullExprArg CondVal, Decl *CondVar,
                   Stmt *thenStmt, SourceLocation ElseLoc,
                   Stmt *elseStmt) {
-  // If the condition was invalid, discard the if statement.  We could recover
-  // better by replacing it with a valid expr, but don't do that yet.
-  if (!CondVal.get() && !CondVar) {
-    getCurFunction()->setHasDroppedStmt();
-    return StmtError();
-  }
-
   ExprResult CondResult(CondVal.release());
 
   VarDecl *ConditionVar = nullptr;
@@ -501,18 +494,17 @@ Sema::ActOnIfStmt(SourceLocation IfLoc, FullExprArg CondVal, Decl *CondVar,
       return StmtError();
   }
   Expr *ConditionExpr = CondResult.getAs<Expr>();
-  if (!ConditionExpr)
-    return StmtError();
+  if (ConditionExpr) {
+    DiagnoseUnusedExprResult(thenStmt);
 
-  DiagnoseUnusedExprResult(thenStmt);
+    if (!elseStmt) {
+      DiagnoseEmptyStmtBody(ConditionExpr->getLocEnd(), thenStmt,
+                            diag::warn_empty_if_body);
+    }
 
-  if (!elseStmt) {
-    DiagnoseEmptyStmtBody(ConditionExpr->getLocEnd(), thenStmt,
-                          diag::warn_empty_if_body);
+    DiagnoseUnusedExprResult(elseStmt);
   }
 
-  DiagnoseUnusedExprResult(elseStmt);
-
   return new (Context) IfStmt(Context, IfLoc, ConditionVar, ConditionExpr,
                               thenStmt, ElseLoc, elseStmt);
 }
diff --git a/test/Misc/ast-dump-invalid.cpp b/test/Misc/ast-dump-invalid.cpp
index 3b97cc6..899bfa0 100644
--- a/test/Misc/ast-dump-invalid.cpp
+++ b/test/Misc/ast-dump-invalid.cpp
@@ -18,3 +18,26 @@ void f(T i, T j) {
 // CHECK-NEXT:         `-CXXUnresolvedConstructExpr {{.*}} <col:10, col:16> 'T'
 // CHECK-NEXT:           |-DeclRefExpr {{.*}} <col:13> 'T' lvalue ParmVar {{.*}} 'i' 'T'
 // CHECK-NEXT:           `-DeclRefExpr {{.*}} <col:16> 'T' lvalue ParmVar {{.*}} 'j' 'T'
+
+
+namespace TestInvalidIf {
+int g(int i) {
+  if (invalid_condition)
+    return 4;
+  else
+    return i;
+}
+}
+// CHECK: NamespaceDecl {{.*}} <{{.*}}> {{.*}} TestInvalidIf
+// CHECK-NEXT: `-FunctionDecl
+// CHECK-NEXT:   |-ParmVarDecl
+// CHECK-NEXT:   `-CompoundStmt
+// CHECK-NEXT:     `-IfStmt {{.*}} <line:25:3, line:28:12>
+// CHECK-NEXT:       |-<<<NULL>>>
+// CHECK-NEXT:       |-<<<NULL>>>
+// CHECK-NEXT:       |-ReturnStmt {{.*}} <line:26:5, col:12>
+// CHECK-NEXT:       | `-IntegerLiteral {{.*}} <col:12> 'int' 4
+// CHECK-NEXT:       `-ReturnStmt {{.*}} <line:28:5, col:12>
+// CHECK-NEXT:         `-ImplicitCastExpr {{.*}} <col:12> 'int' <LValueToRValue>
+// CHECK-NEXT:           `-DeclRefExpr {{.*}} <col:12> 'int' lvalue ParmVar {{.*}} 'i' 'int'
+
-- 
2.6.0

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to