re PR c++/56358 ([C++11] Erroneous interaction of typedef and inherited constructor...
authorJason Merrill <jason@redhat.com>
Wed, 27 Feb 2013 18:13:24 +0000 (13:13 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 27 Feb 2013 18:13:24 +0000 (13:13 -0500)
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

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/name-lookup.c
gcc/cp/pt.c
gcc/testsuite/g++.dg/cpp0x/inh-ctor18.C [new file with mode: 0644]
gcc/testsuite/g++.dg/inherit/using5.C
gcc/testsuite/g++.old-deja/g++.other/using3.C

index 9290413c283fa0e85b17e6be341bf5556ea37175..a0e7405104074a91f28a603e5cea6911c6dda9b5 100644 (file)
@@ -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
index eaa109acce374f49b101ee397af63dfbc56610cc..2a0351f7c83262f5d9f87d5ab7717fa39440fa22 100644 (file)
@@ -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)
index 1f3c042041ecae92774f3b874d29fee4a0ca573b..2a47331ea737951375db3db16c5896afa67d2dd0 100644 (file)
@@ -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",
index 9b7fc3a5a4f075f8a3dd34008f9881feb88481d5..eb9fc7f94c7cdf5b687b63d8e6841cdb4bdeffc2 100644 (file)
@@ -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 (file)
index 0000000..0573555
--- /dev/null
@@ -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);
index 89c7ca03ba69a8e7953642793b7d440d5a41f812..b8e51078ff932f04071939751d47c0bf640ed744 100644 (file)
@@ -6,7 +6,7 @@
 
 template<int> struct A
 {
-  A::A; // { dg-error "constructor" }
+  A::A; // { dg-error "constructor|not a base" }
 };
 
 struct B
index f30ecbc3d0f71589f0742b1a4c76c687aa493dc4..3df78f0969198e68cff628191d7912119175afd2 100644 (file)
@@ -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
 };