On 1/29/26 4:23 PM, Jakub Jelinek wrote:
Hi!
The following testcase is incorrectly rejected, because since r15-6744
it adds build_nop to preserve the exact typedef type and
cxx_eval_constant_expression can't fold NOP_EXPR from integer_zerop of one
NULLPTR_TYPE to another NULLPTR_TYPE, while cxx_eval_constant_expression
relies on fold to do such folding.
I see 3 options to fix that, one is deal with this in the r15-6744 spot
and special case NULLPTR_TYPE there and build_zero_cst instead of build_nop
(with similar condition like in the patch below), another possibility is
what this patch does, special case this in cxx_eval_constant_expression, and
another one would be to handle this somewhere in fold-const.cc (e.g. in
fold_convert_loc or there and also in fold_convert_const).
I guess since NULLPTR_TYPE is in tree.def it makes sense for
fold_convert_loc to handle it.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
Or do you prefer some other spot like mentioned above, and/or multiple
spots?
2026-01-28 Jakub Jelinek <[email protected]>
PR c++/123790
* constexpr.cc (cxx_eval_constant_expression) <case NOP_EXPR>: Return
build_zero_cst (type) for NULLPTR_TYPE_P (type) && integer_zeropp (op).
* g++.dg/cpp0x/nullptr47.C: New test.
--- gcc/cp/constexpr.cc.jj 2026-01-28 09:34:32.746243466 +0100
+++ gcc/cp/constexpr.cc 2026-01-28 19:00:14.201290765 +0100
@@ -10138,6 +10138,10 @@ cxx_eval_constant_expression (const cons
break;
}
+ /* fold doesn't optimize NULLPTR_TYPE casts. */
+ if (NULLPTR_TYPE_P (type) && integer_zerop (op))
+ return build_zero_cst (type);
+
if (op == oldop && tcode != UNARY_PLUS_EXPR)
/* We didn't fold at the top so we could check for ptr-int
conversion. */
--- gcc/testsuite/g++.dg/cpp0x/nullptr47.C.jj 2026-01-28 19:03:10.860279799
+0100
+++ gcc/testsuite/g++.dg/cpp0x/nullptr47.C 2026-01-28 19:02:48.805655698
+0100
@@ -0,0 +1,10 @@
+// PR c++/123790
+// { dg-do compile { target c++11 } }
+
+int
+main ()
+{
+ using nullptr_t = decltype (nullptr);
+ constexpr nullptr_t zero = nullptr;
+ constexpr nullptr_t other_zero = zero;
+}
Jakub