On 10/5/21 18:24, Jakub Jelinek wrote:
On Tue, Oct 05, 2021 at 05:24:09PM -0400, Jason Merrill wrote:
That seems correct to me.  If they have static initialization, they are
initialized.

Ok, I've included those tests in the patch now too.
@@ -8736,14 +8765,14 @@ potential_constant_expression_1 (tree t,
         tmp = DECL_EXPR_DECL (t);
         if (VAR_P (tmp) && !DECL_ARTIFICIAL (tmp))
        {
-         if (TREE_STATIC (tmp))
+         if (TREE_STATIC (tmp) && cxx_dialect < cxx23)
            {
              if (flags & tf_error)
                error_at (DECL_SOURCE_LOCATION (tmp), "%qD declared "
                          "%<static%> in %<constexpr%> context", tmp);
              return false;
            }
-         else if (CP_DECL_THREAD_LOCAL_P (tmp))
+         else if (CP_DECL_THREAD_LOCAL_P (tmp) && cxx_dialect < cxx23)
            {
              if (flags & tf_error)
                error_at (DECL_SOURCE_LOCATION (tmp), "%qD declared "

Hmm, I wouldn't expect this hunk to be needed; if there's a control path
that doesn't include these declarations, we shouldn't hit these errors.

You're right, that is unnecessary, if the static/thread_local declaration
is unconditional, we can (but aren't required to) diagnose it even when
the constexpr function is never evaluated in constant expressions.
But, I had to swap the TREE_STATIC and CP_DECL_THREAD_LOCAL_P checks
because the latter implies the former and so static would be always
printed instead of thread_local for thread_local declarations.

@@ -9025,7 +9054,7 @@ potential_constant_expression_1 (tree t,
       case LABEL_EXPR:
         t = LABEL_EXPR_LABEL (t);
-      if (DECL_ARTIFICIAL (t))
+      if (DECL_ARTIFICIAL (t) || cxx_dialect >= cxx23)
        return true;
         else if (flags & tf_error)
        error_at (loc, "label definition is not a constant expression");

Let's change this message to "only available with..." like the others.

Changed too.

Here is an updated patch (also after IRC chat with Jonathan changed
the __cpp_constexpr value from 202103L that was in the paper to 202110L).
Passes the tests that are modified so far, full bootstrap/regtest
queued after my current one finishes.

OK.

2021-10-06  Jakub Jelinek  <ja...@redhat.com>

gcc/c-family/
        * c-cppbuiltin.c (c_cpp_builtins): For -std=c++23 predefine
        __cpp_constexpr to 202110L rather than 201907L.
gcc/cp/
        * parser.c (cp_parser_jump_statement): Implement C++23 P2242R3.
        Allow goto expressions in constexpr function bodies for C++23.
        Adjust error message for older standards to mention it.
        * decl.c (start_decl): Allow static and thread_local declarations
        in constexpr function bodies for C++23.  Adjust error message for
        older standards to mention it.
        * constexpr.c (ensure_literal_type_for_constexpr_object): Allow
        declarations of variables with non-literal type in constexpr function
        bodies for C++23.  Adjust error message for older standards to mention
        it.
        (cxx_eval_constant_expression) <case DECL_EXPR>: Diagnose declarations
        of initialization of static or thread_local vars.
        (cxx_eval_constant_expression) <case GOTO_EXPR>: Diagnose goto
        statements for C++23.
        (potential_constant_expression_1) <case DECL_EXPR>: Swap the
        CP_DECL_THREAD_LOCAL_P and TREE_STATIC checks.
        (potential_constant_expression_1) <case LABEL_EXPR>: Allow labels for
        C++23.  Adjust error message for older standards to mention it.
gcc/testsuite/
        * g++.dg/cpp23/feat-cxx2b.C: Expect __cpp_constexpr 202110L rather
        than 201907L.
        * g++.dg/cpp23/constexpr-nonlit1.C: New test.
        * g++.dg/cpp23/constexpr-nonlit2.C: New test.
        * g++.dg/cpp23/constexpr-nonlit3.C: New test.
        * g++.dg/cpp23/constexpr-nonlit4.C: New test.
        * g++.dg/cpp23/constexpr-nonlit5.C: New test.
        * g++.dg/cpp23/constexpr-nonlit6.C: New test.
        * g++.dg/diagnostic/constexpr1.C: Only expect some diagnostics for
        c++20_down.
        * g++.dg/cpp1y/constexpr-label.C: Likewise.
        * g++.dg/cpp1y/constexpr-neg1.C: Likewise.
        * g++.dg/cpp2a/constexpr-try5.C: Likewise.  Adjust some expected
        wording.
        * g++.dg/cpp2a/constexpr-dtor3.C: Likewise.
        * g++.dg/cpp2a/consteval3.C: Likewise.  Add effective target c++20
        and remove dg-options.

--- gcc/c-family/c-cppbuiltin.c.jj      2021-10-05 22:27:39.387959561 +0200
+++ gcc/c-family/c-cppbuiltin.c 2021-10-05 23:47:13.865054265 +0200
@@ -1052,7 +1052,8 @@ c_cpp_builtins (cpp_reader *pfile)
          cpp_define (pfile, "__cpp_init_captures=201803L");
          cpp_define (pfile, "__cpp_generic_lambdas=201707L");
          cpp_define (pfile, "__cpp_designated_initializers=201707L");
-         cpp_define (pfile, "__cpp_constexpr=201907L");
+         if (cxx_dialect <= cxx20)
+           cpp_define (pfile, "__cpp_constexpr=201907L");
          cpp_define (pfile, "__cpp_constexpr_in_decltype=201711L");
          cpp_define (pfile, "__cpp_conditional_explicit=201806L");
          cpp_define (pfile, "__cpp_consteval=201811L");
@@ -1071,6 +1072,7 @@ c_cpp_builtins (cpp_reader *pfile)
          /* Set feature test macros for C++23.  */
          cpp_define (pfile, "__cpp_size_t_suffix=202011L");
          cpp_define (pfile, "__cpp_if_consteval=202106L");
+         cpp_define (pfile, "__cpp_constexpr=202110L");
        }
        if (flag_concepts)
          {
--- gcc/cp/parser.c.jj  2021-10-05 22:27:39.551957300 +0200
+++ gcc/cp/parser.c     2021-10-05 23:47:13.895053851 +0200
@@ -14176,9 +14176,11 @@ cp_parser_jump_statement (cp_parser* par
case RID_GOTO:
        if (parser->in_function_body
-         && DECL_DECLARED_CONSTEXPR_P (current_function_decl))
+         && DECL_DECLARED_CONSTEXPR_P (current_function_decl)
+         && cxx_dialect < cxx23)
        {
-         error ("%<goto%> in %<constexpr%> function");
+         error ("%<goto%> in %<constexpr%> function only available with "
+                "%<-std=c++2b%> or %<-std=gnu++2b%>");
          cp_function_chain->invalid_constexpr = true;
        }
--- gcc/cp/decl.c.jj 2021-10-05 22:27:39.502957976 +0200
+++ gcc/cp/decl.c       2021-10-05 23:47:13.916053561 +0200
@@ -5709,17 +5709,20 @@ start_decl (const cp_declarator *declara
      }
if (current_function_decl && VAR_P (decl)
-      && DECL_DECLARED_CONSTEXPR_P (current_function_decl))
+      && DECL_DECLARED_CONSTEXPR_P (current_function_decl)
+      && cxx_dialect < cxx23)
      {
        bool ok = false;
        if (CP_DECL_THREAD_LOCAL_P (decl))
        error_at (DECL_SOURCE_LOCATION (decl),
-                 "%qD declared %<thread_local%> in %qs function", decl,
+                 "%qD declared %<thread_local%> in %qs function only "
+                 "available with %<-std=c++2b%> or %<-std=gnu++2b%>", decl,
                  DECL_IMMEDIATE_FUNCTION_P (current_function_decl)
                  ? "consteval" : "constexpr");
        else if (TREE_STATIC (decl))
        error_at (DECL_SOURCE_LOCATION (decl),
-                 "%qD declared %<static%> in %qs function", decl,
+                 "%qD declared %<static%> in %qs function only available "
+                 "with %<-std=c++2b%> or %<-std=gnu++2b%>", decl,
                  DECL_IMMEDIATE_FUNCTION_P (current_function_decl)
                  ? "consteval" : "constexpr");
        else
--- gcc/cp/constexpr.c.jj       2021-10-05 22:27:48.009840663 +0200
+++ gcc/cp/constexpr.c  2021-10-06 00:08:16.809608246 +0200
@@ -109,14 +109,15 @@ ensure_literal_type_for_constexpr_object
              explain_non_literal_class (type);
              decl = error_mark_node;
            }
-         else
+         else if (cxx_dialect < cxx23)
            {
              if (!is_instantiation_of_constexpr (current_function_decl))
                {
                  auto_diagnostic_group d;
                  error_at (DECL_SOURCE_LOCATION (decl),
                            "variable %qD of non-literal type %qT in "
-                           "%<constexpr%> function", decl, type);
+                           "%<constexpr%> function only available with "
+                           "%<-std=c++2b%> or %<-std=gnu++2b%>", decl, type);
                  explain_non_literal_class (type);
                  decl = error_mark_node;
                }
@@ -6345,6 +6346,26 @@ cxx_eval_constant_expression (const cons
            r = void_node;
            break;
          }
+
+       if (VAR_P (r)
+           && (TREE_STATIC (r) || CP_DECL_THREAD_LOCAL_P (r))
+           /* Allow __FUNCTION__ etc.  */
+           && !DECL_ARTIFICIAL (r))
+         {
+           gcc_assert (cxx_dialect >= cxx23);
+           if (!ctx->quiet)
+             {
+               if (CP_DECL_THREAD_LOCAL_P (r))
+                 error_at (loc, "control passes through declaration of %qD "
+                                "with thread storage duration", r);
+               else
+                 error_at (loc, "control passes through declaration of %qD "
+                                "with static storage duration", r);
+             }
+           *non_constant_p = true;
+           break;
+         }
+
        if (AGGREGATE_TYPE_P (TREE_TYPE (r))
            || VECTOR_TYPE_P (TREE_TYPE (r)))
          {
@@ -7049,10 +7070,18 @@ cxx_eval_constant_expression (const cons
        break;
case GOTO_EXPR:
-      *jump_target = TREE_OPERAND (t, 0);
-      gcc_assert (breaks (jump_target) || continues (jump_target)
-                 /* Allow for jumping to a cdtor_label.  */
-                 || returns (jump_target));
+      if (breaks (&TREE_OPERAND (t, 0))
+         || continues (&TREE_OPERAND (t, 0))
+         /* Allow for jumping to a cdtor_label.  */
+         || returns (&TREE_OPERAND (t, 0)))
+       *jump_target = TREE_OPERAND (t, 0);
+      else
+       {
+         gcc_assert (cxx_dialect >= cxx23);
+         if (!ctx->quiet)
+           error_at (loc, "%<goto%> is not a constant expression");
+         *non_constant_p = true;
+       }
        break;
case LOOP_EXPR:
@@ -8736,18 +8765,18 @@ potential_constant_expression_1 (tree t,
        tmp = DECL_EXPR_DECL (t);
        if (VAR_P (tmp) && !DECL_ARTIFICIAL (tmp))
        {
-         if (TREE_STATIC (tmp))
+         if (CP_DECL_THREAD_LOCAL_P (tmp))
            {
              if (flags & tf_error)
                error_at (DECL_SOURCE_LOCATION (tmp), "%qD declared "
-                         "%<static%> in %<constexpr%> context", tmp);
+                         "%<thread_local%> in %<constexpr%> context", tmp);
              return false;
            }
-         else if (CP_DECL_THREAD_LOCAL_P (tmp))
+         else if (TREE_STATIC (tmp))
            {
              if (flags & tf_error)
                error_at (DECL_SOURCE_LOCATION (tmp), "%qD declared "
-                         "%<thread_local%> in %<constexpr%> context", tmp);
+                         "%<static%> in %<constexpr%> context", tmp);
              return false;
            }
          else if (!check_for_uninitialized_const_var
@@ -9025,10 +9054,11 @@ potential_constant_expression_1 (tree t,
case LABEL_EXPR:
        t = LABEL_EXPR_LABEL (t);
-      if (DECL_ARTIFICIAL (t))
+      if (DECL_ARTIFICIAL (t) || cxx_dialect >= cxx23)
        return true;
        else if (flags & tf_error)
-       error_at (loc, "label definition is not a constant expression");
+       error_at (loc, "label definition in %<constexpr%> function only "
+                      "available with %<-std=c++2b%> or %<-std=gnu++2b%>");
        return false;
case ANNOTATE_EXPR:
--- gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C.jj  2021-10-05 22:27:39.594956707 
+0200
+++ gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C     2021-10-06 00:02:37.480296129 
+0200
@@ -134,8 +134,8 @@
#ifndef __cpp_constexpr
  #  error "__cpp_constexpr"
-#elif __cpp_constexpr != 201907
-#  error "__cpp_constexpr != 201907"
+#elif __cpp_constexpr != 202110
+#  error "__cpp_constexpr != 202110"
  #endif
#ifndef __cpp_decltype_auto
--- gcc/testsuite/g++.dg/cpp23/constexpr-nonlit1.C.jj   2021-10-05 
23:47:13.934053312 +0200
+++ gcc/testsuite/g++.dg/cpp23/constexpr-nonlit1.C      2021-10-05 
23:52:09.879965662 +0200
@@ -0,0 +1,68 @@
+// P2242R3
+// { dg-do compile { target c++14 } }
+
+constexpr int
+foo ()
+{
+lab:           // { dg-error "label definition in 'constexpr' function only available 
with" "" { target c++20_down } }
+  return 1;
+}
+
+constexpr int
+bar (int x)
+{
+  if (x)
+    goto lab;  // { dg-error "'goto' in 'constexpr' function only available with" 
"" { target c++20_down } }
+  return 1;
+lab:
+  return 0;
+}
+
+constexpr int
+baz (int x)
+{
+  if (!x)
+    return 1;
+  static int a;        // { dg-error "'a' declared 'static' in 'constexpr' function only 
available with" "" { target c++20_down } }
+  return ++a;  // { dg-error "uninitialized variable 'a' in 'constexpr' function" 
"" { target c++17_down } .-1 }
+}
+
+constexpr int
+qux (int x)
+{
+  if (!x)
+    return 1;
+  thread_local int a;  // { dg-error "'a' declared 'thread_local' in 'constexpr' function 
only available with" "" { target c++20_down } }
+  return ++a;  // { dg-error "uninitialized variable 'a' in 'constexpr' function" 
"" { target c++17_down } .-1 }
+}
+
+constexpr int
+garply (int x)
+{
+  if (!x)
+    return 1;
+  extern thread_local int a;   // { dg-error "'a' declared 'thread_local' in 'constexpr' 
function only available with" "" { target c++20_down } }
+  return ++a;
+}
+
+struct S { S (); ~S (); int s; };      // { dg-message "'S' is not literal because:" 
"" { target c++20_down } }
+                                       // { dg-message "'S' has a non-trivial 
destructor" "" { target c++17_down } .-1 }
+                                       // { dg-message "'S' does not have 'constexpr' 
destructor" "" { target { c++20_only } } .-2 }
+
+constexpr int
+corge (int x)
+{
+  if (!x)
+    return 1;
+  S s;                 // { dg-error "variable 's' of non-literal type 'S' in 'constexpr' 
function only available with" "" { target c++20_down } }
+  return 0;
+}
+
+#if __cpp_constexpr >= 202110L
+static_assert (foo ());
+static_assert (bar (0));
+static_assert (baz (0));
+static_assert (qux (0));
+static_assert (garply (0));
+static_assert (corge (0));
+#endif
--- gcc/testsuite/g++.dg/cpp23/constexpr-nonlit2.C.jj   2021-10-05 
23:47:13.934053312 +0200
+++ gcc/testsuite/g++.dg/cpp23/constexpr-nonlit2.C      2021-10-06 
00:14:12.586693301 +0200
@@ -0,0 +1,54 @@
+// P2242R3
+// { dg-do compile }
+// { dg-options "-std=c++2b" }
+
+constexpr int
+foo ()
+{
+lab:
+  return 1;
+}
+
+constexpr int
+bar (int x)
+{
+  if (x)
+    goto lab;          // { dg-error "'goto' is not a constant expression" }
+  return 1;
+lab:
+  return 0;
+}
+
+constexpr int
+baz (int x)
+{
+  if (!x)
+    return 1;
+  static int a;                // { dg-error "control passes through declaration of 
'a' with static storage duration" }
+  return ++a;
+}
+
+constexpr int
+qux (int x)
+{
+  if (!x)
+    return 1;
+  thread_local int a;  // { dg-error "control passes through declaration of 'a' 
with thread storage duration" }
+  return ++a;
+}
+
+struct S { S (); ~S (); int s; };      // { dg-message "'S::S\\\(\\\)' declared 
here" }
+
+constexpr int
+corge (int x)
+{
+  if (!x)
+    return 1;
+  S s;                 // { dg-error "call to non-'constexpr' function 
'S::S\\\(\\\)'" }
+  return 0;
+}
+
+constexpr int a = bar (1);     // { dg-message "in 'constexpr' expansion of" }
+constexpr int b = baz (1);     // { dg-message "in 'constexpr' expansion of" }
+constexpr int c = qux (1);     // { dg-message "in 'constexpr' expansion of" }
+constexpr int d = corge (1);   // { dg-message "in 'constexpr' expansion of" }
--- gcc/testsuite/g++.dg/cpp23/constexpr-nonlit3.C.jj   2021-10-05 
23:47:13.934053312 +0200
+++ gcc/testsuite/g++.dg/cpp23/constexpr-nonlit3.C      2021-10-05 
23:47:13.934053312 +0200
@@ -0,0 +1,10 @@
+// P2242R3
+// { dg-do compile { target c++14 } }
+
+constexpr int
+foo ()
+{
+  goto lab;    // { dg-error "'goto' in 'constexpr' function only available with" 
"" { target c++20_down } }
+lab:           // { dg-error "'goto' is not a constant expression" "" { target 
{ c++23 } } .-1 }
+  return 1;
+}
--- gcc/testsuite/g++.dg/cpp23/constexpr-nonlit4.C.jj   2021-10-05 
23:58:42.437543278 +0200
+++ gcc/testsuite/g++.dg/cpp23/constexpr-nonlit4.C      2021-10-05 
23:55:57.699818980 +0200
@@ -0,0 +1,57 @@
+// { dg-do compile }
+// { dg-options "-std=c++2b" }
+
+int qux ();
+
+constexpr int
+foo (int x)
+{
+  switch (x)
+    {
+      static int v = qux ();
+    case 12:
+      return 1;
+    }
+  return 0;
+}
+
+constexpr int
+bar (int x)
+{
+  switch (x)
+    {
+      thread_local int v = qux ();
+    case 12:
+      return 1;
+    }
+  return 0;
+}
+
+constexpr int
+baz (int x)
+{
+  switch (x)
+    {
+      static const int v = qux ();     // { dg-message "'v' was not initialized 
with a constant expression" }
+    case 12:
+      return v;
+    }
+  return 0;
+}
+
+constexpr int
+corge (int x)
+{
+  switch (x)
+    {
+      const thread_local int v = qux ();       // { dg-message "'v' was not 
initialized with a constant expression" }
+    case 12:
+      return v;
+    }
+  return 0;
+}
+
+constexpr int a = foo (12);
+constexpr int b = bar (12);
+constexpr int c = baz (12);            // { dg-error "the value of 'v' is not 
usable in a constant expression" }
+constexpr int d = corge (12);          // { dg-error "the value of 'v' is not 
usable in a constant expression" }
--- gcc/testsuite/g++.dg/cpp23/constexpr-nonlit5.C.jj   2021-10-05 
23:58:47.250476787 +0200
+++ gcc/testsuite/g++.dg/cpp23/constexpr-nonlit5.C      2021-10-05 
23:58:12.130961967 +0200
@@ -0,0 +1,57 @@
+// { dg-do compile }
+// { dg-options "-std=c++2b" }
+
+int qux ();
+
+constexpr int
+foo (int x)
+{
+  switch (x)
+    {
+      static const int v = 6;
+    case 12:
+      return v;
+    }
+  return 0;
+}
+
+constexpr int
+bar (int x)
+{
+  switch (x)
+    {
+      thread_local const int v = 7;
+    case 12:
+      return 7;
+    }
+  return 0;
+}
+
+constexpr int
+baz (int x)
+{
+  switch (x)
+    {
+      static int v = 6;        // { dg-message "int v' is not const" }
+    case 12:
+      return v;
+    }
+  return 0;
+}
+
+constexpr int
+corge (int x)
+{
+  switch (x)
+    {
+      thread_local int v = 6;  // { dg-message "int v' is not const" }
+    case 12:
+      return v;
+    }
+  return 0;
+}
+
+constexpr int a = foo (12);
+constexpr int b = bar (12);
+constexpr int c = baz (12);            // { dg-error "the value of 'v' is not 
usable in a constant expression" }
+constexpr int d = corge (12);          // { dg-error "the value of 'v' is not 
usable in a constant expression" }
--- gcc/testsuite/g++.dg/cpp23/constexpr-nonlit6.C.jj   2021-10-06 
00:12:19.927249541 +0200
+++ gcc/testsuite/g++.dg/cpp23/constexpr-nonlit6.C      2021-10-06 
00:15:32.680587909 +0200
@@ -0,0 +1,25 @@
+// P2242R3
+// { dg-do compile }
+// { dg-options "-std=c++2b" }
+
+constexpr int
+foo ()
+{
+  goto lab;            // { dg-error "'goto' is not a constant expression" }
+lab:
+  return 1;
+}
+
+constexpr int
+bar ()
+{
+  static int a;                // { dg-error "'a' declared 'static' in 'constexpr' 
context" }
+  return ++a;
+}
+
+constexpr int
+baz (int x)
+{
+  thread_local int a;  // { dg-error "'a' declared 'thread_local' in 'constexpr' 
context" }
+  return ++a;
+}
--- gcc/testsuite/g++.dg/diagnostic/constexpr1.C.jj     2020-01-12 
11:54:37.155402214 +0100
+++ gcc/testsuite/g++.dg/diagnostic/constexpr1.C        2021-10-06 
00:08:47.990177482 +0200
@@ -1,5 +1,7 @@
  // { dg-do compile { target c++11 } }
-constexpr int foo() { thread_local int i __attribute__((unused)) {}; return 1; } // { dg-error "40:.i. declared .thread_local." }
+constexpr int foo() { thread_local int i __attribute__((unused)) {}; return 1; }  // { dg-error 
"40:.i. declared .thread_local." "" { target c++20_down } }
+// { dg-error "40:.i. declared .thread_local. in .constexpr. context" "" { 
target c++23 } .-1 }
-constexpr int bar() { static int i __attribute__((unused)) {}; return 1; } // { dg-error "34:.i. declared .static." }
+constexpr int bar() { static int i __attribute__((unused)) {}; return 1; }  // { dg-error 
"34:.i. declared .static." "" { target c++20_down } }
+// { dg-error "34:.i. declared .static. in .constexpr. context" "" { target 
c++23 } .-1 }
--- gcc/testsuite/g++.dg/cpp1y/constexpr-label.C.jj     2020-11-22 
19:11:44.103588521 +0100
+++ gcc/testsuite/g++.dg/cpp1y/constexpr-label.C        2021-10-05 
23:52:09.879965662 +0200
@@ -4,6 +4,6 @@
  constexpr int
  f ()
  {
-x: // { dg-error "label definition is not a constant expression" }
+x: // { dg-error "label definition in 'constexpr' function only available with" 
"" { target c++20_down } }
    return 42;
  }
--- gcc/testsuite/g++.dg/cpp1y/constexpr-neg1.C.jj      2020-01-12 
11:54:37.115402818 +0100
+++ gcc/testsuite/g++.dg/cpp1y/constexpr-neg1.C 2021-10-06 00:01:48.736969524 
+0200
@@ -4,12 +4,12 @@ struct A { A(); };
constexpr int f(int i) {
    static int j = i;           // { dg-error "static" }
-  thread_local int l = i;      // { dg-error "thread_local" }
-  goto foo;                    // { dg-error "goto" }
+  thread_local int l = i;      // { dg-error "thread_local" "" { target 
c++20_down } }
+  goto foo;                    // { dg-error "goto" "" { target c++20_down } }
   foo:
    asm("foo");                       // { dg-error "asm" "" { target 
c++17_down } }
    int k;                      // { dg-error "uninitialized" "" { target 
c++17_down } }
-  A a;                         // { dg-error "non-literal" }
+  A a;                         // { dg-error "non-literal" "" { target 
c++20_down } }
    return i;
  }
--- gcc/testsuite/g++.dg/cpp2a/constexpr-try5.C.jj 2020-01-12 11:54:37.141402425 +0100
+++ gcc/testsuite/g++.dg/cpp2a/constexpr-try5.C 2021-10-06 00:11:41.897774924 
+0200
@@ -5,14 +5,15 @@
  constexpr int foo ()
  try {                 // { dg-warning "function-try-block body of 'constexpr' function only 
available with" "" { target c++17_down } }
    int a;              // { dg-error "uninitialized variable 'a' in 'constexpr' 
function" "" { target c++17_down } }
-  static double b = 1.0;// { dg-error "'b' declared 'static' in 'constexpr' 
function" }
-  goto l;              // { dg-error "'goto' in 'constexpr' function" }
+  static double b = 1.0;// { dg-error "'b' declared 'static' in 'constexpr' function only 
available with" "" { target c++20_down } }
+                       // { dg-error "'b' declared 'static' in 'constexpr' context" 
"" { target c++23 } .-1 }
+  goto l;              // { dg-error "'goto' in 'constexpr' function only available 
with" "" { target c++20_down } }
    l:;
    return 0;
  } catch (...) {
    long int c;         // { dg-error "uninitialized variable 'c' in 'constexpr' 
function" "" { target c++17_down } }
-  static float d = 2.0f;// { dg-error "'d' declared 'static' in 'constexpr' 
function" }
-  goto l2;             // { dg-error "'goto' in 'constexpr' function" }
+  static float d = 2.0f;// { dg-error "'d' declared 'static' in 'constexpr' function only 
available with" "" { target c++20_down } }
+  goto l2;             // { dg-error "'goto' in 'constexpr' function only available 
with" "" { target c++20_down } }
    l2:;
    return -1;
  }
@@ -20,20 +21,21 @@ try {                       // { dg-warning "function-try-bl
  constexpr int bar ()
  {
    int a;              // { dg-error "uninitialized variable 'a' in 'constexpr' 
function" "" { target c++17_down } }
-  static long double b = 3.0;// { dg-error "'b' declared 'static' in 'constexpr' 
function" }
-  goto l;              // { dg-error "'goto' in 'constexpr' function" }
+  static long double b = 3.0;// { dg-error "'b' declared 'static' in 'constexpr' function 
only available with" "" { target c++20_down } }
+                       // { dg-error "'b' declared 'static' in 'constexpr' context" 
"" { target c++23 } .-1 }
+  goto l;              // { dg-error "'goto' in 'constexpr' function only available 
with" "" { target c++20_down } }
    l:;
    try {                       // { dg-warning "'try' in 'constexpr' function only available 
with" "" { target c++17_down } }
      short c;          // { dg-error "uninitialized variable 'c' in 'constexpr' 
function" "" { target c++17_down } }
-    static float d;    // { dg-error "'d' declared 'static' in 'constexpr' 
function" }
+    static float d;    // { dg-error "'d' declared 'static' in 'constexpr' function only 
available with" "" { target c++20_down } }
                        // { dg-error "uninitialized variable 'd' in 'constexpr' 
function" "" { target c++17_down } .-1 }
-    goto l2;           // { dg-error "'goto' in 'constexpr' function" }
+    goto l2;           // { dg-error "'goto' in 'constexpr' function only available 
with" "" { target c++20_down } }
      l2:;
      return 0;
    } catch (int) {
      char e;           // { dg-error "uninitialized variable 'e' in 'constexpr' 
function" "" { target c++17_down } }
-    static int f = 5;  // { dg-error "'f' declared 'static' in 'constexpr' 
function" }
-    goto l3;           // { dg-error "'goto' in 'constexpr' function" }
+    static int f = 5;  // { dg-error "'f' declared 'static' in 'constexpr' function only 
available with" "" { target c++20_down } }
+    goto l3;           // { dg-error "'goto' in 'constexpr' function only available 
with" "" { target c++20_down } }
      l3:;
      return 1;
    }
--- gcc/testsuite/g++.dg/cpp2a/constexpr-dtor3.C.jj     2021-04-14 
10:48:41.330103579 +0200
+++ gcc/testsuite/g++.dg/cpp2a/constexpr-dtor3.C        2021-10-05 
23:47:13.970052815 +0200
@@ -180,6 +180,6 @@ f7 ()
  constexpr int
  f8 ()
  {
-  T t4;                        // { dg-error "variable 't4' of non-literal type 'T' 
in 'constexpr' function" }
+  T t4;                        // { dg-error "variable 't4' of non-literal type 'T' in 
'constexpr' function only available with" "" { target c++20_down } }
    return 0;
  }
--- gcc/testsuite/g++.dg/cpp2a/consteval3.C.jj  2020-02-28 17:34:56.393567559 
+0100
+++ gcc/testsuite/g++.dg/cpp2a/consteval3.C     2021-10-06 00:10:50.161489668 
+0200
@@ -1,5 +1,4 @@
-// { dg-do compile }
-// { dg-options "-std=c++2a" }
+// { dg-do compile { target c++20 } }
struct S { S () : a (0), b (1) {} int a, b; };
  int f1 ();            // { dg-message "previous declaration 'int f1\\(\\)'" }
@@ -57,7 +56,8 @@ template consteval float f12 (float x);
  consteval int
  f13 (int x)
  {
-  static int a = 5;            // { dg-error "'a' declared 'static' in 'consteval' 
function" }
-  thread_local int b = 6;      // { dg-error "'b' declared 'thread_local' in 
'consteval' function" }
+  static int a = 5;            // { dg-error "'a' declared 'static' in 'consteval' function 
only available with" "" { target c++20_only } }
+                               // { dg-error "'a' declared 'static' in 'constexpr' 
context" "" { target c++23 } .-1 }
+  thread_local int b = 6;      // { dg-error "'b' declared 'thread_local' in 'consteval' 
function only available with" "" { target c++20_only } }
    return x;
  }

        Jakub


Reply via email to