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