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