OSDN Git Service

2014-02-26 Fabien Chene <fabien@gcc.gnu.org>
authorfabien <fabien@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 26 Feb 2014 21:16:15 +0000 (21:16 +0000)
committerfabien <fabien@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 26 Feb 2014 21:16:15 +0000 (21:16 +0000)
        PR c++/37140
        * parser.c (cp_parser_nonclass_name): Call strip_using_decl and
    move the code handling dependent USING_DECLs...
        * name-lookup.c (strip_using_decl): ...Here.

2014-02-26  Fabien Chene  <fabien@gcc.gnu.org>

        PR c++/37140
        * g++.dg/template/using27.C: New.
        * g++.dg/template/using28.C: New.
        * g++.dg/template/using29.C: New.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_7-branch@208182 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/name-lookup.c
gcc/cp/parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/using27.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/using28.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/using29.C [new file with mode: 0644]

index a27488a..d22e153 100644 (file)
@@ -1,3 +1,9 @@
+2014-02-26  Fabien ChĂȘne  <fabien@gcc.gnu.org>
+        PR c++/37140
+        * parser.c (cp_parser_nonclass_name): Call strip_using_decl and
+       move the code handling dependent USING_DECLs...
+        * name-lookup.c (strip_using_decl): ...Here.
+
 2014-02-21  Jason Merrill  <jason@redhat.com>
 
        PR c++/60248
index 565d396..952903a 100644 (file)
@@ -399,7 +399,8 @@ pop_binding (tree id, tree decl)
     }
 }
 
-/* Strip non dependent using declarations.  */
+/* Strip non dependent using declarations. If DECL is dependent,
+   surreptitiously create a typename_type and return it.  */
 
 tree
 strip_using_decl (tree decl)
@@ -409,6 +410,23 @@ strip_using_decl (tree decl)
 
   while (TREE_CODE (decl) == USING_DECL && !DECL_DEPENDENT_P (decl))
     decl = USING_DECL_DECLS (decl);
+
+  if (TREE_CODE (decl) == USING_DECL && DECL_DEPENDENT_P (decl)
+      && USING_DECL_TYPENAME_P (decl))
+    {
+      /* We have found a type introduced by a using
+        declaration at class scope that refers to a dependent
+        type.
+            
+        using typename :: [opt] nested-name-specifier unqualified-id ;
+      */
+      decl = make_typename_type (TREE_TYPE (decl),
+                                DECL_NAME (decl),
+                                typename_type, tf_error);
+      if (decl != error_mark_node)
+       decl = TYPE_NAME (decl);
+    }
+
   return decl;
 }
 
index fe8c84d..120360a 100644 (file)
@@ -13846,25 +13846,7 @@ cp_parser_nonclass_name (cp_parser* parser)
   /* Look up the type-name.  */
   type_decl = cp_parser_lookup_name_simple (parser, identifier, token->location);
 
-  if (TREE_CODE (type_decl) == USING_DECL)
-    {
-      if (!DECL_DEPENDENT_P (type_decl))
-       type_decl = strip_using_decl (type_decl);
-      else if (USING_DECL_TYPENAME_P (type_decl))
-       {
-         /* We have found a type introduced by a using
-            declaration at class scope that refers to a dependent
-            type.
-            
-            using typename :: [opt] nested-name-specifier unqualified-id ;
-         */
-         type_decl = make_typename_type (TREE_TYPE (type_decl),
-                                         DECL_NAME (type_decl),
-                                         typename_type, tf_error);
-         if (type_decl != error_mark_node)
-           type_decl = TYPE_NAME (type_decl);
-       }
-    }
+  type_decl = strip_using_decl (type_decl);
   
   if (TREE_CODE (type_decl) != TYPE_DECL
       && (objc_is_id (identifier) || objc_is_class_name (identifier)))
index fc5526c..4475c32 100644 (file)
@@ -1,3 +1,10 @@
+2014-02-26  Fabien ChĂȘne  <fabien@gcc.gnu.org>
+
+        PR c++/37140
+        * g++.dg/template/using27.C: New.
+        * g++.dg/template/using28.C: New.
+        * g++.dg/template/using29.C: New.
+
 2014-02-22  Mikael Morin  <mikael@gcc.gnu.org>
 
        PR fortran/59599
diff --git a/gcc/testsuite/g++.dg/template/using27.C b/gcc/testsuite/g++.dg/template/using27.C
new file mode 100644 (file)
index 0000000..f1835e1
--- /dev/null
@@ -0,0 +1,33 @@
+// PR c++/37140
+
+struct X
+{
+  typedef int nested_type;
+};
+
+template <class T>
+struct A
+{
+  typedef X type;
+};
+
+template <class T>
+struct B : A<T>
+{
+  using typename A<T>::type;
+  typename type::nested_type x;
+};
+
+template <class T> 
+struct C : B<T>
+{
+  using typename B<T>::type;
+  typename type::nested_type y;
+};
+
+struct D : C<int>
+{
+  using C<int>::type;
+  type::nested_type z;
+};
+
diff --git a/gcc/testsuite/g++.dg/template/using28.C b/gcc/testsuite/g++.dg/template/using28.C
new file mode 100644 (file)
index 0000000..52f68cf
--- /dev/null
@@ -0,0 +1,17 @@
+// PR c++/37140
+
+struct C
+{
+  static const int block_size = 1;
+};
+
+template <typename T> struct A {
+  typedef C type;
+};
+
+template <typename T> struct B : public A<T> {
+  using typename A<T>::type;
+  static const int block_size = type::block_size;
+};
+
+template class B<int>;
diff --git a/gcc/testsuite/g++.dg/template/using29.C b/gcc/testsuite/g++.dg/template/using29.C
new file mode 100644 (file)
index 0000000..8726547
--- /dev/null
@@ -0,0 +1,21 @@
+// PR c++/58047
+
+template <int N>
+struct print_arg { };
+
+struct const_holder {
+  static const int CONSTANT = 42;
+};
+
+template <typename T>
+struct identity {
+  typedef T type;
+};
+
+template <class T>
+struct test_case : public identity<T> {
+  using typename identity<T>::type;
+  print_arg<type::CONSTANT> printer;
+};
+
+template struct test_case<const_holder>;