Tested x86_64-pc-linux-gnu, applying to trunk.

-- 8< --

Apparently I wasn't actually running the testsuite in C++26 mode like I
thought I was, so there were some failures I wasn't seeing.

The constexpr hunk fixes regressions with the P2738 implementation; we still
need to use the old handling for casting from void pointers to heap
variables.

        PR c++/110344

gcc/cp/ChangeLog:

        * constexpr.cc (cxx_eval_constant_expression): Move P2738 handling
        after heap handling.
        * name-lookup.cc (get_cxx_dialect_name): Add C++26.

gcc/testsuite/ChangeLog:

        * g++.dg/cpp0x/constexpr-cast2.C: Adjust for P2738.
        * g++.dg/ipa/devirt-45.C: Handle -fimplicit-constexpr.
---
 gcc/cp/constexpr.cc                          | 21 ++++++++++----------
 gcc/cp/name-lookup.cc                        |  2 ++
 gcc/testsuite/g++.dg/cpp0x/constexpr-cast2.C |  6 +++---
 gcc/testsuite/g++.dg/ipa/devirt-45.C         |  2 +-
 4 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index cca0435bafc..9f96a6c41ea 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -7681,17 +7681,6 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, 
tree t,
            && !is_std_construct_at (ctx->call)
            && !is_std_allocator_allocate (ctx->call))
          {
-           /* P2738 (C++26): a conversion from a prvalue P of type "pointer to
-              cv void" to a pointer-to-object type T unless P points to an
-              object whose type is similar to T.  */
-           if (cxx_dialect > cxx23)
-             if (tree ob
-                 = cxx_fold_indirect_ref (ctx, loc, TREE_TYPE (type), op))
-               {
-                 r = build1 (ADDR_EXPR, type, ob);
-                 break;
-               }
-
            /* Likewise, don't error when casting from void* when OP is
               &heap uninit and similar.  */
            tree sop = tree_strip_nop_conversions (op);
@@ -7699,6 +7688,16 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, 
tree t,
                && VAR_P (TREE_OPERAND (sop, 0))
                && DECL_ARTIFICIAL (TREE_OPERAND (sop, 0)))
              /* OK */;
+           /* P2738 (C++26): a conversion from a prvalue P of type "pointer to
+              cv void" to a pointer-to-object type T unless P points to an
+              object whose type is similar to T.  */
+           else if (cxx_dialect > cxx23
+                    && (sop = cxx_fold_indirect_ref (ctx, loc,
+                                                     TREE_TYPE (type), sop)))
+             {
+               r = build1 (ADDR_EXPR, type, sop);
+               break;
+             }
            else
              {
                if (!ctx->quiet)
diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc
index 74565184403..2d747561e1f 100644
--- a/gcc/cp/name-lookup.cc
+++ b/gcc/cp/name-lookup.cc
@@ -6731,6 +6731,8 @@ get_cxx_dialect_name (enum cxx_dialect dialect)
       return "C++20";
     case cxx23:
       return "C++23";
+    case cxx26:
+      return "C++26";
     }
 }
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-cast2.C 
b/gcc/testsuite/g++.dg/cpp0x/constexpr-cast2.C
index b79e8a90131..3efbd92f043 100644
--- a/gcc/testsuite/g++.dg/cpp0x/constexpr-cast2.C
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-cast2.C
@@ -6,11 +6,11 @@ static int i;
 constexpr void *vp0 = nullptr;
 constexpr void *vpi = &i;
 constexpr int *p1 = (int *) vp0; // { dg-error "cast from .void\\*. is not 
allowed" }
-constexpr int *p2 = (int *) vpi; // { dg-error "cast from .void\\*. is not 
allowed" }
+constexpr int *p2 = (int *) vpi; // { dg-error "cast from .void\\*. is not 
allowed" "" { target c++23_down } }
 constexpr int *p3 = static_cast<int *>(vp0); // { dg-error "cast from 
.void\\*. is not allowed" }
-constexpr int *p4 = static_cast<int *>(vpi); // { dg-error "cast from 
.void\\*. is not allowed" }
+constexpr int *p4 = static_cast<int *>(vpi); // { dg-error "cast from 
.void\\*. is not allowed" "" { target c++23_down } }
 constexpr void *p5 = vp0;
 constexpr void *p6 = vpi;
 
 constexpr int *pi = &i;
-constexpr bool b = ((int *)(void *) pi == pi); // { dg-error "cast from 
.void\\*. is not allowed" }
+constexpr bool b = ((int *)(void *) pi == pi); // { dg-error "cast from 
.void\\*. is not allowed" "" { target c++23_down } }
diff --git a/gcc/testsuite/g++.dg/ipa/devirt-45.C 
b/gcc/testsuite/g++.dg/ipa/devirt-45.C
index c26be21964c..019b454835c 100644
--- a/gcc/testsuite/g++.dg/ipa/devirt-45.C
+++ b/gcc/testsuite/g++.dg/ipa/devirt-45.C
@@ -37,5 +37,5 @@ int main()
 }
 
 /* One invocation is A::foo () other is B::foo () even though the type is 
destroyed and rebuilt in test() */
-/* { dg-final { scan-ipa-dump-times "Discovered a virtual call to a known 
target\[^\\n\]*A::foo" 2 "inline"  } } */
+/* { dg-final { scan-ipa-dump-times "Discovered a virtual call to a known 
target\[^\\n\]*A::foo" 2 "inline" { target { ! implicit_constexpr } } } }*/
 /* { dg-final { scan-ipa-dump-times "Discovered a virtual call to a known 
target\[^\\n\]*B::foo" 1 "inline"  } } */

base-commit: 49a2a63e6518cfa294d903f5f62ab1f922df438e
-- 
2.39.3

Reply via email to