aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2013-02-14 20:27:03 -0500
committerJason Merrill <jason@gcc.gnu.org>2013-02-14 20:27:03 -0500
commit06449b408eb72fbc8f5b78fea962efd4e72db5e6 (patch)
treead0d25171feaf55e2a861ed9ae317b09f912e845
parent5b858a6cc3584c4dfec7c9ef377f71bccf986e13 (diff)
downloadgcc-06449b408eb72fbc8f5b78fea962efd4e72db5e6.zip
gcc-06449b408eb72fbc8f5b78fea962efd4e72db5e6.tar.gz
gcc-06449b408eb72fbc8f5b78fea962efd4e72db5e6.tar.bz2
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
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/name-lookup.c11
-rw-r--r--gcc/cp/pt.c3
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/inh-ctor17.C45
4 files changed, 61 insertions, 5 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index de03a7a..76cefcf 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 074dcf3..1f3c042 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -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))
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index aa868a4..e88ea85 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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);
diff --git a/gcc/testsuite/g++.dg/cpp0x/inh-ctor17.C b/gcc/testsuite/g++.dg/cpp0x/inh-ctor17.C
new file mode 100644
index 0000000..22eda3a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/inh-ctor17.C
@@ -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);