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

Reply via email to