]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/53549 (g++ and armadillo 3.2.0, operator() is inaccessible)
authorJason Merrill <jason@redhat.com>
Tue, 17 Jul 2012 18:08:59 +0000 (14:08 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 17 Jul 2012 18:08:59 +0000 (14:08 -0400)
PR c++/53549
* parser.c (cp_parser_class_head): Call xref_basetypes here.
(cp_parser_class_specifier_1): Not here.
* pt.c (tsubst_decl) [USING_DECL]: Check uses_template_parms
as well as DECL_DEPENDENT_P.

From-SVN: r189582

gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/parse/crash35.C
gcc/testsuite/g++.dg/template/current-inst1.C [new file with mode: 0644]

index a8b19aec857bc097d35b3c5b0278e3366e234459..142a8667d448e054fdc5d5438b71d0756e258cb1 100644 (file)
@@ -1,3 +1,11 @@
+2012-07-17  Jason Merrill  <jason@redhat.com>
+
+       PR c++/53549
+       * parser.c (cp_parser_class_head): Call xref_basetypes here.
+       (cp_parser_class_specifier_1): Not here.
+       * pt.c (tsubst_decl) [USING_DECL]: Check uses_template_parms
+       as well as DECL_DEPENDENT_P.
+
 2012-07-16  Jason Merrill  <jason@redhat.com>
 
        * cp-tree.h (struct deferred_access_check): Add location.
index 1428a2616bc6ea4b56b619cb6c12d3345899c740..df23299efe2cab715ec687caa957330b3798d3be 100644 (file)
@@ -2008,7 +2008,7 @@ static tree cp_parser_class_name
 static tree cp_parser_class_specifier
   (cp_parser *);
 static tree cp_parser_class_head
-  (cp_parser *, bool *, tree *);
+  (cp_parser *, bool *);
 static enum tag_types cp_parser_class_key
   (cp_parser *);
 static void cp_parser_member_specification_opt
@@ -17961,15 +17961,13 @@ cp_parser_class_specifier_1 (cp_parser* parser)
   bool saved_in_unbraced_linkage_specification_p;
   tree old_scope = NULL_TREE;
   tree scope = NULL_TREE;
-  tree bases;
   cp_token *closing_brace;
 
   push_deferring_access_checks (dk_no_deferred);
 
   /* Parse the class-head.  */
   type = cp_parser_class_head (parser,
-                              &nested_name_specifier_p,
-                              &bases);
+                              &nested_name_specifier_p);
   /* If the class-head was a semantic disaster, skip the entire body
      of the class.  */
   if (!type)
@@ -17986,18 +17984,6 @@ cp_parser_class_specifier_1 (cp_parser* parser)
       return error_mark_node;
     }
 
-  /* Process the base classes. If they're invalid, skip the 
-     entire class body.  */
-  if (!xref_basetypes (type, bases))
-    {
-      /* Consuming the closing brace yields better error messages
-         later on.  */
-      if (cp_parser_skip_to_closing_brace (parser))
-       cp_lexer_consume_token (parser->lexer);
-      pop_deferring_access_checks ();
-      return error_mark_node;
-    }
-
   /* Issue an error message if type-definitions are forbidden here.  */
   cp_parser_check_type_definition (parser);
   /* Remember that we are defining one more class.  */
@@ -18283,14 +18269,14 @@ cp_parser_class_specifier (cp_parser* parser)
 
 static tree
 cp_parser_class_head (cp_parser* parser,
-                     bool* nested_name_specifier_p,
-                     tree *bases)
+                     bool* nested_name_specifier_p)
 {
   tree nested_name_specifier;
   enum tag_types class_key;
   tree id = NULL_TREE;
   tree type = NULL_TREE;
   tree attributes;
+  tree bases;
   cp_virt_specifiers virt_specifiers = VIRT_SPEC_UNSPECIFIED;
   bool template_id_p = false;
   bool qualified_p = false;
@@ -18307,8 +18293,6 @@ cp_parser_class_head (cp_parser* parser,
   num_templates = 0;
   parser->colon_corrects_to_scope_p = false;
 
-  *bases = NULL_TREE;
-
   /* Look for the class-key.  */
   class_key = cp_parser_class_key (parser);
   if (class_key == none_type)
@@ -18671,7 +18655,15 @@ cp_parser_class_head (cp_parser* parser,
 
   /* Get the list of base-classes, if there is one.  */
   if (cp_lexer_next_token_is (parser->lexer, CPP_COLON))
-    *bases = cp_parser_base_clause (parser);
+    bases = cp_parser_base_clause (parser);
+  else
+    bases = NULL_TREE;
+
+  /* If we're really defining a class, process the base classes.
+     If they're invalid, fail.  */
+  if (type && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)
+      && !xref_basetypes (type, bases))
+    type = NULL_TREE;
 
  done:
   /* Leave the scope given by the nested-name-specifier.  We will
index 95c6464e61b43cbdb3e034f7f3ce440b2014898e..542f57a30a0dbae1422ac524dc457c0f37bba9e4 100644 (file)
@@ -10235,8 +10235,12 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
       break;
 
     case USING_DECL:
-      /* We reach here only for member using decls.  */
-      if (DECL_DEPENDENT_P (t))
+      /* We reach here only for member using decls.  We also need to check
+        uses_template_parms because DECL_DEPENDENT_P is not set for a
+        using-declaration that designates a member of the current
+        instantiation (c++/53549).  */
+      if (DECL_DEPENDENT_P (t)
+         || uses_template_parms (USING_DECL_SCOPE (t)))
        {
          r = do_class_using_decl
            (tsubst_copy (USING_DECL_SCOPE (t), args, complain, in_decl),
index 56743bd137b38c9dd118db233e95774ef6875917..f4e7ff58b0d8e904109d349ac019432c58092395 100644 (file)
@@ -1,3 +1,9 @@
+2012-07-17  Jason Merrill  <jason@redhat.com>
+
+       PR c++/53549
+       * g++.dg/template/current-inst1.C: New.
+       * g++.dg/parse/crash35.C: Adjust.
+
 2012-07-17  Tobias Burnus  <burnus@net-b.de>
 
        PR fortran/52101
index 4937cdc66e72e57b573fbc12879124efd23afb8f..161edad32a2a790254ef3028422a57d2e45b1d93 100644 (file)
@@ -3,5 +3,5 @@
 
 struct a {};
 
-class foo : public a, a
-{ /* { dg-error "duplicate base type|at end of input" } */
+class foo : public a, a                // { dg-error "duplicate base" }
+{ /* { dg-error "at end of input" } */
diff --git a/gcc/testsuite/g++.dg/template/current-inst1.C b/gcc/testsuite/g++.dg/template/current-inst1.C
new file mode 100644 (file)
index 0000000..8f42ef8
--- /dev/null
@@ -0,0 +1,19 @@
+// PR c++/53549
+
+template<typename T>
+struct C2
+{
+  int operator()();
+
+  template<int> struct F2;
+};
+
+
+template<typename T>
+template<int I>
+struct C2<T>::F2 : C2<T>
+{
+  using C2<T>::operator();
+};
+
+C2<int>::F2<42> f;