[clang] 1c55f05 - Properly diagnose constant evaluation issues at TU scope

Aaron Ballman via cfe-commits cfe-commits at lists.llvm.org
Tue Mar 8 07:19:24 PST 2022


Author: Aaron Ballman
Date: 2022-03-08T10:19:15-05:00
New Revision: 1c55f05c6a6b58f8cc7b15a37e79753fb8abe3e3

URL: https://github.com/llvm/llvm-project/commit/1c55f05c6a6b58f8cc7b15a37e79753fb8abe3e3
DIFF: https://github.com/llvm/llvm-project/commit/1c55f05c6a6b58f8cc7b15a37e79753fb8abe3e3.diff

LOG: Properly diagnose constant evaluation issues at TU scope

We were not creating an evaluation context for the TU scope, so we
never popped an evaluation context for it. Popping the evaluation
context triggers a number of diagnostics, including warnings about
immediate invocations that we were previously missing.

Note: I think we have an additional issue that we should solve, but not
as part of this patch. I don't think Clang is properly modeling static
initialization as happening before constant expression evaluation. I
think structure members members are zero initialized per
http://eel.is/c++draft/basic.start.static#1,
https://eel.is/c++draft/basic.start.static#2.sentence-2, and
http://eel.is/c++draft/dcl.init#general-6.2 and the new test case
actually should be accepted. However, it's also worth noting that other
compilers behave the way this patch makes Clang behave:
https://godbolt.org/z/T7noqhdPr

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/Parse/ParseAST.cpp
    clang/lib/Sema/Sema.cpp
    clang/test/SemaCXX/cxx2a-consteval.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index d5f6c2d730f59..662d4b1b2443e 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -118,6 +118,8 @@ C++ Language Changes in Clang
 
 C++20 Feature Support
 ^^^^^^^^^^^^^^^^^^^^^
+- Diagnose consteval and constexpr issues that happen at namespace scope. This
+  partially addresses `Issue 51593 <https://github.com/llvm/llvm-project/issues/51593>`_.
 
 C++2b Feature Support
 ^^^^^^^^^^^^^^^^^^^^^

diff  --git a/clang/lib/Parse/ParseAST.cpp b/clang/lib/Parse/ParseAST.cpp
index fd79ed3ca158b..04b3f0460bf3e 100644
--- a/clang/lib/Parse/ParseAST.cpp
+++ b/clang/lib/Parse/ParseAST.cpp
@@ -155,6 +155,9 @@ void clang::ParseAST(Sema &S, bool PrintStats, bool SkipFunctionBodies) {
     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

diff  --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index f1dc02d0b6dd9..ed868a9c00736 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -233,6 +233,9 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
   // 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);

diff  --git a/clang/test/SemaCXX/cxx2a-consteval.cpp b/clang/test/SemaCXX/cxx2a-consteval.cpp
index 941d47dcb055e..4d59261104ed2 100644
--- a/clang/test/SemaCXX/cxx2a-consteval.cpp
+++ b/clang/test/SemaCXX/cxx2a-consteval.cpp
@@ -689,3 +689,23 @@ struct A {
   }
 };
 } // 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 <typename Ty>
+struct T {
+  Ty Val; // expected-note {{subobject declared here}}
+  consteval T() {}
+};
+
+T<int> t; // expected-error {{call to consteval function 'NamespaceScopeConsteval::T<int>::T' is not a constant expression}} \
+             expected-note {{subobject of type 'int' is not initialized}}
+
+} // namespace NamespaceScopeConsteval


        


More information about the cfe-commits mailing list