]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: address of class NTTP object as targ [PR113242]
authorPatrick Palka <ppalka@redhat.com>
Wed, 17 Jan 2024 18:01:01 +0000 (13:01 -0500)
committerPatrick Palka <ppalka@redhat.com>
Wed, 17 Jan 2024 18:01:01 +0000 (13:01 -0500)
invalid_tparm_referent_p was rejecting using the address of a class NTTP
object as a template argument, but this should be fine.

PR c++/113242
PR c++/99493

gcc/cp/ChangeLog:

* pt.cc (invalid_tparm_referent_p) <case ADDR_EXPR>: Suppress
DECL_ARTIFICIAL rejection test for class NTTP objects.

gcc/testsuite/ChangeLog:

* g++.dg/cpp2a/nontype-class61.C: New test.
* g++.dg/cpp2a/nontype-class62.C: New test.

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

index b6117231de1c71d23cc6bdca0ad430e5a1e4d9cb..f82d018c9816d0c35189113d98664a472e8e9431 100644 (file)
@@ -7217,8 +7217,10 @@ invalid_tparm_referent_p (tree type, tree expr, tsubst_flags_t complain)
           * a string literal (5.13.5),
           * the result of a typeid expression (8.2.8), or
           * a predefined __func__ variable (11.4.1).  */
-       else if (VAR_P (decl) && DECL_ARTIFICIAL (decl))
+       else if (VAR_P (decl) && DECL_ARTIFICIAL (decl)
+                && !DECL_NTTP_OBJECT_P (decl))
          {
+           gcc_checking_assert (DECL_TINFO_P (decl) || DECL_FNAME_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/cpp2a/nontype-class61.C b/gcc/testsuite/g++.dg/cpp2a/nontype-class61.C
new file mode 100644 (file)
index 0000000..4033cf0
--- /dev/null
@@ -0,0 +1,25 @@
+// PR c++/113242
+// { dg-do compile { target c++20 } }
+
+struct wrapper { int n; };
+
+template<const wrapper& X>
+void f1() {
+  static_assert(X.n == 42);
+}
+
+template<const wrapper* X>
+void f2() {
+  static_assert(X->n == 42);
+}
+
+template<wrapper X>
+void g() {
+  f1<X>();
+  f2<&X>();
+}
+
+int main() {
+  constexpr wrapper X = {42};
+  g<X>();
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/nontype-class62.C b/gcc/testsuite/g++.dg/cpp2a/nontype-class62.C
new file mode 100644 (file)
index 0000000..f5068fb
--- /dev/null
@@ -0,0 +1,8 @@
+// PR c++/99493
+// { dg-do compile { target c++20 } }
+
+struct owner{int m;};
+struct view{const int*m;constexpr view(const owner&o):m{&o.m}{}};
+template<view V>struct constant{};
+template<owner O>constexpr constant<O>v{};
+constexpr auto a=v<owner{}>;