Commit ac308262 by Jason Merrill Committed by Jason Merrill

PR c++/91930 - ICE with constrained inherited default ctor.

The testcase was crashing because lazily_declare_fn was failing to add a
defaulted constructor, because the implicit declaration was less constrained
than the inherited default constructor.  But when we have an inherited
constructor, we shouldn't be trying to declare a default constructor in the
first place, because it counts as "a user-declared constructor".  With that
fixed I needed to adjust a couple of inherited constructor testcases that
previously had been diagnosing the default constructor as deleted rather
than not declared.

	* name-lookup.c (do_class_using_decl): Set TYPE_HAS_USER_CONSTRUCTOR
	for inherited constructor.

From-SVN: r276968
parent 10aabe33
2019-10-14 Jason Merrill <jason@redhat.com>
PR c++/91930 - ICE with constrained inherited default ctor.
* name-lookup.c (do_class_using_decl): Set TYPE_HAS_USER_CONSTRUCTOR
for inherited constructor.
2019-10-14 Paolo Carlini <paolo.carlini@oracle.com>
* decl.c (check_tag_decl): Use DECL_SOURCE_LOCATION.
......
......@@ -4613,6 +4613,7 @@ do_class_using_decl (tree scope, tree name)
maybe_warn_cpp0x (CPP0X_INHERITING_CTORS);
name = ctor_identifier;
CLASSTYPE_NON_AGGREGATE (current_class_type) = true;
TYPE_HAS_USER_CONSTRUCTOR (current_class_type) = true;
}
/* Cannot introduce a constructor name. */
......
......@@ -6,13 +6,13 @@ struct B1 {
struct B2 {
B2(double) { }
};
struct D1 : B1 { // { dg-error "no match" }
struct D1 : B1 {
using B1::B1; // implicitly declares D1(int)
int x;
};
void test() {
D1 d(6); // OK: d.x is not initialized
D1 e; // { dg-error "deleted" } D1 has no default constructor
D1 e; // { dg-error "no match" } D1 has no default constructor
}
struct D2 : B2 {
using B2::B2; // { dg-error "B1::B1" }
......
......@@ -12,7 +12,7 @@ struct B2 {
int get();
struct D1 : B1 { // { dg-message "B1::B1" }
struct D1 : B1 {
using B1::B1; // inherits B1(int, ...)
int x;
int y = get();
......@@ -22,7 +22,7 @@ void test() {
D1 d(2, 3, 4); // OK: B1 is initialized by calling B1(2, 3, 4),
// then d.x is default-initialized (no initialization is performed),
// then d.y is initialized by calling get()
D1 e; // { dg-error "" } D1 has a deleted default constructor
D1 e; // { dg-error "" } D1 has no default constructor
}
struct D2 : B2 {
......
// PR c++/91930
// { dg-do compile { target c++2a } }
template <typename T> struct basic_mixin {
basic_mixin() requires true;
};
struct mixin : basic_mixin<int> {
using basic_mixin<int>::basic_mixin;
};
mixin m;
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