re PR c++/24687 (ICE after error)
authorMark Mitchell <mark@codesourcery.com>
Tue, 15 Nov 2005 00:15:09 +0000 (00:15 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Tue, 15 Nov 2005 00:15:09 +0000 (00:15 +0000)
PR c++/24687
* pt.c (check_explicit_specialization): Don't check for C linkage.
(push_template_decl_real): Likewise.
* parser.c (cp_parser_explicit_specialization): Check here.
(cp_parser_template_declaration_after_export): And here.
PR c++/24687
* g++.dg/template/crash43.C: New test.

From-SVN: r106909

gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/crash43.C [new file with mode: 0644]

index 3a2d6d20d4a7f6ae0f70f49fcb9c5dcf47522e29..60f3166b3cea74d6238615386797de9cf634a839 100644 (file)
@@ -1,5 +1,11 @@
 2005-11-14  Mark Mitchell  <mark@codesourcery.com>
 
+       PR c++/24687
+       * pt.c (check_explicit_specialization): Don't check for C linkage.
+       (push_template_decl_real): Likewise.
+       * parser.c (cp_parser_explicit_specialization): Check here.
+       (cp_parser_template_declaration_after_export): And here.
+
        * parser.c (cp_lexer_get_preprocessor_token): Initialize keyword
        field.
 
index 40a1768e3cadcdd6e0ada8d13c69bac1237bd27f..5827e5ebcdcab61e8ac97e6fb13de3a5b579d825 100644 (file)
@@ -9295,6 +9295,7 @@ cp_parser_explicit_instantiation (cp_parser* parser)
 static void
 cp_parser_explicit_specialization (cp_parser* parser)
 {
+  bool need_lang_pop;
   /* Look for the `template' keyword.  */
   cp_parser_require_keyword (parser, RID_TEMPLATE, "`template'");
   /* Look for the `<'.  */
@@ -9303,9 +9304,22 @@ cp_parser_explicit_specialization (cp_parser* parser)
   cp_parser_require (parser, CPP_GREATER, "`>'");
   /* We have processed another parameter list.  */
   ++parser->num_template_parameter_lists;
+  /* [temp]
+   
+     A template ... explicit specialization ... shall not have C
+     linkage.  */ 
+  if (current_lang_name == lang_name_c)
+    {
+      error ("template specialization with C linkage");
+      /* Give it C++ linkage to avoid confusing other parts of the
+        front end.  */
+      push_lang_context (lang_name_cplusplus);
+      need_lang_pop = true;
+    }
+  else
+    need_lang_pop = false;
   /* Let the front end know that we are beginning a specialization.  */
   begin_specialization ();
-
   /* 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))
@@ -9322,9 +9336,12 @@ cp_parser_explicit_specialization (cp_parser* parser)
     cp_parser_single_declaration (parser,
                                  /*member_p=*/false,
                                  /*friend_p=*/NULL);
-
   /* We're done with the specialization.  */
   end_specialization ();
+  /* For the erroneous case of a template with C linkage, we pushed an
+     implicit C++ linkage scope; exit that scope now.  */
+  if (need_lang_pop)
+    pop_lang_context ();
   /* We're done with this parameter list.  */
   --parser->num_template_parameter_lists;
 }
@@ -15168,6 +15185,7 @@ cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p)
   tree decl = NULL_TREE;
   tree parameter_list;
   bool friend_p = false;
+  bool need_lang_pop;
 
   /* Look for the `template' keyword.  */
   if (!cp_parser_require_keyword (parser, RID_TEMPLATE, "`template'"))
@@ -15176,7 +15194,19 @@ cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p)
   /* And the `<'.  */
   if (!cp_parser_require (parser, CPP_LESS, "`<'"))
     return;
-
+  /* [temp]
+   
+     A template ... shall not have C linkage.  */
+  if (current_lang_name == lang_name_c)
+    {
+      error ("template with C linkage");
+      /* Give it C++ linkage to avoid confusing other parts of the
+        front end.  */
+      push_lang_context (lang_name_cplusplus);
+      need_lang_pop = true;
+    }
+  else
+    need_lang_pop = false;
   /* If the next token is `>', then we have an invalid
      specialization.  Rather than complain about an invalid template
      parameter, issue an error message here.  */
@@ -15237,7 +15267,10 @@ cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p)
   /* Register member declarations.  */
   if (member_p && !friend_p && decl && !DECL_CLASS_TEMPLATE_P (decl))
     finish_member_declaration (decl);
-
+  /* For the erroneous case of a template with C linkage, we pushed an
+     implicit C++ linkage scope; exit that scope now.  */
+  if (need_lang_pop)
+    pop_lang_context ();
   /* If DECL is a function template, we must return to parse it later.
      (Even though there is no definition, there might be default
      arguments that need handling.)  */
index 63123c47f97d688fddb69e7f9b66db608e3e5185..3e495643fd65506392055509c5e992025bf532ac 100644 (file)
@@ -1895,8 +1895,6 @@ check_explicit_specialization (tree declarator,
              ("default argument specified in explicit specialization");
            break;
          }
-      if (current_lang_name == lang_name_c)
-       error ("template specialization with C linkage");
     }
 
   if (specialization || member_specialization || explicit_instantiation)
@@ -2985,10 +2983,8 @@ push_template_decl_real (tree decl, bool is_friend)
     {
       if (DECL_CLASS_SCOPE_P (decl))
        member_template_p = true;
-      if (current_lang_name == lang_name_c)
-       error ("template with C linkage");
-      else if (TREE_CODE (decl) == TYPE_DECL
-              && ANON_AGGRNAME_P (DECL_NAME (decl)))
+      if (TREE_CODE (decl) == TYPE_DECL
+         && ANON_AGGRNAME_P (DECL_NAME (decl)))
        error ("template class without a name");
       else if (TREE_CODE (decl) == FUNCTION_DECL)
        {
index 2a864b0558bbb405c097557e379d98b8241e35c7..d87105b3fe82d40b34f67d27f475c15ca967b559 100644 (file)
@@ -1,3 +1,8 @@
+2005-11-14  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/24687
+       * g++.dg/template/crash43.C: New test. 
+
 2005-11-14  Daniel Jacobowitz  <dan@codesourcery.com>
 
        * gcc.c-torture/unsorted/unsorted.exp: Sort tests before running them.
diff --git a/gcc/testsuite/g++.dg/template/crash43.C b/gcc/testsuite/g++.dg/template/crash43.C
new file mode 100644 (file)
index 0000000..1261c36
--- /dev/null
@@ -0,0 +1,8 @@
+// PR c++/24687
+
+extern "C" {
+  template<typename _Tp>  // { dg-error "C" }   
+  struct __is_pod {
+    enum {
+      __value = (sizeof(__gnu_internal::__test_type<_Tp>(0)))}; // { dg-error "declared|expected" }
+