hokein created this revision. hokein added a reviewer: sammccall. Herald added a project: clang.
Tested with enabling "-frecovery-ast", only 1 failure, which is an improvement of secondary diagnostic. -- error: 'error' diagnostics seen but not expected: File /workspace/llvm-project/clang/test/SemaTemplate/instantiate-expr-3.cpp Line 68: invalid operands to binary expression ('N1::X' and 'int') 1 error generated. -- Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D81163 Files: clang/lib/Sema/SemaExpr.cpp clang/test/AST/ast-dump-recovery.cpp Index: clang/test/AST/ast-dump-recovery.cpp =================================================================== --- clang/test/AST/ast-dump-recovery.cpp +++ clang/test/AST/ast-dump-recovery.cpp @@ -211,3 +211,30 @@ } NoCrashOnInvalidInitList = { .abc = nullptr, }; + +void InvalidCondition() { + // CHECK: IfStmt {{.*}} + // CHECK-NEXT: |-RecoveryExpr {{.*}} <col:7, col:15> '<dependent type>' contains-errors + // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}} <col:7> + if (invalid()) {} + + // CHECK: WhileStmt {{.*}} + // CHECK-NEXT: |-RecoveryExpr {{.*}} <col:10, col:18> '<dependent type>' contains-errors + // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}} <col:10> + while (invalid()) {} + + // CHECK: SwitchStmt {{.*}} + // CHECK-NEXT: |-RecoveryExpr {{.*}} '<dependent type>' contains-errors + // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}} <col:10> + switch(invalid()) { + case 1: + break; + } + // FIXME: figure out why the type of ConditionalOperator is not int. + // CHECK: ConditionalOperator {{.*}} '<dependent type>' contains-errors + // CHECK-NEXT: |-RecoveryExpr {{.*}} '<dependent type>' contains-errors + // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}} + // CHECK-NEXT: |-IntegerLiteral {{.*}} 'int' 1 + // CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 2 + invalid() ? 1 : 2; +} Index: clang/lib/Sema/SemaExpr.cpp =================================================================== --- clang/lib/Sema/SemaExpr.cpp +++ clang/lib/Sema/SemaExpr.cpp @@ -18420,9 +18420,12 @@ Cond = CheckSwitchCondition(Loc, SubExpr); break; } - if (Cond.isInvalid()) - return ConditionError(); - + if (Cond.isInvalid()) { + Cond = CreateRecoveryExpr(SubExpr->getBeginLoc(), SubExpr->getEndLoc(), + {SubExpr}); + if (!Cond.get()) + return ConditionError(); + } // FIXME: FullExprArg doesn't have an invalid bit, so check nullness instead. FullExprArg FullExpr = MakeFullExpr(Cond.get(), Loc); if (!FullExpr.get())
Index: clang/test/AST/ast-dump-recovery.cpp =================================================================== --- clang/test/AST/ast-dump-recovery.cpp +++ clang/test/AST/ast-dump-recovery.cpp @@ -211,3 +211,30 @@ } NoCrashOnInvalidInitList = { .abc = nullptr, }; + +void InvalidCondition() { + // CHECK: IfStmt {{.*}} + // CHECK-NEXT: |-RecoveryExpr {{.*}} <col:7, col:15> '<dependent type>' contains-errors + // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}} <col:7> + if (invalid()) {} + + // CHECK: WhileStmt {{.*}} + // CHECK-NEXT: |-RecoveryExpr {{.*}} <col:10, col:18> '<dependent type>' contains-errors + // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}} <col:10> + while (invalid()) {} + + // CHECK: SwitchStmt {{.*}} + // CHECK-NEXT: |-RecoveryExpr {{.*}} '<dependent type>' contains-errors + // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}} <col:10> + switch(invalid()) { + case 1: + break; + } + // FIXME: figure out why the type of ConditionalOperator is not int. + // CHECK: ConditionalOperator {{.*}} '<dependent type>' contains-errors + // CHECK-NEXT: |-RecoveryExpr {{.*}} '<dependent type>' contains-errors + // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}} + // CHECK-NEXT: |-IntegerLiteral {{.*}} 'int' 1 + // CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 2 + invalid() ? 1 : 2; +} Index: clang/lib/Sema/SemaExpr.cpp =================================================================== --- clang/lib/Sema/SemaExpr.cpp +++ clang/lib/Sema/SemaExpr.cpp @@ -18420,9 +18420,12 @@ Cond = CheckSwitchCondition(Loc, SubExpr); break; } - if (Cond.isInvalid()) - return ConditionError(); - + if (Cond.isInvalid()) { + Cond = CreateRecoveryExpr(SubExpr->getBeginLoc(), SubExpr->getEndLoc(), + {SubExpr}); + if (!Cond.get()) + return ConditionError(); + } // FIXME: FullExprArg doesn't have an invalid bit, so check nullness instead. FullExprArg FullExpr = MakeFullExpr(Cond.get(), Loc); if (!FullExpr.get())
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits