diff options
author | Jason Merrill <jason@redhat.com> | 2013-02-27 13:13:24 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2013-02-27 13:13:24 -0500 |
commit | 140bec21b86df21fd9a0105dc5334ac45d172505 (patch) | |
tree | 35dd8290aca2f22ffa98a2e2de1913fb9eb7a5c3 /gcc | |
parent | bbb3a9e27368ae01b96b33becb3cf662c95eba2a (diff) | |
download | gcc-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/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/cp/class.c | 5 | ||||
-rw-r--r-- | gcc/cp/name-lookup.c | 21 | ||||
-rw-r--r-- | gcc/cp/pt.c | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/inh-ctor18.C | 22 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/inherit/using5.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.other/using3.C | 2 |
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 }; |