https://gcc.gnu.org/g:37738f0422aa4d70ac5a71bd82b6c257a9309bde
commit r16-7630-g37738f0422aa4d70ac5a71bd82b6c257a9309bde Author: Jakub Jelinek <[email protected]> Date: Sun Feb 22 22:09:13 2026 +0100 c++: Fix up recent regression in convert_nontype_argument for C++1[14] [PR124173] The following testcase is rejected since my recent convert_nontype_argument change, but only in C++11/14 modes. The problem is that C++17 says that all NTTPs should be converted constant expressions, but C++11 only said that for integral and enumeration ones and something that applied to the decltype(nullptr) case was - a constant expression that evaluates to a null pointer value The problem is that for NULLPTR_TYPE_P for C++11/14, we just never called maybe_constant_value, so obviously just making sure it is integer_zerop and without tf_error returning NULL_TREE otherwise changes behavior on valid programs, we really need to constant evaluate it first. The following patch fixes that. I'm afraid I actually don't know what exactly C++14 specifies, whether I've grabbed a pre-C++14 or post-C++14 draft, which looked like the C++17 wording. So, if C++14 needs something different, we'll need a further change, but this at least fixes the regression. 2026-02-22 Jakub Jelinek <[email protected]> PR c++/124173 * pt.cc (convert_nontype_argument): For C++11/C++14 handle NULLPTR_TYPE_P non-type arguments like TYPE_PTR_P. * g++.dg/cpp0x/pr124173.C: New test. Diff: --- gcc/cp/pt.cc | 6 ++++-- gcc/testsuite/g++.dg/cpp0x/pr124173.C | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 11711ee3543e..bcc1525ff8b6 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -7690,10 +7690,12 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) /* EXPR may have become value-dependent. */ val_dep_p = value_dependent_expression_p (expr); } - else if (TYPE_PTR_OR_PTRMEM_P (type)) + else if (TYPE_PTR_OR_PTRMEM_P (type) + || NULLPTR_TYPE_P (type)) { tree folded = maybe_constant_value (expr, NULL_TREE, mce_true); - if (TYPE_PTR_P (type) ? integer_zerop (folded) + if ((TYPE_PTR_P (type) || NULLPTR_TYPE_P (type)) + ? integer_zerop (folded) : null_member_pointer_value_p (folded)) expr = folded; } diff --git a/gcc/testsuite/g++.dg/cpp0x/pr124173.C b/gcc/testsuite/g++.dg/cpp0x/pr124173.C new file mode 100644 index 000000000000..a8e9ae7c4545 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/pr124173.C @@ -0,0 +1,15 @@ +// PR c++/124173 +// { dg-do compile { target c++11 } } + +template <decltype (nullptr)> +void +foo () +{ +} + +int +main () +{ + constexpr decltype (nullptr) t = nullptr; + foo <t> (); +}
