aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@redhat.com>2020-07-29 22:06:33 -0400
committerPatrick Palka <ppalka@redhat.com>2020-07-29 22:06:33 -0400
commitdc3d1e181445fafbbd146eb355a750c41c338794 (patch)
treeee9484d0ba615f7e8127a51efd6025ace0f0dade /gcc
parentbea7a39103a5a86d5daabfff746316dfd4e42b3d (diff)
downloadgcc-dc3d1e181445fafbbd146eb355a750c41c338794.zip
gcc-dc3d1e181445fafbbd146eb355a750c41c338794.tar.gz
gcc-dc3d1e181445fafbbd146eb355a750c41c338794.tar.bz2
c++: constraints and explicit instantiation [PR96164]
When considering to instantiate a member of a class template as part of an explicit instantiation of the class template, we need to first check the member's constraints before proceeding with the instantiation of the member. gcc/cp/ChangeLog: PR c++/96164 * constraint.cc (constraints_satisfied_p): Return true if !flags_concepts. * pt.c (do_type_instantiation): Update a paragraph taken from [temp.explicit] to reflect the latest specification. Don't instantiate a member with unsatisfied constraints. gcc/testsuite/ChangeLog: PR c++/96164 * g++.dg/cpp2a/concepts-explicit-inst5.C: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/constraint.cc6
-rw-r--r--gcc/cp/pt.c23
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/concepts-explicit-inst5.C14
3 files changed, 31 insertions, 12 deletions
diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index d0da230..e4aace5 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -2864,6 +2864,9 @@ constraint_satisfaction_value (tree t, tree args, tsubst_flags_t complain)
bool
constraints_satisfied_p (tree t)
{
+ if (!flag_concepts)
+ return true;
+
return constraint_satisfaction_value (t, tf_none) == boolean_true_node;
}
@@ -2873,6 +2876,9 @@ constraints_satisfied_p (tree t)
bool
constraints_satisfied_p (tree t, tree args)
{
+ if (!flag_concepts)
+ return true;
+
return constraint_satisfaction_value (t, args, tf_none) == boolean_true_node;
}
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 6a42cf9..9b4e6ce 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -24928,23 +24928,22 @@ do_type_instantiation (tree t, tree storage, tsubst_flags_t complain)
[temp.explicit]
- The explicit instantiation of a class template specialization
- implies the instantiation of all of its members not
- previously explicitly specialized in the translation unit
- containing the explicit instantiation.
-
- Of course, we can't instantiate member template classes, since we
- don't have any arguments for them. Note that the standard is
- unclear on whether the instantiation of the members are
- *explicit* instantiations or not. However, the most natural
- interpretation is that it should be an explicit
- instantiation. */
+ An explicit instantiation that names a class template
+ specialization is also an explicit instantiation of the same
+ kind (declaration or definition) of each of its members (not
+ including members inherited from base classes and members
+ that are templates) that has not been previously explicitly
+ specialized in the translation unit containing the explicit
+ instantiation, provided that the associated constraints, if
+ any, of that member are satisfied by the template arguments
+ of the explicit instantiation. */
for (tree fld = TYPE_FIELDS (t); fld; fld = DECL_CHAIN (fld))
if ((VAR_P (fld)
|| (TREE_CODE (fld) == FUNCTION_DECL
&& !static_p
&& user_provided_p (fld)))
- && DECL_TEMPLATE_INSTANTIATION (fld))
+ && DECL_TEMPLATE_INSTANTIATION (fld)
+ && constraints_satisfied_p (fld))
{
mark_decl_instantiated (fld, extern_p);
if (! extern_p)
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-explicit-inst5.C b/gcc/testsuite/g++.dg/cpp2a/concepts-explicit-inst5.C
new file mode 100644
index 0000000..05959a8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-explicit-inst5.C
@@ -0,0 +1,14 @@
+// PR c++/96164
+// { dg-do compile { target concepts } }
+
+template <int N>
+struct A {
+ void f() requires (N == 3) { static_assert(N == 3); }
+};
+template struct A<2>;
+
+template <int N>
+struct B {
+ void f() requires (N == 2) { static_assert(N == 3); } // { dg-error "assert" }
+};
+template struct B<2>;