]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: fix ICE with invalid targ [PR125043]
authorMarek Polacek <polacek@redhat.com>
Thu, 7 May 2026 22:09:57 +0000 (18:09 -0400)
committerMarek Polacek <polacek@redhat.com>
Fri, 8 May 2026 21:41:48 +0000 (17:41 -0400)
The patch that allowed DECL_NTTP_OBJECT_P in invalid_tparm_referent_p
also added the assert checking for tinfos/__func__ (r14-8189).  But in
these tests we got to the assert with a temporary object coming from
create_temporary_var: either a reference temporary or compound literal
temporary.  The former could be checked by seeing if the name starts
with _ZGR but the latter don't have it.  So perhaps we can just check
DECL_IGNORED_P, always set for create_temporary_var objects.

PR c++/115181
PR c++/125043
PR c++/124979

gcc/cp/ChangeLog:

* pt.cc (invalid_tparm_referent_p): Allow DECL_IGNORED_P in an
assert.

gcc/testsuite/ChangeLog:

* g++.dg/cpp1z/nontype-auto27.C: New test.
* g++.dg/cpp1z/nontype-auto28.C: New test.
* g++.dg/cpp2a/nontype-class75.C: New test.

Reviewed-by: Jason Merrill <jason@redhat.com>
gcc/cp/pt.cc
gcc/testsuite/g++.dg/cpp1z/nontype-auto27.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp1z/nontype-auto28.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp2a/nontype-class75.C [new file with mode: 0644]

index 6992b5196fe1a59a1e5d5b515989d6fcdd09f416..b6e8948f005a42213a401b8c690d8f57c4bda50c 100644 (file)
@@ -7439,18 +7439,22 @@ invalid_tparm_referent_p (tree type, tree expr, tsubst_flags_t complain)
                        "because %qD has no linkage", expr, type, decl);
            return true;
          }
-       /* C++17: For a non-type template-parameter of reference or pointer
-          type, the value of the constant expression shall not refer to (or
-          for a pointer type, shall not be the address of):
-          * a subobject (4.5),
-          * a temporary object (15.2),
-          * a string literal (5.13.5),
-          * the result of a typeid expression (8.2.8), or
-          * a predefined __func__ variable (11.4.1).  */
+       /* For a constant template parameter of reference or pointer type,
+          or for each non-static data member of reference or pointer type
+          in a constant template parameter of class type or subobject thereof,
+          the reference or pointer value shall not refer or point to
+          (respectively):
+          -- a temporary object,
+          -- a string literal object,
+          -- the result of a typeid expression,
+          -- a predefined __func__ variable, or
+          -- a subobject of one of the above.  */
        else if (VAR_P (decl) && DECL_ARTIFICIAL (decl)
                 && !DECL_NTTP_OBJECT_P (decl))
          {
-           gcc_checking_assert (DECL_TINFO_P (decl) || DECL_FNAME_P (decl));
+           gcc_checking_assert (DECL_TINFO_P (decl)
+                                || DECL_FNAME_P (decl)
+                                || DECL_IGNORED_P (decl));
            if (complain & tf_error)
              error ("the address of %qD is not a valid template argument",
                     decl);
diff --git a/gcc/testsuite/g++.dg/cpp1z/nontype-auto27.C b/gcc/testsuite/g++.dg/cpp1z/nontype-auto27.C
new file mode 100644 (file)
index 0000000..51ff86d
--- /dev/null
@@ -0,0 +1,5 @@
+// PR c++/115181
+// { dg-do compile { target c++17 } }
+
+template <auto> struct S {};
+__extension__ S<(int[]){1}> x;  // { dg-error "not a valid template argument" }
diff --git a/gcc/testsuite/g++.dg/cpp1z/nontype-auto28.C b/gcc/testsuite/g++.dg/cpp1z/nontype-auto28.C
new file mode 100644 (file)
index 0000000..d9165f8
--- /dev/null
@@ -0,0 +1,14 @@
+// PR c++/125043
+// { dg-do compile { target c++17 } }
+
+template <auto V>
+struct wrapper {
+    static constexpr const auto& value = V;
+};
+
+template <int const& I>
+auto f() -> void;
+
+auto main() -> int {
+    f<wrapper<42>::value>();  // { dg-error "no matching function|not a valid template argument" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/nontype-class75.C b/gcc/testsuite/g++.dg/cpp2a/nontype-class75.C
new file mode 100644 (file)
index 0000000..a30ccbe
--- /dev/null
@@ -0,0 +1,34 @@
+// PR c++/124979
+// { dg-do compile { target c++20 } }
+
+template<auto X, class = decltype(X)>
+struct cw;
+
+struct base {
+
+    template <class L>
+    friend constexpr auto operator &(L) noexcept
+        -> cw<(&L::value)> {
+        return {};
+    }
+};
+
+template<auto X, class>
+struct cw : base {
+    static constexpr const auto& value = X;
+};
+    template <auto L, auto R>
+    constexpr auto operator ->*(cw<L>, cw<R>) noexcept
+        -> cw<L ->* R> {
+        return {};
+    }
+
+struct Divide { int value; };
+auto cvalue = cw<&Divide::value>{};
+constexpr const Divide &t = {42};
+auto co = cw<Divide{42}>{};
+auto co1 = cw<&t>{};  // { dg-error "not a valid template argument|is invalid" }
+
+template<class> class TD;
+template<int t> class TD<cw<t>>{};
+TD<decltype((co1)->*cvalue)> _;          // { dg-error "is invalid" }