diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -3740,6 +3740,9 @@ NullPointerConstantValueDependence NPC) const { if (isValueDependent() && (!Ctx.getLangOpts().CPlusPlus11 || Ctx.getLangOpts().MSVCCompat)) { + // Error-dependent expr should never be a null pointer. + if (containsErrors()) + return NPCK_NotNull; switch (NPC) { case NPC_NeverValueDependent: llvm_unreachable("Unexpected value dependent expression!"); diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -539,8 +539,10 @@ if (VK == VK_RValue && !E->isRValue()) { switch (Kind) { default: - llvm_unreachable("can't implicitly cast lvalue to rvalue with this cast " - "kind"); + llvm_unreachable(("can't implicitly cast lvalue to rvalue with this cast " + "kind: " + + std::string(CastExpr::getCastKindName(Kind))) + .c_str()); case CK_Dependent: case CK_LValueToRValue: case CK_ArrayToPointerDecay: diff --git a/clang/test/AST/ast-dump-recovery.c b/clang/test/AST/ast-dump-recovery.c --- a/clang/test/AST/ast-dump-recovery.c +++ b/clang/test/AST/ast-dump-recovery.c @@ -39,3 +39,14 @@ // CHECK-NEXT: `-DeclRefExpr {{.*}} 'a' 'const int' static int foo = a++; // verify no crash on local static var decl. } + +void test2() { + int* ptr; + // FIXME: the top-level expr should be a binary operator. + // CHECK: ImplicitCastExpr {{.*}} contains-errors + // CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors lvalue + // CHECK-NEXT: |-DeclRefExpr {{.*}} 'ptr' 'int *' + // CHECK-NEXT: `-RecoveryExpr {{.*}} + // CHECK-NEXT: `-DeclRefExpr {{.*}} 'some_func' + ptr = some_func(); // should not crash +}