re PR c++/56323 ([C++11] cannot compile inherited constructor for typedef'ed base class)
PR c++/56323 * name-lookup.c (do_class_using_decl): Handle typedefs with inheriting constructors. (push_class_level_binding_1): Allow inheriting from template template parameter, too. * pt.c (tsubst_decl) [USING_DECL]: Likewise. From-SVN: r196067
This commit is contained in:
parent
5b858a6cc3
commit
06449b408e
|
@ -1,5 +1,12 @@
|
|||
2013-02-14 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/56323
|
||||
* name-lookup.c (do_class_using_decl): Handle typedefs with
|
||||
inheriting constructors.
|
||||
(push_class_level_binding_1): Allow inheriting from template
|
||||
template parameter, too.
|
||||
* pt.c (tsubst_decl) [USING_DECL]: Likewise.
|
||||
|
||||
PR c++/55223
|
||||
* pt.c (tsubst_copy_and_build) [LAMBDA_EXPR]: Fix handling of
|
||||
default argument scope.
|
||||
|
|
|
@ -3028,11 +3028,10 @@ push_class_level_binding_1 (tree name, tree x)
|
|||
decl = TREE_VALUE (decl);
|
||||
|
||||
if (TREE_CODE (decl) == USING_DECL
|
||||
&& TREE_CODE (USING_DECL_SCOPE (decl)) == TEMPLATE_TYPE_PARM
|
||||
&& TYPE_NAME (USING_DECL_SCOPE (decl))
|
||||
&& DECL_NAME (decl) == TYPE_IDENTIFIER (USING_DECL_SCOPE (decl)))
|
||||
/* This using-declaration declares constructors that inherit from the
|
||||
constructors for the template parameter. It does not redeclare the
|
||||
name of the template parameter. */
|
||||
/* This using-declaration declares inheriting constructors; it does not
|
||||
redeclare the name of a template parameter. */
|
||||
return true;
|
||||
|
||||
if (!check_template_shadow (decl))
|
||||
|
@ -3226,6 +3225,10 @@ 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);
|
||||
if (constructor_name_p (name, current_class_type))
|
||||
|
|
|
@ -10492,7 +10492,8 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
|
|||
tree inst_scope = tsubst_copy (USING_DECL_SCOPE (t), args,
|
||||
complain, in_decl);
|
||||
tree name = tsubst_copy (DECL_NAME (t), args, complain, in_decl);
|
||||
if (TREE_CODE (scope) == TEMPLATE_TYPE_PARM
|
||||
/* 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);
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
// PR c++/56323
|
||||
// { dg-do compile { target c++11 } }
|
||||
|
||||
struct A {
|
||||
A(int i);
|
||||
};
|
||||
|
||||
typedef A B;
|
||||
|
||||
struct C : B {
|
||||
using B::B;
|
||||
};
|
||||
|
||||
struct D : B {
|
||||
using B::A;
|
||||
};
|
||||
|
||||
C c(0);
|
||||
D d(0);
|
||||
|
||||
template <class T>
|
||||
struct E {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct F : E<T>::type {
|
||||
using E<T>::type::type; // error: E<T>::type is a typedef
|
||||
};
|
||||
|
||||
F<A> f(0);
|
||||
|
||||
template <class T>
|
||||
struct AT
|
||||
{
|
||||
AT(T);
|
||||
};
|
||||
|
||||
template <template <class> class T>
|
||||
struct G : T<int>
|
||||
{
|
||||
using T<int>::T;
|
||||
};
|
||||
|
||||
G<AT> g(0);
|
Loading…
Reference in New Issue