re PR c++/27667 (ICE with in-class specialization)
authorLee Millward <lee.millward@codesourcery.com>
Mon, 25 Sep 2006 19:58:10 +0000 (19:58 +0000)
committerLee Millward <lmillward@gcc.gnu.org>
Mon, 25 Sep 2006 19:58:10 +0000 (19:58 +0000)
        PR c++/27667
        * cp-tree.h (begin_specialization): Return bool instead of void.
        * pt.c (check_specialization_scope): Likwise. Adjust comment.
        Return false if a specialization isn't permitted in the current scope,.
        (begin_specialization): Use the return value of
        check_specialization_scope.
        * parser.c (cp_parser_explicit_specialization): If
        begin_specialization returned false, skip the rest of the
        specialization.

        * g++.dg/template/spec33.C: New test.
        * g++.old-deja/g++.pt/spec20.C: Adjust error markers.

From-SVN: r117206

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/parser.c
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/spec33.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.pt/spec20.C

index a41714cdcd1a860570e02193f6244233664dd701..46bfeb876d37666ce64e3559484dfcb3874ed43e 100644 (file)
@@ -8,6 +8,18 @@
        Return false on error.
         * decl.c (xref_tag): Return error_mark_node if
        redeclare_class_template returned false.
+
+       PR c++/27667
+        * cp-tree.h (begin_specialization): Return bool 
+       instead of void.
+        * pt.c (check_specialization_scope): Likwise. 
+       Adjust comment. Return false if a specialization 
+       isn't permitted in the current scope.
+        (begin_specialization): Use the return value of  
+        check_specialization_scope.
+        * parser.c (cp_parser_explicit_specialization): If
+        begin_specialization returned false, skip the rest 
+       of the specialization.
        
 2006-09-21  Mark Mitchell  <mark@codesourcery.com>
 
index 227fc9dfdec0f1cb8e045b415c22e94bd3a60f5e..93c4053ccd6e9cc2da7e6996234c2daf02fd2277 100644 (file)
@@ -4086,7 +4086,7 @@ extern void maybe_begin_member_template_processing (tree);
 extern void maybe_end_member_template_processing (void);
 extern tree finish_member_template_decl                (tree);
 extern void begin_template_parm_list           (void);
-extern void begin_specialization               (void);
+extern bool begin_specialization               (void);
 extern void reset_specialization               (void);
 extern void end_specialization                 (void);
 extern void begin_explicit_instantiation       (void);
index d0205208eb33b54408abc8c870887b004971b72d..0b7dd3cde476fdc58794003a1ea503ec37790401 100644 (file)
@@ -9455,7 +9455,13 @@ cp_parser_explicit_specialization (cp_parser* parser)
   else
     need_lang_pop = false;
   /* Let the front end know that we are beginning a specialization.  */
-  begin_specialization ();
+  if (!begin_specialization ())
+    {
+      end_specialization ();
+      cp_parser_skip_to_end_of_block_or_statement (parser);
+      return;
+    }
+
   /* If the next keyword is `template', we need to figure out whether
      or not we're looking a template-declaration.  */
   if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TEMPLATE))
index daee2522047c313742062b80d09ce2c154ec0364..4e8fad66e5c352090cca48bd513daccd2df719e1 100644 (file)
@@ -142,7 +142,7 @@ static tree most_specialized_class (tree, tree);
 static tree tsubst_aggr_type (tree, tree, tsubst_flags_t, tree, int);
 static tree tsubst_arg_types (tree, tree, tsubst_flags_t, tree);
 static tree tsubst_function_type (tree, tree, tsubst_flags_t, tree);
-static void check_specialization_scope (void);
+static bool check_specialization_scope (void);
 static tree process_partial_specialization (tree);
 static void set_current_access_from_decl (tree);
 static void check_default_tmpl_args (tree, tree, int, int);
@@ -535,9 +535,10 @@ begin_template_parm_list (void)
 }
 
 /* This routine is called when a specialization is declared.  If it is
-   invalid to declare a specialization here, an error is reported.  */
+   invalid to declare a specialization here, an error is reported and
+   false is returned, otherwise this routine will return true.  */
 
-static void
+static bool
 check_specialization_scope (void)
 {
   tree scope = current_scope ();
@@ -552,7 +553,10 @@ check_specialization_scope (void)
      shall be declared in the namespace of which the class template
      is a member.  */
   if (scope && TREE_CODE (scope) != NAMESPACE_DECL)
-    error ("explicit specialization in non-namespace scope %qD", scope);
+    {
+      error ("explicit specialization in non-namespace scope %qD", scope);
+      return false;
+    }
 
   /* [temp.expl.spec]
 
@@ -563,17 +567,22 @@ check_specialization_scope (void)
      explicitly specialize a class member template if its enclosing
      class templates are not explicitly specialized as well.  */
   if (current_template_parms)
-    error ("enclosing class templates are not explicitly specialized");
+    {
+      error ("enclosing class templates are not explicitly specialized");
+      return false;
+    }
+
+  return true;
 }
 
 /* We've just seen template <>.  */
 
-void
+bool
 begin_specialization (void)
 {
   begin_scope (sk_template_spec, NULL);
   note_template_header (1);
-  check_specialization_scope ();
+  return check_specialization_scope ();
 }
 
 /* Called at then end of processing a declaration preceded by
index a511e56253652a719f3638a443c88ec00fba719a..4fc16e5f23df88c611d8111c16cb026af8aba6ab 100644 (file)
@@ -9,6 +9,10 @@
 
         PR c++/27329
         * g++.dg/template/crash59.C: New test.
+
+       PR c++/27667
+        * g++.dg/template/spec33.C: New test.
+        * g++.old-deja/g++.pt/spec20.C: Adjust error markers.
        
 2006-09-24  Zdenek Dvorak <dvorakz@suse.cz>
            Adam Nemet  <anemet@caviumnetworks.com>
diff --git a/gcc/testsuite/g++.dg/template/spec33.C b/gcc/testsuite/g++.dg/template/spec33.C
new file mode 100644 (file)
index 0000000..809d4f0
--- /dev/null
@@ -0,0 +1,7 @@
+//PR c++/27667
+
+struct A
+{
+    template<int> static void foo   () {}
+    template<>    static void foo<0>() {}  // { dg-error "explicit" }
+}; 
index 064ce1423a7979c12c2b832a1af3cf3f335444a8..b6148e5ded99fba0fde5a91ef360aabc24da9cd3 100644 (file)
@@ -10,7 +10,7 @@ struct S {
   template <class U> void f(U);
   template <> void f<int>(int); // { dg-error "" } invalid specialization
 
-  template <class V> struct I {};
-  template <class V> struct I<V*> {};
+  template <class V> struct I {};      // { dg-error "template" }
+  template <class V> struct I<V*> {};  // { dg-error "template" }
   template <> struct I<int>; // { dg-error "" } invalid specialization
 };