OSDN Git Service

gcc/testsuite/ChangeLog
authorfabien <fabien@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 13 Dec 2011 18:46:58 +0000 (18:46 +0000)
committerfabien <fabien@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 13 Dec 2011 18:46:58 +0000 (18:46 +0000)
2011-12-11  Fabien Chene  <fabien@gcc.gnu.org>

PR c++/14258
* g++.dg/template/using16.C: New.
* g++.dg/template/using17.C: New.

gcc/cp/ChangeLog

2011-12-11  Fabien Chene  <fabien@gcc.gnu.org>

PR c++/14258
* cp-tree.h (USING_DECL_TYPENAME_P): New macro.
* parser.c (cp_parser_nonclass_name): Handle using declarations
that refer to a dependent type.
(cp_parser_using_declaration): Set USING_DECL_TYPENAME_P to 1 if
the using declaration refers to a dependent type.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@182292 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/using16.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/using17.C [new file with mode: 0644]

index 3f04054..3e7abcc 100644 (file)
@@ -1,3 +1,12 @@
+2011-12-13  Fabien ChĂȘne  <fabien@gcc.gnu.org>
+
+       PR c++/14258
+       * cp-tree.h (USING_DECL_TYPENAME_P): New macro.
+       * parser.c (cp_parser_nonclass_name): Handle using declarations
+       that refer to a dependent type.
+       (cp_parser_using_declaration): Set USING_DECL_TYPENAME_P to 1 if
+       the using declaration refers to a dependent type.
+
 2011-12-12  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/51496
 2011-12-12  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/51496
index f443816..a96adbb 100644 (file)
@@ -130,6 +130,7 @@ c-common.h, not after.
       DECL_TEMPLATE_INSTANTIATED (in a VAR_DECL or a FUNCTION_DECL)
       DECL_MEMBER_TEMPLATE_P (in TEMPLATE_DECL)
       FUNCTION_PARAMETER_PACK_P (in PARM_DECL)
       DECL_TEMPLATE_INSTANTIATED (in a VAR_DECL or a FUNCTION_DECL)
       DECL_MEMBER_TEMPLATE_P (in TEMPLATE_DECL)
       FUNCTION_PARAMETER_PACK_P (in PARM_DECL)
+      USING_DECL_TYPENAME_P (in USING_DECL)
    2: DECL_THIS_EXTERN (in VAR_DECL or FUNCTION_DECL).
       DECL_IMPLICIT_TYPEDEF_P (in a TYPE_DECL)
    3: DECL_IN_AGGR_P.
    2: DECL_THIS_EXTERN (in VAR_DECL or FUNCTION_DECL).
       DECL_IMPLICIT_TYPEDEF_P (in a TYPE_DECL)
    3: DECL_IN_AGGR_P.
@@ -2521,6 +2522,9 @@ extern void decl_shadowed_for_var_insert (tree, tree);
 /* The decls named by a using decl.  */
 #define USING_DECL_DECLS(NODE) DECL_INITIAL (USING_DECL_CHECK (NODE))
 
 /* The decls named by a using decl.  */
 #define USING_DECL_DECLS(NODE) DECL_INITIAL (USING_DECL_CHECK (NODE))
 
+/* Non zero if the using decl refers to a dependent type.  */
+#define USING_DECL_TYPENAME_P(NODE) DECL_LANG_FLAG_1 (USING_DECL_CHECK (NODE))
+
 /* In a VAR_DECL, true if we have a shadowed local variable
    in the shadowed var table for this VAR_DECL.  */
 #define DECL_HAS_SHADOWED_FOR_VAR_P(NODE) \
 /* In a VAR_DECL, true if we have a shadowed local variable
    in the shadowed var table for this VAR_DECL.  */
 #define DECL_HAS_SHADOWED_FOR_VAR_P(NODE) \
index 2bd91ec..91280b7 100644 (file)
@@ -13807,9 +13807,26 @@ cp_parser_nonclass_name (cp_parser* parser)
   /* Look up the type-name.  */
   type_decl = cp_parser_lookup_name_simple (parser, identifier, token->location);
 
   /* Look up the type-name.  */
   type_decl = cp_parser_lookup_name_simple (parser, identifier, token->location);
 
-  /* If it is a using decl, use its underlying decl.  */
-  type_decl = strip_using_decl (type_decl);
-
+  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);
+       }
+    }
+  
   if (TREE_CODE (type_decl) != TYPE_DECL
       && (objc_is_id (identifier) || objc_is_class_name (identifier)))
     {
   if (TREE_CODE (type_decl) != TYPE_DECL
       && (objc_is_id (identifier) || objc_is_class_name (identifier)))
     {
@@ -14947,6 +14964,9 @@ cp_parser_using_declaration (cp_parser* parser,
          /* Create the USING_DECL.  */
          decl = do_class_using_decl (parser->scope, identifier);
 
          /* Create the USING_DECL.  */
          decl = do_class_using_decl (parser->scope, identifier);
 
+         if (typename_p)
+           USING_DECL_TYPENAME_P (decl) = 1;
+
          if (check_for_bare_parameter_packs (decl))
             return false;
           else
          if (check_for_bare_parameter_packs (decl))
             return false;
           else
@@ -18900,7 +18920,11 @@ cp_parser_member_declaration (cp_parser* parser)
   parser->colon_corrects_to_scope_p = false;
 
   if (cp_parser_using_declaration (parser, /*access_declaration=*/true))
   parser->colon_corrects_to_scope_p = false;
 
   if (cp_parser_using_declaration (parser, /*access_declaration=*/true))
-    goto out;
+    {
+      warning (OPT_Wdeprecated, "access declarations are deprecated; "
+              "employ using declarations instead");
+      goto out;
+    }
 
   /* Parse the decl-specifier-seq.  */
   decl_spec_token_start = cp_lexer_peek_token (parser->lexer);
 
   /* Parse the decl-specifier-seq.  */
   decl_spec_token_start = cp_lexer_peek_token (parser->lexer);
index e5fa8ba..50595b2 100644 (file)
@@ -1,3 +1,9 @@
+2011-12-11  Fabien ChĂȘne  <fabien@gcc.gnu.org>
+
+       PR c++/14258
+       * g++.dg/template/using16.C: New.
+       * g++.dg/template/using17.C: New.
+
 2011-12-13  Martin Jambor  <mjambor@suse.cz>
 
        PR tree-optimization/51362
 2011-12-13  Martin Jambor  <mjambor@suse.cz>
 
        PR tree-optimization/51362
diff --git a/gcc/testsuite/g++.dg/template/using16.C b/gcc/testsuite/g++.dg/template/using16.C
new file mode 100644 (file)
index 0000000..589f7f1
--- /dev/null
@@ -0,0 +1,42 @@
+// { dg-do compile }
+
+template <class T>
+struct A
+{
+    typedef T type;
+};
+
+template <class T>
+struct B
+{
+    class type
+    {
+       type(); // { dg-error "private" }
+    };
+};
+
+template <class T>
+struct C : A<T>, B<T>
+{
+    using typename B<T>::type;
+
+    void f()
+    {
+       type j; // { dg-error "context" }
+    }
+};
+
+template class C<int>; // { dg-message "required" }
+
+template <class T>
+struct D
+{
+    typedef T type;
+};
+
+template <class T>
+class E : D<T>
+{
+    using typename D<T>::type; // { dg-message "previous" }
+    using typename D<T>::type; // { dg-error "redeclaration" }
+};
diff --git a/gcc/testsuite/g++.dg/template/using17.C b/gcc/testsuite/g++.dg/template/using17.C
new file mode 100644 (file)
index 0000000..1af1dc7
--- /dev/null
@@ -0,0 +1,44 @@
+// PR c++/14258
+// { dg-do run }
+
+template<typename T>
+struct A 
+{
+  typedef T type;
+  typedef A type2;
+};
+                                                                               
+template<typename T>
+struct B : A<T> 
+{
+  using typename A<T>::type;
+  type t;
+
+  using typename A<T>::type2;
+
+  type f()
+  {
+    type i = 1;
+    return i;
+  }
+};
+
+int main()
+{
+  B<int>::type t = 4;
+  if (t != 4)
+    __builtin_abort();
+
+  B<double> b;
+  b.t = 3;
+  if (b.t != 3)
+    __builtin_abort();
+
+  B<long> b2;
+  if (b2.f() != 1)
+    __builtin_abort();
+
+  B<double>::type2::type tt = 12;
+  if (tt != 12)
+    __builtin_abort();
+}