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> ();
+}

Reply via email to