diff --git a/clang/lib/AST/Interp/EvaluationResult.cpp b/clang/lib/AST/Interp/EvaluationResult.cpp index 387e3dc88bff26..395e3f5b4348d8 100644 --- a/clang/lib/AST/Interp/EvaluationResult.cpp +++ b/clang/lib/AST/Interp/EvaluationResult.cpp @@ -141,7 +141,9 @@ bool EvaluationResult::checkFullyInitialized(InterpState &S, const Pointer &Ptr) const { assert(Source); assert(empty()); - assert(!Ptr.isZero()); + + if (Ptr.isZero()) + return true; SourceLocation InitLoc; if (const auto *D = Source.dyn_cast()) diff --git a/clang/test/AST/Interp/cxx20.cpp b/clang/test/AST/Interp/cxx20.cpp index 434823644a7a38..2faacbbf70fd7a 100644 --- a/clang/test/AST/Interp/cxx20.cpp +++ b/clang/test/AST/Interp/cxx20.cpp @@ -814,3 +814,16 @@ namespace GH64949 { // both-note {{subobject 'g' is not initialized}} \ // both-warning {{expression result unused}} } + +/// This used to cause an assertion failure inside EvaluationResult::checkFullyInitialized. +namespace CheckingNullPtrForInitialization { + struct X { + consteval operator const char *() const { + return nullptr; + } + }; + const char *f() { + constexpr X x; + return x; + } +}