On Thu, Feb 06, 2025 at 01:45:59PM -0500, Marek Polacek wrote: > > --- gcc/cp/constexpr.cc.jj 2025-02-05 13:14:34.771198185 +0100 > > +++ gcc/cp/constexpr.cc 2025-02-06 09:53:03.236587121 +0100 > > @@ -9717,7 +9717,8 @@ potential_constant_expression_1 (tree t, > > return true; > > > > if (TREE_THIS_VOLATILE (t) && want_rval > > - && !FUNC_OR_METHOD_TYPE_P (TREE_TYPE (t))) > > + && !FUNC_OR_METHOD_TYPE_P (TREE_TYPE (t)) > > + && TREE_CODE (TREE_TYPE (t)) != NULLPTR_TYPE) > > Patch looks good but we should use NULLPTR_TYPE_P.
You're right. Here is the patch adjusted: 2025-02-06 Jakub Jelinek <ja...@redhat.com> PR c++/118661 * constexpr.cc (potential_constant_expression_1): Don't diagnose lvalue-to-rvalue conversion of volatile lvalue if it has NULLPTR_TYPE. * decl2.cc (decl_maybe_constant_var_p): Return true for constexpr decls with NULLPTR_TYPE even if they are volatile. * g++.dg/cpp0x/constexpr-volatile4.C: New test. * g++.dg/cpp0x/constexpr-union9.C: New test. --- gcc/cp/constexpr.cc.jj 2025-02-05 13:14:34.771198185 +0100 +++ gcc/cp/constexpr.cc 2025-02-06 09:53:03.236587121 +0100 @@ -9717,7 +9717,8 @@ potential_constant_expression_1 (tree t, return true; if (TREE_THIS_VOLATILE (t) && want_rval - && !FUNC_OR_METHOD_TYPE_P (TREE_TYPE (t))) + && !FUNC_OR_METHOD_TYPE_P (TREE_TYPE (t)) + && !NULLPTR_TYPE_P (TREE_TYPE (t))) { if (flags & tf_error) constexpr_error (loc, fundef_p, "lvalue-to-rvalue conversion of " --- gcc/cp/decl2.cc.jj 2025-01-27 16:45:45.455970792 +0100 +++ gcc/cp/decl2.cc 2025-02-06 09:53:53.150890600 +0100 @@ -4985,7 +4985,8 @@ decl_maybe_constant_var_p (tree decl) tree type = TREE_TYPE (decl); if (!VAR_P (decl)) return false; - if (DECL_DECLARED_CONSTEXPR_P (decl) && !TREE_THIS_VOLATILE (decl)) + if (DECL_DECLARED_CONSTEXPR_P (decl) + && (!TREE_THIS_VOLATILE (decl) || NULLPTR_TYPE_P (type))) return true; if (DECL_HAS_VALUE_EXPR_P (decl)) /* A proxy isn't constant. */ --- gcc/testsuite/g++.dg/cpp0x/constexpr-volatile4.C.jj 2025-02-06 09:50:43.339539282 +0100 +++ gcc/testsuite/g++.dg/cpp0x/constexpr-volatile4.C 2025-02-06 09:50:16.071919784 +0100 @@ -0,0 +1,20 @@ +// PR c++/118661 +// { dg-do compile { target c++11 } } + +using nullptr_t = decltype (nullptr); +constexpr volatile nullptr_t a = {}; +constexpr nullptr_t b = a; + +constexpr nullptr_t +foo () +{ +#if __cplusplus >= 201402L + volatile nullptr_t c = {}; + return c; +#else + return nullptr; +#endif +} + +static_assert (b == nullptr, ""); +static_assert (foo () == nullptr, ""); --- gcc/testsuite/g++.dg/cpp0x/constexpr-union9.C.jj 2025-02-06 09:57:46.149639270 +0100 +++ gcc/testsuite/g++.dg/cpp0x/constexpr-union9.C 2025-02-06 10:01:08.472815988 +0100 @@ -0,0 +1,16 @@ +// PR c++/118661 +// { dg-do compile { target c++11 } } + +using nullptr_t = decltype (nullptr); +union U { int i; nullptr_t n; }; +constexpr U u = { 42 }; +static_assert (u.n == nullptr, ""); + +#if __cplusplus >= 201402L +constexpr nullptr_t +foo () +{ + union U { int i; nullptr_t n; } u = { 42 }; + return u.n; +} +#endif Jakub