]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/37140 (type inherited from base class not recognized)
authorFabien Chêne <fabien@gcc.gnu.org>
Mon, 24 Feb 2014 20:27:34 +0000 (21:27 +0100)
committerFabien Chêne <fabien@gcc.gnu.org>
Mon, 24 Feb 2014 20:27:34 +0000 (21:27 +0100)
2014-02-24  Fabien Chene  <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-24  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.

From-SVN: r208093

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 4b0b8e24ed502c7be1c04d5254e5d1a116e3185d..1f45ee80c2bd9b181c560f5722666b9e40b0210c 100644 (file)
@@ -1,3 +1,9 @@
+2014-02-24  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++/60108
index 5763b9b4257b86c161eb37dc55eae7a52abaf217..da167ec415870dba13d377d6a424f6c06166a262 100644 (file)
@@ -394,7 +394,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)
@@ -404,6 +405,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 de30f7325b7128fdeb9767ef1918f72f2ac3e77a..c512d69c6a68da07d3ec02c5342a0194cfff383d 100644 (file)
@@ -14164,25 +14164,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 668421d89f6ad24a2d8c5b9b7b34d8b861db113c..87c93a2b5b7765b8a440db034089b561e09e6e9c 100644 (file)
@@ -1,3 +1,10 @@
+2014-02-24  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-23  David Holsgrove <david.holsgrove@xilinx.com>
 
        * gcc/testsuite/gcc.target/microblaze/others/mem_reload.c: New test.
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>;