On 2/6/25 1:52 PM, Jakub Jelinek wrote:
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:

OK.

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


Reply via email to