diff options
author | mmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-11-15 00:15:09 +0000 |
---|---|---|
committer | mmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-11-15 00:15:09 +0000 |
commit | 9f25cdd89d8d7b972ccf139bda43c382b79bdc33 (patch) | |
tree | da378b2769e30d45fdc1f0df7d28f03de6254e43 | |
parent | c47b82579d5ce057778c9e8d5bce29aa61147822 (diff) | |
download | gcc-9f25cdd89d8d7b972ccf139bda43c382b79bdc33.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@106909 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/parser.c | 41 | ||||
-rw-r--r-- | gcc/cp/pt.c | 8 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/crash43.C | 8 |
5 files changed, 58 insertions, 10 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 3a2d6d20d4a..60f3166b3ce 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 40a1768e3ca..5827e5ebcdc 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -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.) */ diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 63123c47f97..3e495643fd6 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -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) { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2a864b0558b..d87105b3fe8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 index 00000000000..1261c365058 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash43.C @@ -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" } + |