aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2013-02-27 13:13:24 -0500
committerJason Merrill <jason@gcc.gnu.org>2013-02-27 13:13:24 -0500
commit140bec21b86df21fd9a0105dc5334ac45d172505 (patch)
tree35dd8290aca2f22ffa98a2e2de1913fb9eb7a5c3 /gcc
parentbbb3a9e27368ae01b96b33becb3cf662c95eba2a (diff)
downloadgcc-140bec21b86df21fd9a0105dc5334ac45d172505.zip
gcc-140bec21b86df21fd9a0105dc5334ac45d172505.tar.gz
gcc-140bec21b86df21fd9a0105dc5334ac45d172505.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog10
-rw-r--r--gcc/cp/class.c5
-rw-r--r--gcc/cp/name-lookup.c21
-rw-r--r--gcc/cp/pt.c5
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/inh-ctor18.C22
-rw-r--r--gcc/testsuite/g++.dg/inherit/using5.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/using3.C2
7 files changed, 44 insertions, 23 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 9290413..a0e74051 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index eaa109a..2a0351f 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -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)
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 1f3c042..2a47331 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -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",
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 9b7fc3a..eb9fc7f 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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;
diff --git a/gcc/testsuite/g++.dg/cpp0x/inh-ctor18.C b/gcc/testsuite/g++.dg/cpp0x/inh-ctor18.C
new file mode 100644
index 0000000..0573555
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/inh-ctor18.C
@@ -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);
diff --git a/gcc/testsuite/g++.dg/inherit/using5.C b/gcc/testsuite/g++.dg/inherit/using5.C
index 89c7ca0..b8e5107 100644
--- a/gcc/testsuite/g++.dg/inherit/using5.C
+++ b/gcc/testsuite/g++.dg/inherit/using5.C
@@ -6,7 +6,7 @@
template<int> struct A
{
- A::A; // { dg-error "constructor" }
+ A::A; // { dg-error "constructor|not a base" }
};
struct B
diff --git a/gcc/testsuite/g++.old-deja/g++.other/using3.C b/gcc/testsuite/g++.old-deja/g++.other/using3.C
index f30ecbc..3df78f0 100644
--- a/gcc/testsuite/g++.old-deja/g++.other/using3.C
+++ b/gcc/testsuite/g++.old-deja/g++.other/using3.C
@@ -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
};