summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlivier Goffart <ogoffart@woboq.com>2015-10-11 17:27:29 +0000
committerOlivier Goffart <ogoffart@woboq.com>2015-10-11 17:27:29 +0000
commit122993bfd69de0501a0eff387c7468ea30f18809 (patch)
treeb4105793f25f27ed0554bc0270a12bfd77e71491
parent602b0e1f0bf1b01f59aa174703a2c691272db2a7 (diff)
downloadbcm5719-llvm-122993bfd69de0501a0eff387c7468ea30f18809.tar.gz
bcm5719-llvm-122993bfd69de0501a0eff387c7468ea30f18809.zip
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 llvm-svn: 249982
-rw-r--r--clang/lib/Sema/SemaStmt.cpp28
-rw-r--r--clang/test/Misc/ast-dump-invalid.cpp23
2 files changed, 34 insertions, 17 deletions
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index e876fa921e1..0afff06f15d 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/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;
@@ -497,22 +490,23 @@ Sema::ActOnIfStmt(SourceLocation IfLoc, FullExprArg CondVal, Decl *CondVar,
ConditionVar = cast<VarDecl>(CondVar);
CondResult = CheckConditionVariable(ConditionVar, IfLoc, true);
CondResult = ActOnFinishFullExpr(CondResult.get(), IfLoc);
- if (CondResult.isInvalid())
- 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);
+ } else {
+ // Create a dummy Expr for the condition for error recovery
+ ConditionExpr = new (Context) OpaqueValueExpr(SourceLocation(),
+ Context.BoolTy, VK_RValue);
}
- DiagnoseUnusedExprResult(elseStmt);
-
return new (Context) IfStmt(Context, IfLoc, ConditionVar, ConditionExpr,
thenStmt, ElseLoc, elseStmt);
}
diff --git a/clang/test/Misc/ast-dump-invalid.cpp b/clang/test/Misc/ast-dump-invalid.cpp
index 3b97cc65409..7b02ba11133 100644
--- a/clang/test/Misc/ast-dump-invalid.cpp
+++ b/clang/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: |-OpaqueValueExpr {{.*}} <<invalid sloc>> '_Bool'
+// 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'
+
OpenPOWER on IntegriCloud