re PR c++/24687 (ICE after error)

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
This commit is contained in:
Mark Mitchell 2005-11-15 00:15:09 +00:00 committed by Mark Mitchell
parent 37edf0a6c4
commit 2f1b1731e6
5 changed files with 58 additions and 10 deletions

View 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.

View 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.) */

View 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)
{

View 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.

View File

@ -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" }