diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -5319,6 +5319,11 @@ return ESR; } + // In error-recovery cases it's possible to get here even if we failed to + // synthesize the __begin and __end variables. + if (!FS->getBeginStmt() || !FS->getEndStmt() || !FS->getCond()) + return ESR_Failed; + // Create the __begin and __end iterators. ESR = EvaluateStmt(Result, Info, FS->getBeginStmt()); if (ESR != ESR_Succeeded) { diff --git a/clang/test/SemaCXX/constexpr-function-recovery-crash.cpp b/clang/test/SemaCXX/constexpr-function-recovery-crash.cpp --- a/clang/test/SemaCXX/constexpr-function-recovery-crash.cpp +++ b/clang/test/SemaCXX/constexpr-function-recovery-crash.cpp @@ -69,3 +69,8 @@ constexpr int test10() { return undef(); } // expected-error {{use of undeclared identifier 'undef'}} static_assert(test10() <= 1, "should not crash"); // expected-error {{static_assert expression is not an integral constant expression}} + +struct X {} array[] = {undef()}; // expected-error {{use of undeclared identifier 'undef'}} +constexpr void test11() { + for (X& e : array) {} +}