On Thu, Feb 06, 2025 at 07:32:43PM +0100, Jakub Jelinek wrote: > Hi! > > As mentioned in the PR, https://eel.is/c++draft/conv.lval#note-1 > says that even volatile reads from std::nullptr_t typed objects actually > don't read anything and https://eel.is/c++draft/expr.const#10.9 > says that even those are ok in constant expressions. > > So, the following patch adjusts the r9-4793 changes to have an exception > for NULLPTR_TYPE. > As [conv.lval]/3 also talks about accessing to inactive member, I've added > testcase to cover that as well. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? > > 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)) > + && TREE_CODE (TREE_TYPE (t)) != NULLPTR_TYPE)
Patch looks good but we should use NULLPTR_TYPE_P. > { > 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) || TREE_CODE (type) == NULLPTR_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 > Marek