Commit 140bec21 by Jason Merrill Committed by Jason Merrill

re PR c++/56358 ([C++11] Erroneous interaction of typedef and inherited constructor declarations)

	PR c++/56358
	PR c++/56323
	* name-lookup.c (do_class_using_decl): Use ctor_identifier instead
	of the base name for inheriting ctors.
	(push_class_level_binding_1): Remove inheriting ctor handling.
	* pt.c (tsubst_decl) [USING_DECL]: Likewise.
	* class.c (add_implicitly_declared_members): Adjust.

From-SVN: r196316
parent bbb3a9e2
2013-02-27 Jason Merrill <jason@redhat.com>
PR c++/56358
PR c++/56323
* name-lookup.c (do_class_using_decl): Use ctor_identifier instead
of the base name for inheriting ctors.
(push_class_level_binding_1): Remove inheriting ctor handling.
* pt.c (tsubst_decl) [USING_DECL]: Likewise.
* class.c (add_implicitly_declared_members): Adjust.
2013-02-26 David Binderman <dcb314@hotmail.com> 2013-02-26 David Binderman <dcb314@hotmail.com>
PR c++/55632 PR c++/55632
......
...@@ -3010,11 +3010,10 @@ add_implicitly_declared_members (tree t, tree* access_decls, ...@@ -3010,11 +3010,10 @@ add_implicitly_declared_members (tree t, tree* access_decls,
{ {
tree using_decl = TREE_VALUE (*access_decls); tree using_decl = TREE_VALUE (*access_decls);
tree decl = USING_DECL_DECLS (using_decl); tree decl = USING_DECL_DECLS (using_decl);
if (DECL_SELF_REFERENCE_P (decl)) if (DECL_NAME (using_decl) == ctor_identifier)
{ {
/* declare, then remove the decl */ /* declare, then remove the decl */
tree ctor_list = lookup_fnfields_slot (TREE_TYPE (decl), tree ctor_list = decl;
ctor_identifier);
location_t loc = input_location; location_t loc = input_location;
input_location = DECL_SOURCE_LOCATION (using_decl); input_location = DECL_SOURCE_LOCATION (using_decl);
if (ctor_list) if (ctor_list)
......
...@@ -3027,13 +3027,6 @@ push_class_level_binding_1 (tree name, tree x) ...@@ -3027,13 +3027,6 @@ push_class_level_binding_1 (tree name, tree x)
&& TREE_TYPE (decl) == error_mark_node) && TREE_TYPE (decl) == error_mark_node)
decl = TREE_VALUE (decl); decl = TREE_VALUE (decl);
if (TREE_CODE (decl) == USING_DECL
&& TYPE_NAME (USING_DECL_SCOPE (decl))
&& DECL_NAME (decl) == TYPE_IDENTIFIER (USING_DECL_SCOPE (decl)))
/* This using-declaration declares inheriting constructors; it does not
redeclare the name of a template parameter. */
return true;
if (!check_template_shadow (decl)) if (!check_template_shadow (decl))
return false; return false;
...@@ -3225,12 +3218,14 @@ do_class_using_decl (tree scope, tree name) ...@@ -3225,12 +3218,14 @@ do_class_using_decl (tree scope, tree name)
error ("%<%T::%D%> names destructor", scope, name); error ("%<%T::%D%> names destructor", scope, name);
return NULL_TREE; return NULL_TREE;
} }
if (TYPE_NAME (scope) && name == TYPE_IDENTIFIER (scope)) /* Using T::T declares inheriting ctors, even if T is a typedef. */
/* 3.4.3.1 says that using B::B always names the constructor even if B if (MAYBE_CLASS_TYPE_P (scope)
is a typedef; now replace the second B with the real name. */ && ((TYPE_NAME (scope) && name == TYPE_IDENTIFIER (scope))
name = TYPE_IDENTIFIER (TYPE_MAIN_VARIANT (scope)); || constructor_name_p (name, scope)))
if (MAYBE_CLASS_TYPE_P (scope) && constructor_name_p (name, scope)) {
maybe_warn_cpp0x (CPP0X_INHERITING_CTORS); maybe_warn_cpp0x (CPP0X_INHERITING_CTORS);
name = ctor_identifier;
}
if (constructor_name_p (name, current_class_type)) if (constructor_name_p (name, current_class_type))
{ {
error ("%<%T::%D%> names constructor in %qT", error ("%<%T::%D%> names constructor in %qT",
......
...@@ -10490,14 +10490,9 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) ...@@ -10490,14 +10490,9 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
if (DECL_DEPENDENT_P (t) if (DECL_DEPENDENT_P (t)
|| uses_template_parms (USING_DECL_SCOPE (t))) || uses_template_parms (USING_DECL_SCOPE (t)))
{ {
tree scope = USING_DECL_SCOPE (t);
tree inst_scope = tsubst_copy (USING_DECL_SCOPE (t), args, tree inst_scope = tsubst_copy (USING_DECL_SCOPE (t), args,
complain, in_decl); complain, in_decl);
tree name = tsubst_copy (DECL_NAME (t), args, complain, in_decl); tree name = tsubst_copy (DECL_NAME (t), args, complain, in_decl);
/* Handle 'using T::T'. */
if (TYPE_NAME (scope)
&& name == TYPE_IDENTIFIER (scope))
name = TYPE_IDENTIFIER (inst_scope);
r = do_class_using_decl (inst_scope, name); r = do_class_using_decl (inst_scope, name);
if (!r) if (!r)
r = error_mark_node; r = error_mark_node;
......
// PR c++/56358
// { dg-do compile { target c++11 } }
struct foo {
explicit foo(int) {}
};
template<typename T>
struct bar: T {
using T::T;
// Bad
explicit bar(): T(0) {}
void baz()
{
// Also bad
using qux = T;
}
};
bar<foo> b, b2(42);
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
template<int> struct A template<int> struct A
{ {
A::A; // { dg-error "constructor" } A::A; // { dg-error "constructor|not a base" }
}; };
struct B struct B
......
...@@ -8,5 +8,5 @@ typedef struct { ...@@ -8,5 +8,5 @@ typedef struct {
} S; } S;
struct B: S{ struct B: S{
using S::S; // { dg-error "" } no such field using S::S; // { dg-error "" "" { target c++98 } } no such field
}; };
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