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