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
This commit is contained in:
parent
bbb3a9e273
commit
140bec21b8
7 changed files with 44 additions and 23 deletions
|
@ -1,3 +1,13 @@
|
|||
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>
|
||||
|
||||
PR c++/55632
|
||||
|
|
|
@ -3010,11 +3010,10 @@ add_implicitly_declared_members (tree t, tree* access_decls,
|
|||
{
|
||||
tree using_decl = TREE_VALUE (*access_decls);
|
||||
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 */
|
||||
tree ctor_list = lookup_fnfields_slot (TREE_TYPE (decl),
|
||||
ctor_identifier);
|
||||
tree ctor_list = decl;
|
||||
location_t loc = input_location;
|
||||
input_location = DECL_SOURCE_LOCATION (using_decl);
|
||||
if (ctor_list)
|
||||
|
|
|
@ -3027,13 +3027,6 @@ push_class_level_binding_1 (tree name, tree x)
|
|||
&& TREE_TYPE (decl) == error_mark_node)
|
||||
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))
|
||||
return false;
|
||||
|
||||
|
@ -3225,12 +3218,14 @@ do_class_using_decl (tree scope, tree name)
|
|||
error ("%<%T::%D%> names destructor", scope, name);
|
||||
return NULL_TREE;
|
||||
}
|
||||
if (TYPE_NAME (scope) && name == TYPE_IDENTIFIER (scope))
|
||||
/* 3.4.3.1 says that using B::B always names the constructor even if B
|
||||
is a typedef; now replace the second B with the real name. */
|
||||
name = TYPE_IDENTIFIER (TYPE_MAIN_VARIANT (scope));
|
||||
if (MAYBE_CLASS_TYPE_P (scope) && constructor_name_p (name, scope))
|
||||
maybe_warn_cpp0x (CPP0X_INHERITING_CTORS);
|
||||
/* Using T::T declares inheriting ctors, even if T is a typedef. */
|
||||
if (MAYBE_CLASS_TYPE_P (scope)
|
||||
&& ((TYPE_NAME (scope) && name == TYPE_IDENTIFIER (scope))
|
||||
|| constructor_name_p (name, scope)))
|
||||
{
|
||||
maybe_warn_cpp0x (CPP0X_INHERITING_CTORS);
|
||||
name = ctor_identifier;
|
||||
}
|
||||
if (constructor_name_p (name, current_class_type))
|
||||
{
|
||||
error ("%<%T::%D%> names constructor in %qT",
|
||||
|
|
|
@ -10490,14 +10490,9 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
|
|||
if (DECL_DEPENDENT_P (t)
|
||||
|| uses_template_parms (USING_DECL_SCOPE (t)))
|
||||
{
|
||||
tree scope = USING_DECL_SCOPE (t);
|
||||
tree inst_scope = tsubst_copy (USING_DECL_SCOPE (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);
|
||||
if (!r)
|
||||
r = error_mark_node;
|
||||
|
|
22
gcc/testsuite/g++.dg/cpp0x/inh-ctor18.C
Normal file
22
gcc/testsuite/g++.dg/cpp0x/inh-ctor18.C
Normal file
|
@ -0,0 +1,22 @@
|
|||
// 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 @@
|
|||
|
||||
template<int> struct A
|
||||
{
|
||||
A::A; // { dg-error "constructor" }
|
||||
A::A; // { dg-error "constructor|not a base" }
|
||||
};
|
||||
|
||||
struct B
|
||||
|
|
|
@ -8,5 +8,5 @@ typedef struct {
|
|||
} S;
|
||||
|
||||
struct B: S{
|
||||
using S::S; // { dg-error "" } no such field
|
||||
using S::S; // { dg-error "" "" { target c++98 } } no such field
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue