forked from OSchip/llvm-project
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
This commit is contained in:
parent
602b0e1f0b
commit
122993bfd6
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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'
|
||||
|
||||
|
|
Loading…
Reference in New Issue