Index: clang/docs/ReleaseNotes.rst =================================================================== --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -118,6 +118,8 @@ C++20 Feature Support ^^^^^^^^^^^^^^^^^^^^^ +- Diagnose consteval and constexpr issues that happen at namespace scope. This + partially addresses `Issue 51593 `_. C++2b Feature Support ^^^^^^^^^^^^^^^^^^^^^ Index: clang/lib/Parse/ParseAST.cpp =================================================================== --- clang/lib/Parse/ParseAST.cpp +++ clang/lib/Parse/ParseAST.cpp @@ -155,6 +155,9 @@ P.Initialize(); Parser::DeclGroupPtrTy ADecl; Sema::ModuleImportState ImportState; + EnterExpressionEvaluationContext PotentiallyEvaluated( + S, Sema::ExpressionEvaluationContext::PotentiallyEvaluated); + for (bool AtEOF = P.ParseFirstTopLevelDecl(ADecl, ImportState); !AtEOF; AtEOF = P.ParseTopLevelDecl(ADecl, ImportState)) { // If we got a null return and something *was* parsed, ignore it. This Index: clang/lib/Sema/Sema.cpp =================================================================== --- clang/lib/Sema/Sema.cpp +++ clang/lib/Sema/Sema.cpp @@ -233,6 +233,9 @@ // Tell diagnostics how to render things from the AST library. Diags.SetArgToStringFn(&FormatASTNodeDiagnosticArgument, &Context); + // This evaluation context exists to ensure that there's always at least one + // valid evaluation context available. It is never removed from the + // evaluation stack. ExprEvalContexts.emplace_back( ExpressionEvaluationContext::PotentiallyEvaluated, 0, CleanupInfo{}, nullptr, ExpressionEvaluationContextRecord::EK_Other); Index: clang/test/SemaCXX/cxx2a-consteval.cpp =================================================================== --- clang/test/SemaCXX/cxx2a-consteval.cpp +++ clang/test/SemaCXX/cxx2a-consteval.cpp @@ -689,3 +689,23 @@ } }; } // PR48235 + +namespace NamespaceScopeConsteval { +struct S { + int Val; // expected-note {{subobject declared here}} + consteval S() {} +}; + +S s1; // expected-error {{call to consteval function 'NamespaceScopeConsteval::S::S' is not a constant expression}} \ + expected-note {{subobject of type 'int' is not initialized}} + +template +struct T { + Ty Val; // expected-note {{subobject declared here}} + consteval T() {} +}; + +T t; // expected-error {{call to consteval function 'NamespaceScopeConsteval::T::T' is not a constant expression}} \ + expected-note {{subobject of type 'int' is not initialized}} + +} // namespace NamespaceScopeConsteval