Commit 0e665f25 by Patrick Palka

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.
parent e76100ce
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.
......
......@@ -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. */
......
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
......
......@@ -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" }
}
......@@ -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" }
}
// 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'};
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment