On 4/20/20 4:38 PM, Patrick Palka wrote:
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 this comment seems to be false when the inherited constructor points to an
instantiation of a constructor template. In this 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.
Since DECL_TEMPLATE_INFO seems to be non-NULL for an inherited constructor only
when the inherited constructor points to an instantiation of a constructor
template, this patch fixes this issue by avoiding to call strip_inheriting_ctors
when DECL_TEMPLATE_INFO is already non-NULL.
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.
Passes 'make check-c++', does this look OK to commit after bootstrap/regtesting?
OK.
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: Adjust expected diagnostics.
* g++.dg/cpp2a/concepts-inherit-ctor8.C: New test.
---
gcc/cp/constraint.cc | 7 ++++---
gcc/testsuite/g++.dg/concepts/inherit-ctor3.C | 4 ++--
.../g++.dg/cpp2a/concepts-inherit-ctor4.C | 4 ++--
.../g++.dg/cpp2a/concepts-inherit-ctor8.C | 20 +++++++++++++++++++
4 files changed, 28 insertions(+), 7 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor8.C
diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 320792195d6..b76402c2f85 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/g++.dg/concepts/inherit-ctor3.C
b/gcc/testsuite/g++.dg/concepts/inherit-ctor3.C
index abfe96e8240..6b7a7a43910 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 75190eb3413..34eaf22c26c 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 00000000000..5b571e32318
--- /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'};
+}