public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
From: Patrick Palka <ppalka@gcc.gnu.org>
To: gcc-cvs@gcc.gnu.org
Subject: [gcc r13-2878] c++ modules: variable template partial spec fixes [PR107033]
Date: Mon, 26 Sep 2022 15:30:59 +0000 (GMT)	[thread overview]
Message-ID: <20220926153059.49E243858D37@sourceware.org> (raw)

https://gcc.gnu.org/g:099a66498bf7a40764002793eba66c881a251b76

commit r13-2878-g099a66498bf7a40764002793eba66c881a251b76
Author: Patrick Palka <ppalka@redhat.com>
Date:   Mon Sep 26 11:30:17 2022 -0400

    c++ modules: variable template partial spec fixes [PR107033]
    
    In r13-2775-g32d8123cd6ce87 I missed that we need to adjust the call to
    add_mergeable_specialization in the MK_partial case to correctly handle
    variable template partial specializations (it currently assumes we're
    always dealing with one for a class template).  This fixes an ICE when
    converting the testcase from that commit to use an importable header
    instead of a named module.
    
            PR c++/107033
    
    gcc/cp/ChangeLog:
    
            * module.cc (trees_in::decl_value): In the MK_partial case for
            a variable template partial specialization, pass decl_p=true to
            add_mergeable_specialization, and set spec to the VAR_DECL not
            the TEMPLATE_DECL.
            * pt.cc (add_mergeable_specialization): For a variable template
            partial specialization, set the TREE_TYPE of the new
            DECL_TEMPLATE_SPECIALIZATIONS node to the TREE_TYPE of the
            VAR_DECL not the VAR_DECL itself.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/modules/partial-2.cc, g++.dg/modules/partial-2.h: New
            files, factored out from ...
            * g++.dg/modules/partial-2_a.C, g++.dg/modules/partial-2_b.C: ...
            these.
            * g++.dg/modules/partial-2_c.H: New test.
            * g++.dg/modules/partial-2_d.C: New test.

Diff:
---
 gcc/cp/module.cc                           | 17 ++++++++-----
 gcc/cp/pt.cc                               |  2 +-
 gcc/testsuite/g++.dg/modules/partial-2.cc  | 17 +++++++++++++
 gcc/testsuite/g++.dg/modules/partial-2.h   | 38 +++++++++++++++++++++++++++++
 gcc/testsuite/g++.dg/modules/partial-2_a.C | 39 +-----------------------------
 gcc/testsuite/g++.dg/modules/partial-2_b.C | 18 +-------------
 gcc/testsuite/g++.dg/modules/partial-2_c.H |  5 ++++
 gcc/testsuite/g++.dg/modules/partial-2_d.C |  8 ++++++
 8 files changed, 82 insertions(+), 62 deletions(-)

diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index f23832cb56a..7496df5e843 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -8185,13 +8185,18 @@ trees_in::decl_value ()
 	/* Set the TEMPLATE_DECL's type.  */
 	TREE_TYPE (decl) = TREE_TYPE (inner);
 
-      if (mk & MK_template_mask
-	  || mk == MK_partial)
+      /* Add to specialization tables now that constraints etc are
+	 added.  */
+      if (mk == MK_partial)
 	{
-	  /* Add to specialization tables now that constraints etc are
-	     added.  */
-	  bool is_type = mk == MK_partial || !(mk & MK_tmpl_decl_mask);
-
+	  bool is_type = TREE_CODE (inner) == TYPE_DECL;
+	  spec.spec = is_type ? type : inner;
+	  add_mergeable_specialization (!is_type, false,
+					&spec, decl, spec_flags);
+	}
+      else if (mk & MK_template_mask)
+	{
+	  bool is_type = !(mk & MK_tmpl_decl_mask);
 	  spec.spec = is_type ? type : mk & MK_tmpl_tmpl_mask ? inner : decl;
 	  add_mergeable_specialization (!is_type,
 					!is_type && mk & MK_tmpl_alias_mask,
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index db4e808adec..1f088fe281e 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -31010,7 +31010,7 @@ add_mergeable_specialization (bool decl_p, bool alias_p, spec_entry *elt,
       /* A partial specialization.  */
       tree cons = tree_cons (elt->args, decl,
 			     DECL_TEMPLATE_SPECIALIZATIONS (elt->tmpl));
-      TREE_TYPE (cons) = elt->spec;
+      TREE_TYPE (cons) = decl_p ? TREE_TYPE (elt->spec) : elt->spec;
       DECL_TEMPLATE_SPECIALIZATIONS (elt->tmpl) = cons;
     }
 }
diff --git a/gcc/testsuite/g++.dg/modules/partial-2.cc b/gcc/testsuite/g++.dg/modules/partial-2.cc
new file mode 100644
index 00000000000..1316bf5e1c5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/partial-2.cc
@@ -0,0 +1,17 @@
+static_assert(is_reference_v<int&>);
+static_assert(is_reference_v<int&&>);
+static_assert(!is_reference_v<int>);
+
+static_assert(A::is_reference_v<long&>);
+static_assert(A::is_reference_v<long&&>);
+static_assert(!A::is_reference_v<long>);
+
+#if __cpp_concepts
+static_assert(concepts::is_reference_v<char&>);
+static_assert(concepts::is_reference_v<char&&>);
+static_assert(!concepts::is_reference_v<char>);
+
+static_assert(concepts::A::is_reference_v<bool&>);
+static_assert(concepts::A::is_reference_v<bool&&>);
+static_assert(!concepts::A::is_reference_v<bool>);
+#endif
diff --git a/gcc/testsuite/g++.dg/modules/partial-2.h b/gcc/testsuite/g++.dg/modules/partial-2.h
new file mode 100644
index 00000000000..afcfce791b3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/partial-2.h
@@ -0,0 +1,38 @@
+template<class T> constexpr bool is_reference_v = false;
+template<class T> constexpr bool is_reference_v<T&> = true;
+template<class T> constexpr bool is_reference_v<T&&> = true;
+
+struct A {
+  template<class T> static constexpr bool is_reference_v = false;
+};
+
+template<class T> constexpr bool A::is_reference_v<T&> = true;
+template<class T> constexpr bool A::is_reference_v<T&&> = true;
+
+#if __cpp_concepts
+namespace concepts {
+  template<class T> bool is_reference_v;
+
+  template<class T> requires __is_same(T, T&)
+  constexpr bool is_reference_v<T> = true;
+
+  template<class T> requires __is_same(T, T&&) && (!__is_same(T, T&))
+  constexpr bool is_reference_v<T> = true;
+
+  template<class T> requires (!__is_same(T, T&)) && (!__is_same(T, T&&))
+  constexpr bool is_reference_v<T> = false;
+
+  struct A {
+    template<class T> static bool is_reference_v;
+  };
+
+  template<class T> requires __is_same(T, T&)
+  constexpr bool A::is_reference_v<T> = true;
+
+  template<class T> requires __is_same(T, T&&) && (!__is_same(T, T&))
+  constexpr bool A::is_reference_v<T> = true;
+
+  template<class T> requires (!__is_same(T, T&)) && (!__is_same(T, T&&))
+  constexpr bool A::is_reference_v<T> = false;
+}
+#endif
diff --git a/gcc/testsuite/g++.dg/modules/partial-2_a.C b/gcc/testsuite/g++.dg/modules/partial-2_a.C
index 2681bb59ce8..1582f56f2d4 100644
--- a/gcc/testsuite/g++.dg/modules/partial-2_a.C
+++ b/gcc/testsuite/g++.dg/modules/partial-2_a.C
@@ -3,41 +3,4 @@
 // { dg-module-cmi pr106826 }
 export module pr106826;
 
-template<class T> constexpr bool is_reference_v = false;
-template<class T> constexpr bool is_reference_v<T&> = true;
-template<class T> constexpr bool is_reference_v<T&&> = true;
-
-struct A {
-  template<class T> static constexpr bool is_reference_v = false;
-};
-
-template<class T> constexpr bool A::is_reference_v<T&> = true;
-template<class T> constexpr bool A::is_reference_v<T&&> = true;
-
-#if __cpp_concepts
-namespace concepts {
-  template<class T> bool is_reference_v;
-
-  template<class T> requires __is_same(T, T&)
-  constexpr bool is_reference_v<T> = true;
-
-  template<class T> requires __is_same(T, T&&) && (!__is_same(T, T&))
-  constexpr bool is_reference_v<T> = true;
-
-  template<class T> requires (!__is_same(T, T&)) && (!__is_same(T, T&&))
-  constexpr bool is_reference_v<T> = false;
-
-  struct A {
-    template<class T> static bool is_reference_v;
-  };
-
-  template<class T> requires __is_same(T, T&)
-  constexpr bool A::is_reference_v<T> = true;
-
-  template<class T> requires __is_same(T, T&&) && (!__is_same(T, T&))
-  constexpr bool A::is_reference_v<T> = true;
-
-  template<class T> requires (!__is_same(T, T&)) && (!__is_same(T, T&&))
-  constexpr bool A::is_reference_v<T> = false;
-}
-#endif
+#include "partial-2.h"
diff --git a/gcc/testsuite/g++.dg/modules/partial-2_b.C b/gcc/testsuite/g++.dg/modules/partial-2_b.C
index 0af41ef5e5e..1b0c7a53e9f 100644
--- a/gcc/testsuite/g++.dg/modules/partial-2_b.C
+++ b/gcc/testsuite/g++.dg/modules/partial-2_b.C
@@ -2,20 +2,4 @@
 // { dg-additional-options -fmodules-ts }
 module pr106826;
 
-static_assert(is_reference_v<int&>);
-static_assert(is_reference_v<int&&>);
-static_assert(!is_reference_v<int>);
-
-static_assert(A::is_reference_v<long&>);
-static_assert(A::is_reference_v<long&&>);
-static_assert(!A::is_reference_v<long>);
-
-#if __cpp_concepts
-static_assert(concepts::is_reference_v<char&>);
-static_assert(concepts::is_reference_v<char&&>);
-static_assert(!concepts::is_reference_v<char>);
-
-static_assert(concepts::A::is_reference_v<bool&>);
-static_assert(concepts::A::is_reference_v<bool&&>);
-static_assert(!concepts::A::is_reference_v<bool>);
-#endif
+#include "partial-2.cc"
diff --git a/gcc/testsuite/g++.dg/modules/partial-2_c.H b/gcc/testsuite/g++.dg/modules/partial-2_c.H
new file mode 100644
index 00000000000..bd838529ce0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/partial-2_c.H
@@ -0,0 +1,5 @@
+// PR c++/107033
+// { dg-additional-options -fmodule-header }
+// { dg-module-cmi {} }
+
+#include "partial-2.h"
diff --git a/gcc/testsuite/g++.dg/modules/partial-2_d.C b/gcc/testsuite/g++.dg/modules/partial-2_d.C
new file mode 100644
index 00000000000..ed54d3c2884
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/partial-2_d.C
@@ -0,0 +1,8 @@
+// PR c++/107033
+// { dg-additional-options -fmodules-ts }
+// { dg-module-cmi pr107033 }
+export module pr107033;
+
+import "partial-2_c.H";
+
+#include "partial-2.cc"

                 reply	other threads:[~2022-09-26 15:30 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220926153059.49E243858D37@sourceware.org \
    --to=ppalka@gcc.gnu.org \
    --cc=gcc-cvs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).