cor3ntin updated this revision to Diff 400317.
cor3ntin added a comment.

Fix tests


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D111400/new/

https://reviews.llvm.org/D111400

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Frontend/InitPreprocessor.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/CXX/basic/basic.types/p10.cpp
  clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/dtor.cpp
  clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp
  clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp
  clang/test/Lexer/cxx-features.cpp
  clang/test/SemaCXX/constant-expression-cxx14.cpp
  clang/test/SemaCXX/constant-expression-cxx2b.cpp
  clang/test/SemaCXX/cxx1z-constexpr-lambdas.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===================================================================
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -1358,7 +1358,7 @@
     <tr>
       <td>Non-literal variables (and labels and gotos) in constexpr functions</td>
       <td><a href="https://wg21.link/P2242R3";>P2242R3</a></td>
-      <td class="none" align="center">No</td>
+      <td class="unreleased" align="center">Clang 14</td>
     </tr>
     <tr>
       <td>Character encoding of diagnostic text</td>
Index: clang/test/SemaCXX/cxx1z-constexpr-lambdas.cpp
===================================================================
--- clang/test/SemaCXX/cxx1z-constexpr-lambdas.cpp
+++ clang/test/SemaCXX/cxx1z-constexpr-lambdas.cpp
@@ -115,11 +115,6 @@
 constexpr const char *Str = "abc";
 static_assert(fp4(Str) == Str);
 
-auto NCL = [](int i) { static int j; return j; }; //expected-note{{declared here}}
-constexpr int (*fp5)(int) = NCL;
-constexpr int I =  //expected-error{{must be initialized by a constant expression}}
-                  fp5(5); //expected-note{{non-constexpr function}} 
-
 namespace test_dont_always_instantiate_constexpr_templates {
 
 auto explicit_return_type = [](auto x) -> int { return x.get(); };
Index: clang/test/SemaCXX/constant-expression-cxx2b.cpp
===================================================================
--- /dev/null
+++ clang/test/SemaCXX/constant-expression-cxx2b.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -std=c++2b -fsyntax-only -verify %s -fcxx-exceptions -triple=x86_64-linux-gnu
+
+constexpr int f(int n) {  // expected-error {{constexpr function never produces a constant expression}}
+  static const int m = n; //  expected-note {{declared here}}
+  return m;               //  expected-note {{initializer of 'm' is not a constant expression}}
+}
+constexpr int g(int n) {        // expected-error {{constexpr function never produces a constant expression}}
+  thread_local const int m = n; //  expected-note {{declared here}}
+  return m;                     //  expected-note {{initializer of 'm' is not a constant expression}}
+}
+
+constexpr int h(int n) {
+  if (!n)
+    return 0;
+  static const int m = n;
+  return m;
+}
+constexpr int i(int n) {
+  if (!n)
+    return 0;
+  thread_local const int m = n;
+  return m;
+}
Index: clang/test/SemaCXX/constant-expression-cxx14.cpp
===================================================================
--- clang/test/SemaCXX/constant-expression-cxx14.cpp
+++ clang/test/SemaCXX/constant-expression-cxx14.cpp
@@ -44,14 +44,6 @@
   return 3 * k3 + 5 * k2 + n * k - 20;
 }
 static_assert(g(2) == 42, "");
-constexpr int h(int n) {
-  static const int m = n; // expected-error {{static variable not permitted in a constexpr function}}
-  return m;
-}
-constexpr int i(int n) {
-  thread_local const int m = n; // expected-error {{thread_local variable not permitted in a constexpr function}}
-  return m;
-}
 
 // if-statements can be used in constexpr functions.
 constexpr int j(int k) {
@@ -65,7 +57,9 @@
       return 2;
     }
   }
-} // expected-note 2{{control reached end of constexpr function}}
+} // expected-warning {{non-void}} \
+  //expected-note 2{{control reached end of constexpr function}}
+
 static_assert(j(0) == -3, "");
 static_assert(j(1) == 5, "");
 static_assert(j(2), ""); // expected-error {{constant expression}} expected-note {{in call to 'j(2)'}}
Index: clang/test/Lexer/cxx-features.cpp
===================================================================
--- clang/test/Lexer/cxx-features.cpp
+++ clang/test/Lexer/cxx-features.cpp
@@ -277,7 +277,7 @@
 #error "wrong value for __cpp_lambdas"
 #endif
 
-#if check(constexpr, 0, 200704, 201304, 201603, 201907, 201907)
+#if check(constexpr, 0, 200704, 201304, 201603, 201907, 202110)
 #error "wrong value for __cpp_constexpr"
 #endif
 
Index: clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp
===================================================================
--- clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp
+++ clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp
@@ -1,6 +1,7 @@
-// RUN: %clang_cc1 -verify -fcxx-exceptions -triple=x86_64-linux-gnu -std=c++11 -Werror=c++14-extensions -Werror=c++20-extensions %s
-// RUN: %clang_cc1 -verify -fcxx-exceptions -triple=x86_64-linux-gnu -std=c++14 -DCXX14 -Werror=c++20-extensions %s
-// RUN: %clang_cc1 -verify -fcxx-exceptions -triple=x86_64-linux-gnu -std=c++20 -DCXX14 -DCXX20 %s
+// RUN: %clang_cc1 -verify -fcxx-exceptions -triple=x86_64-linux-gnu -std=c++11 -Werror=c++14-extensions -Werror=c++20-extensions -Werror=c++2b-extensions %s
+// RUN: %clang_cc1 -verify -fcxx-exceptions -triple=x86_64-linux-gnu -std=c++14 -DCXX14 -Werror=c++20-extensions -Werror=c++2b-extensions %s
+// RUN: %clang_cc1 -verify -fcxx-exceptions -triple=x86_64-linux-gnu -std=c++20 -DCXX14 -DCXX20 -Werror=c++2b-extensions %s
+// RUN: %clang_cc1 -verify -fcxx-exceptions -triple=x86_64-linux-gnu -std=c++2b -DCXX14 -DCXX20 -DCXX2b %s
 
 namespace N {
   typedef char C;
@@ -10,7 +11,7 @@
   typedef double D;
 }
 
-struct NonLiteral { // expected-note 3{{no constexpr constructors}}
+struct NonLiteral { // expected-note 2{{no constexpr constructors}}
   NonLiteral() {}
   NonLiteral(int) {}
 };
@@ -150,16 +151,25 @@
 }
 constexpr int DisallowedStmtsCXX14_2() {
   //  - a goto statement
-  goto x; // expected-error {{statement not allowed in constexpr function}}
-x:
+  try {
+  }catch (...){
+    goto x;
+    x: ;
+  }
+#ifndef CXX2b
+  // expected-error@-4 {{use of this statement in a constexpr function is a C++2b extension}}
+#endif
   return 0;
 }
 constexpr int DisallowedStmtsCXX14_2_1() {
   try {
-    return 0;
   } catch (...) {
-  merp: goto merp; // expected-error {{statement not allowed in constexpr function}}
+  merp: goto merp;
+#ifndef CXX2b
+  // expected-error@-2 {{use of this statement in a constexpr function is a C++2b extension}}
+#endif
   }
+  return 0;
 }
 constexpr int DisallowedStmtsCXX14_3() {
   //  - a try-block,
@@ -171,18 +181,35 @@
 }
 constexpr int DisallowedStmtsCXX14_4() {
   //  - a definition of a variable of non-literal type
-  NonLiteral nl; // expected-error {{variable of non-literal type 'NonLiteral' cannot be defined in a constexpr function}}
   return 0;
+  NonLiteral nl;
+#ifndef CXX2b
+  // expected-error@-2 {{variable of non-literal type 'NonLiteral' cannot be defined in a constexpr function before C++2b}}
+  // expected-note@14  {{'NonLiteral' is not literal}}
+#endif
 }
+
 constexpr int DisallowedStmtsCXX14_5() {
   //  - a definition of a variable of static storage duration
-  static constexpr int n = 123; // expected-error {{static variable not permitted in a constexpr function}}
-  return n;
+  static constexpr int n = 123;
+#ifndef CXX2b
+  // expected-error@-2 {{definition of a static variable in a constexpr function is a C++2b extension}}
+#endif
+#if !defined(CXX14)
+  // expected-error@-5 {{variable declaration in a constexpr function is a C++14 extension}}
+#endif
+  return 0;
 }
 constexpr int DisallowedStmtsCXX14_6() {
   //  - a definition of a variable of thread storage duration
-  thread_local constexpr int n = 123; // expected-error {{thread_local variable not permitted in a constexpr function}}
-  return n;
+  return 0;
+  thread_local constexpr int n = 123;
+#ifndef CXX2b
+  // expected-error@-2 {{definition of a thread_local variable in a constexpr function is a C++2b extension}}
+#endif
+#if !defined(CXX14)
+  // expected-error@-5 {{variable declaration in a constexpr function is a C++14 extension}}
+#endif
 }
 constexpr int DisallowedStmtsCXX14_7() {
   //  - a definition of a variable for which no initialization is performed
@@ -317,8 +344,14 @@
     return x;
   }
   constexpr int first(int n) {
-    static int value = n; // expected-error {{static variable not permitted}}
-    return value;
+    return 0;
+    static int value = n;
+#ifndef CXX2b
+  // expected-error@-2 {{definition of a static variable in a constexpr function is a C++2b extension}}
+#endif
+#ifndef CXX14
+  // expected-error@-5 {{C++14}}
+#endif
   }
   constexpr int uninit() {
     int a;
Index: clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp
===================================================================
--- /dev/null
+++ clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -verify -std=c++2b %s
+
+
+constexpr int f(int x) {
+    if(x) {
+        return 0;
+    }
+    else {
+        goto test; // expected-note {{subexpression not valid in a constant expression}}
+    }
+    test: return 0;
+}
+
+constexpr int g() { //expected-error {{constexpr function never produces a constant expression}}
+goto test; // expected-note {{subexpression not valid in a constant expression}}
+test:
+return 0;
+}
+
+
+int x = f(0);
+constexpr int y = f(0); //expected-error {{must be initialized by a constant expression}} \
+                        // expected-note {{in call to 'f(0)'}}
Index: clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/dtor.cpp
===================================================================
--- clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/dtor.cpp
+++ clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/dtor.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++2a -verify %s
+// RUN: %clang_cc1 -std=c++2b -verify %s
 
 // p3: if the function is a constructor or destructor, its class shall not have
 // any virtual base classes;
@@ -9,40 +9,42 @@
   };
 }
 
-// p3: its function-body shall not enclose
-//  -- a goto statement
-//  -- an identifier label
-//  -- a variable of non-literal type or of static or thread storage duration
 namespace contents {
   struct A {
     constexpr ~A() {
-      goto x; // expected-error {{statement not allowed in constexpr function}}
+      return;
+      goto x;
       x: ;
     }
   };
   struct B {
     constexpr ~B() {
-      x: ; // expected-error {{statement not allowed in constexpr function}}
+      x: ;
     }
   };
-  struct Nonlit { Nonlit(); }; // expected-note {{not literal}}
+  struct Nonlit { Nonlit(); };
   struct C {
     constexpr ~C() {
-      Nonlit nl; // expected-error {{non-literal}}
+      return;
+      Nonlit nl;
     }
   };
   struct D {
     constexpr ~D() {
-      static int a; // expected-error {{static variable}}
+      return;
+      static int a;
     }
   };
   struct E {
     constexpr ~E() {
-      thread_local int e; // expected-error {{thread_local variable}}
+      return;
+      thread_local int e;
+
     }
   };
   struct F {
     constexpr ~F() {
+      return;
       extern int f;
     }
   };
Index: clang/test/CXX/basic/basic.types/p10.cpp
===================================================================
--- clang/test/CXX/basic/basic.types/p10.cpp
+++ clang/test/CXX/basic/basic.types/p10.cpp
@@ -20,7 +20,7 @@
 
 struct BeingDefined;
 extern BeingDefined beingdefined;
-struct BeingDefined { 
+struct BeingDefined {
   static constexpr BeingDefined& t = beingdefined;
 };
 
Index: clang/lib/Sema/SemaDeclCXX.cpp
===================================================================
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -1892,13 +1892,17 @@
         if (VD->isStaticLocal()) {
           if (Kind == Sema::CheckConstexprKind::Diagnose) {
             SemaRef.Diag(VD->getLocation(),
-                         diag::err_constexpr_local_var_static)
-              << isa<CXXConstructorDecl>(Dcl)
-              << (VD->getTLSKind() == VarDecl::TLS_Dynamic);
+                         SemaRef.getLangOpts().CPlusPlus2b
+                             ? diag::warn_cxx20_compat_constexpr_static_var
+                             : diag::ext_constexpr_static_var)
+                << isa<CXXConstructorDecl>(Dcl)
+                << (VD->getTLSKind() == VarDecl::TLS_Dynamic);
+          } else if (!SemaRef.getLangOpts().CPlusPlus2b) {
+              return false;
           }
-          return false;
         }
-        if (CheckLiteralType(SemaRef, Kind, VD->getLocation(), VD->getType(),
+        if (!SemaRef.LangOpts.CPlusPlus2b &&
+            CheckLiteralType(SemaRef, Kind, VD->getLocation(), VD->getType(),
                              diag::err_constexpr_local_var_non_literal_type,
                              isa<CXXConstructorDecl>(Dcl)))
           return false;
@@ -2021,6 +2025,7 @@
 CheckConstexprFunctionStmt(Sema &SemaRef, const FunctionDecl *Dcl, Stmt *S,
                            SmallVectorImpl<SourceLocation> &ReturnStmts,
                            SourceLocation &Cxx1yLoc, SourceLocation &Cxx2aLoc,
+                           SourceLocation &Cxx2bLoc,
                            Sema::CheckConstexprKind Kind) {
   // - its function-body shall be [...] a compound-statement that contains only
   switch (S->getStmtClass()) {
@@ -2053,9 +2058,9 @@
   case Stmt::AttributedStmtClass:
     // Attributes on a statement don't affect its formal kind and hence don't
     // affect its validity in a constexpr function.
-    return CheckConstexprFunctionStmt(SemaRef, Dcl,
-                                      cast<AttributedStmt>(S)->getSubStmt(),
-                                      ReturnStmts, Cxx1yLoc, Cxx2aLoc, Kind);
+    return CheckConstexprFunctionStmt(
+        SemaRef, Dcl, cast<AttributedStmt>(S)->getSubStmt(), ReturnStmts,
+        Cxx1yLoc, Cxx2aLoc, Cxx2bLoc, Kind);
 
   case Stmt::CompoundStmtClass: {
     // C++1y allows compound-statements.
@@ -2065,7 +2070,7 @@
     CompoundStmt *CompStmt = cast<CompoundStmt>(S);
     for (auto *BodyIt : CompStmt->body()) {
       if (!CheckConstexprFunctionStmt(SemaRef, Dcl, BodyIt, ReturnStmts,
-                                      Cxx1yLoc, Cxx2aLoc, Kind))
+                                      Cxx1yLoc, Cxx2aLoc, Cxx2bLoc, Kind))
         return false;
     }
     return true;
@@ -2078,11 +2083,11 @@
 
     IfStmt *If = cast<IfStmt>(S);
     if (!CheckConstexprFunctionStmt(SemaRef, Dcl, If->getThen(), ReturnStmts,
-                                    Cxx1yLoc, Cxx2aLoc, Kind))
+                                    Cxx1yLoc, Cxx2aLoc, Cxx2bLoc, Kind))
       return false;
     if (If->getElse() &&
         !CheckConstexprFunctionStmt(SemaRef, Dcl, If->getElse(), ReturnStmts,
-                                    Cxx1yLoc, Cxx2aLoc, Kind))
+                                    Cxx1yLoc, Cxx2aLoc, Cxx2bLoc, Kind))
       return false;
     return true;
   }
@@ -2101,7 +2106,7 @@
     for (Stmt *SubStmt : S->children())
       if (SubStmt &&
           !CheckConstexprFunctionStmt(SemaRef, Dcl, SubStmt, ReturnStmts,
-                                      Cxx1yLoc, Cxx2aLoc, Kind))
+                                      Cxx1yLoc, Cxx2aLoc, Cxx2bLoc, Kind))
         return false;
     return true;
 
@@ -2116,7 +2121,18 @@
     for (Stmt *SubStmt : S->children())
       if (SubStmt &&
           !CheckConstexprFunctionStmt(SemaRef, Dcl, SubStmt, ReturnStmts,
-                                      Cxx1yLoc, Cxx2aLoc, Kind))
+                                      Cxx1yLoc, Cxx2aLoc, Cxx2bLoc, Kind))
+        return false;
+    return true;
+
+  case Stmt::LabelStmtClass:
+  case Stmt::GotoStmtClass:
+    if (!Cxx2bLoc.isValid())
+      Cxx2bLoc = S->getBeginLoc();
+    for (Stmt *SubStmt : S->children())
+      if (SubStmt &&
+          !CheckConstexprFunctionStmt(SemaRef, Dcl, SubStmt, ReturnStmts,
+                                      Cxx1yLoc, Cxx2aLoc, Cxx2bLoc, Kind))
         return false;
     return true;
 
@@ -2129,7 +2145,7 @@
     for (Stmt *SubStmt : S->children()) {
       if (SubStmt &&
           !CheckConstexprFunctionStmt(SemaRef, Dcl, SubStmt, ReturnStmts,
-                                      Cxx1yLoc, Cxx2aLoc, Kind))
+                                      Cxx1yLoc, Cxx2aLoc, Cxx2bLoc, Kind))
         return false;
     }
     return true;
@@ -2137,9 +2153,9 @@
   case Stmt::CXXCatchStmtClass:
     // Do not bother checking the language mode (already covered by the
     // try block check).
-    if (!CheckConstexprFunctionStmt(SemaRef, Dcl,
-                                    cast<CXXCatchStmt>(S)->getHandlerBlock(),
-                                    ReturnStmts, Cxx1yLoc, Cxx2aLoc, Kind))
+    if (!CheckConstexprFunctionStmt(
+            SemaRef, Dcl, cast<CXXCatchStmt>(S)->getHandlerBlock(), ReturnStmts,
+            Cxx1yLoc, Cxx2aLoc, Cxx2bLoc, Kind))
       return false;
     return true;
 
@@ -2204,20 +2220,27 @@
   //
   // Note that walking the children here is enough to properly check for
   // CompoundStmt and CXXTryStmt body.
-  SourceLocation Cxx1yLoc, Cxx2aLoc;
+  SourceLocation Cxx1yLoc, Cxx2aLoc, Cxx2bLoc;
   for (Stmt *SubStmt : Body->children()) {
     if (SubStmt &&
         !CheckConstexprFunctionStmt(SemaRef, Dcl, SubStmt, ReturnStmts,
-                                    Cxx1yLoc, Cxx2aLoc, Kind))
+                                    Cxx1yLoc, Cxx2aLoc, Cxx2bLoc, Kind))
       return false;
   }
 
   if (Kind == Sema::CheckConstexprKind::CheckValid) {
     // If this is only valid as an extension, report that we don't satisfy the
     // constraints of the current language.
-    if ((Cxx2aLoc.isValid() && !SemaRef.getLangOpts().CPlusPlus20) ||
+    if ((Cxx2bLoc.isValid() && !SemaRef.getLangOpts().CPlusPlus2b) ||
+        (Cxx2aLoc.isValid() && !SemaRef.getLangOpts().CPlusPlus20) ||
         (Cxx1yLoc.isValid() && !SemaRef.getLangOpts().CPlusPlus17))
       return false;
+  } else if (Cxx2bLoc.isValid()) {
+    SemaRef.Diag(Cxx2bLoc,
+                 SemaRef.getLangOpts().CPlusPlus2b
+                     ? diag::warn_cxx20_compat_constexpr_body_invalid_stmt
+                     : diag::ext_constexpr_body_invalid_stmt_cxx2b)
+        << isa<CXXConstructorDecl>(Dcl);
   } else if (Cxx2aLoc.isValid()) {
     SemaRef.Diag(Cxx2aLoc,
          SemaRef.getLangOpts().CPlusPlus20
Index: clang/lib/Frontend/InitPreprocessor.cpp
===================================================================
--- clang/lib/Frontend/InitPreprocessor.cpp
+++ clang/lib/Frontend/InitPreprocessor.cpp
@@ -557,10 +557,11 @@
     Builder.defineMacro("__cpp_unicode_literals", "200710L");
     Builder.defineMacro("__cpp_user_defined_literals", "200809L");
     Builder.defineMacro("__cpp_lambdas", "200907L");
-    Builder.defineMacro("__cpp_constexpr",
-                        LangOpts.CPlusPlus20 ? "201907L" :
-                        LangOpts.CPlusPlus17 ? "201603L" :
-                        LangOpts.CPlusPlus14 ? "201304L" : "200704");
+    Builder.defineMacro("__cpp_constexpr", LangOpts.CPlusPlus2b   ? "202110L"
+                                           : LangOpts.CPlusPlus20 ? "201907L"
+                                           : LangOpts.CPlusPlus17 ? "201603L"
+                                           : LangOpts.CPlusPlus14 ? "201304L"
+                                                                  : "200704");
     Builder.defineMacro("__cpp_constexpr_in_decltype", "201711L");
     Builder.defineMacro("__cpp_range_based_for",
                         LangOpts.CPlusPlus17 ? "201603L" : "200907");
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2682,6 +2682,13 @@
   "use of this statement in a constexpr %select{function|constructor}0 "
   "is incompatible with C++ standards before C++20">,
   InGroup<CXXPre20Compat>, DefaultIgnore;
+def ext_constexpr_body_invalid_stmt_cxx2b : ExtWarn<
+  "use of this statement in a constexpr %select{function|constructor}0 "
+  "is a C++2b extension">, InGroup<CXX2b>;
+def warn_cxx20_compat_constexpr_body_invalid_stmt : Warning<
+  "use of this statement in a constexpr %select{function|constructor}0 "
+  "is incompatible with C++ standards before C++2b">,
+  InGroup<CXXPre2bCompat>, DefaultIgnore;
 def ext_constexpr_type_definition : ExtWarn<
   "type definition in a constexpr %select{function|constructor}0 "
   "is a C++14 extension">, InGroup<CXX14>;
@@ -2699,12 +2706,18 @@
   "variable declaration in a constexpr %select{function|constructor}0 "
   "is incompatible with C++ standards before C++14">,
   InGroup<CXXPre14Compat>, DefaultIgnore;
-def err_constexpr_local_var_static : Error<
-  "%select{static|thread_local}1 variable not permitted in a constexpr "
-  "%select{function|constructor}0">;
+def ext_constexpr_static_var : ExtWarn<
+  "definition of a %select{static|thread_local}1 variable "
+  "in a constexpr %select{function|constructor}0 "
+  "is a C++2b extension">, InGroup<CXX2b>;
+def warn_cxx20_compat_constexpr_static_var : Warning<
+  "definition of a %select{static|thread_local}1 variable "
+  "in a constexpr %select{function|constructor}0 "
+  "is incompatible with C++ standards before C++2b">,
+  InGroup<CXXPre2bCompat>, DefaultIgnore;
 def err_constexpr_local_var_non_literal_type : Error<
   "variable of non-literal type %1 cannot be defined in a constexpr "
-  "%select{function|constructor}0">;
+  "%select{function|constructor}0 before C++2b">;
 def ext_constexpr_local_var_no_init : ExtWarn<
   "uninitialized variable in a constexpr %select{function|constructor}0 "
   "is a C++20 extension">, InGroup<CXX20>;
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -182,6 +182,7 @@
 ^^^^^^^^^^^^^^^^^^^^^
 - Implemented `P1938R3: if consteval <https://wg21.link/P1938R3>`_.
 - Implemented `P2360R0: Extend init-statement to allow alias-declaration <https://wg21.link/P2360R0>`_.
+- Implemented `P2242R3: Non-literal variables (and labels and gotos) in constexpr functions	<https://wg21.link/P2242R3>`_.
 
 
 CUDA Language Changes in Clang
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to