diff options
author | Patrick Palka <ppalka@redhat.com> | 2020-04-21 18:41:02 -0400 |
---|---|---|
committer | Patrick Palka <ppalka@redhat.com> | 2020-04-21 18:41:02 -0400 |
commit | 0e665f256b4ac8c5f78713ebd4e9378fd4ecf5a8 (patch) | |
tree | 62ef8f7c90b6b9c30ddcedef2cfe428c51b40641 /gcc | |
parent | e76100ced607218a3bf26344fd57d7384a7c18b5 (diff) | |
download | gcc-0e665f256b4ac8c5f78713ebd4e9378fd4ecf5a8.zip gcc-0e665f256b4ac8c5f78713ebd4e9378fd4ecf5a8.tar.gz gcc-0e665f256b4ac8c5f78713ebd4e9378fd4ecf5a8.tar.bz2 |
c++: Constrained inherited constructor template [PR94549]
A comment in satisfy_declaration_constraints says
/* For inherited constructors, consider the original declaration;
it has the correct template information attached. */
d = strip_inheriting_ctors (d);
but it looks like this comment is wrong when the inherited constructor is for an
instantiation of a constructor template. In that case, DECL_TEMPLATE_INFO is
correct and DECL_INHERITED_CTOR points to the constructor template of the base
class rather than to the particular instantiation of the constructor template
(and so the DECL_TI_ARGS of the DECL_INHERITED_CTOR are in their dependent
form).
So doing strip_inheriting_ctors in this case then eventually leads to
satisfy_associated_constraints returning true regardless of the constraints
themselves, due to the passed in 'args' being dependent.
An inherited constructor seems to have a non-empty DECL_TEMPLATE_INFO only when
it's for an instantiation of a constructor template, so this patch fixes this
issue by checking for empty DECL_TEMPLATE_INFO before calling
strip_inheriting_ctors.
There is another unguarded call to strip_inheriting_ctors in
get_normalized_constraints_from_decl, but this one seems to be safe to do
unconditionally because the rest of that function doesn't need/look at the
DECL_TI_ARGS of the decl.
gcc/cp/ChangeLog:
PR c++/94549
* constraint.cc (satisfy_declaration_constraints): Don't strip the
inherited constructor if it already has template information.
gcc/testsuite/ChangeLog:
PR c++/94549
* g++.dg/concepts/inherit-ctor3.C: Adjust expected diagnostics.
* g++.dg/cpp2a/concepts-inherit-ctor4.C: New test.
* g++.dg/cpp2a/concepts-inherit-ctor8.C: New test.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/cp/constraint.cc | 7 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/concepts/inherit-ctor3.C | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor4.C | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor8.C | 20 |
6 files changed, 39 insertions, 7 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 372fd08..67b571c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2020-04-21 Patrick Palka <ppalka@redhat.com> + PR c++/94549 + * constraint.cc (satisfy_declaration_constraints): Don't strip the + inherited constructor if it already has template information. + PR c++/94597 * pt.c (any_template_parm_r) <case IDENTIFIER_NODE>: New case. If this is a conversion operator, visit its TREE_TYPE. diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc index e530841..d56ec10 100644 --- a/gcc/cp/constraint.cc +++ b/gcc/cp/constraint.cc @@ -2737,9 +2737,10 @@ satisfy_declaration_constraints (tree t, subst_info info) { gcc_assert (DECL_P (t)); - /* For inherited constructors, consider the original declaration; - it has the correct template information attached. */ - if (flag_new_inheriting_ctors) + if (!DECL_TEMPLATE_INFO (t)) + /* For inherited constructors without template information, consider + the original declaration; it has the correct template information + attached. */ t = strip_inheriting_ctors (t); /* Update the declaration for diagnostics. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0d67147..87d99b1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2020-04-21 Patrick Palka <ppalka@redhat.com> + + PR c++/94549 + * g++.dg/concepts/inherit-ctor3.C: Adjust expected diagnostics. + * g++.dg/cpp2a/concepts-inherit-ctor4.C: New test. + * g++.dg/cpp2a/concepts-inherit-ctor8.C: New test. + 2020-04-21 Jonathan Wakely <jwakely@redhat.com> PR c++/94149 diff --git a/gcc/testsuite/g++.dg/concepts/inherit-ctor3.C b/gcc/testsuite/g++.dg/concepts/inherit-ctor3.C index abfe96e..6b7a7a4 100644 --- a/gcc/testsuite/g++.dg/concepts/inherit-ctor3.C +++ b/gcc/testsuite/g++.dg/concepts/inherit-ctor3.C @@ -12,12 +12,12 @@ template<typename T> template<typename T> struct S2 : S1<T> { // { dg-error "no matching function" } - using S1<T>::S1; // { dg-error "no matching function" } + using S1<T>::S1; }; struct X { } x; int main() { - S2<X> s1(0); // { dg-error "use of deleted function" } + S2<X> s1(0); // { dg-error "no matching function" } S2<X> s2; // { dg-error "use of deleted function" } } diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor4.C b/gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor4.C index 75190eb3..34eaf22 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor4.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor4.C @@ -10,9 +10,9 @@ template<typename T> template<typename T> struct S2 : S1<T> { - using S1<T>::S1; // { dg-error "no matching function" } + using S1<T>::S1; }; int main() { - S2<int> s(0); // { dg-error "use of deleted function" } + S2<int> s(0); // { dg-error "no matching function" } } diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor8.C b/gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor8.C new file mode 100644 index 0000000..5b571e3 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor8.C @@ -0,0 +1,20 @@ +// PR c++/94549 +// { dg-do compile { target concepts } } + +struct base { + template <typename type> + requires false + base(type); + + template <typename type> + requires true + base(type); +}; + +struct derived : base { + using base::base; +}; + +void foo() { + derived{'G'}; +} |