diff options
author | Paolo Carlini <paolo.carlini@oracle.com> | 2013-07-04 21:58:35 +0000 |
---|---|---|
committer | Paolo Carlini <paolo@gcc.gnu.org> | 2013-07-04 21:58:35 +0000 |
commit | 5fde62e29930ccf09c647c47db77894ff046b0ac (patch) | |
tree | c58498a40d74bafba92fba29b471baa953295b4b /gcc/cp | |
parent | 1d77bc548ad22e5a82ab8f885ea045f3fdfabd24 (diff) | |
download | gcc-5fde62e29930ccf09c647c47db77894ff046b0ac.zip gcc-5fde62e29930ccf09c647c47db77894ff046b0ac.tar.gz gcc-5fde62e29930ccf09c647c47db77894ff046b0ac.tar.bz2 |
re PR c++/38634 (ICE with wrong number of template parameters)
/cp
2013-07-04 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/38634
* decl.c (start_preparsed_function): Return a bool, false if
push_template_decl fails.
(start_function): Adjust.
* cp-tree.h: Update.
/testsuite
2013-07-04 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/38634
* g++.dg/template/crash116.C: New.
From-SVN: r200682
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 5 | ||||
-rw-r--r-- | gcc/cp/decl.c | 32 |
3 files changed, 29 insertions, 16 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 92fefea..3a0ba58 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2013-07-04 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/38634 + * decl.c (start_preparsed_function): Return a bool, false if + push_template_decl fails. + (start_function): Adjust. + * cp-tree.h: Update. + 2013-07-03 Jakub Jelinek <jakub@redhat.com> PR c++/57771 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 3e8043a..1b0b243 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5206,8 +5206,9 @@ extern void finish_enum_value_list (tree); extern void finish_enum (tree); extern void build_enumerator (tree, tree, tree, location_t); extern tree lookup_enumerator (tree, tree); -extern void start_preparsed_function (tree, tree, int); -extern int start_function (cp_decl_specifier_seq *, const cp_declarator *, tree); +extern bool start_preparsed_function (tree, tree, int); +extern bool start_function (cp_decl_specifier_seq *, + const cp_declarator *, tree); extern tree begin_function_body (void); extern void finish_function_body (tree); extern tree outer_curly_brace_block (tree); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 047fd77..54bede0 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -12993,7 +12993,7 @@ check_function_type (tree decl, tree current_function_parms) error_mark_node if the function has never been defined, or a BLOCK if the function has been defined somewhere. */ -void +bool start_preparsed_function (tree decl1, tree attrs, int flags) { tree ctype = NULL_TREE; @@ -13090,10 +13090,14 @@ start_preparsed_function (tree decl1, tree attrs, int flags) by push_nested_class.) */ if (processing_template_decl) { - /* FIXME: Handle error_mark_node more gracefully. */ tree newdecl1 = push_template_decl (decl1); - if (newdecl1 != error_mark_node) - decl1 = newdecl1; + if (newdecl1 == error_mark_node) + { + if (ctype || DECL_STATIC_FUNCTION_P (decl1)) + pop_nested_class (); + return false; + } + decl1 = newdecl1; } /* We are now in the scope of the function being defined. */ @@ -13204,7 +13208,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags) /* This function may already have been parsed, in which case just return; our caller will skip over the body without parsing. */ if (DECL_INITIAL (decl1) != error_mark_node) - return; + return true; /* Initialize RTL machinery. We cannot do this until CURRENT_FUNCTION_DECL and DECL_RESULT are set up. We do this @@ -13366,17 +13370,19 @@ start_preparsed_function (tree decl1, tree attrs, int flags) start_fname_decls (); store_parm_decls (current_function_parms); + + return true; } /* Like start_preparsed_function, except that instead of a FUNCTION_DECL, this function takes DECLSPECS and DECLARATOR. - Returns 1 on success. If the DECLARATOR is not suitable for a function - (it defines a datum instead), we return 0, which tells - yyparse to report a parse error. */ + Returns true on success. If the DECLARATOR is not suitable + for a function, we return false, which tells the parser to + skip the entire function. */ -int +bool start_function (cp_decl_specifier_seq *declspecs, const cp_declarator *declarator, tree attrs) @@ -13385,13 +13391,13 @@ start_function (cp_decl_specifier_seq *declspecs, decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1, &attrs); if (decl1 == error_mark_node) - return 0; + return false; /* If the declarator is not suitable for a function definition, cause a syntax error. */ if (decl1 == NULL_TREE || TREE_CODE (decl1) != FUNCTION_DECL) { error ("invalid function declaration"); - return 0; + return false; } if (DECL_MAIN_P (decl1)) @@ -13400,9 +13406,7 @@ start_function (cp_decl_specifier_seq *declspecs, gcc_assert (same_type_p (TREE_TYPE (TREE_TYPE (decl1)), integer_type_node)); - start_preparsed_function (decl1, attrs, /*flags=*/SF_DEFAULT); - - return 1; + return start_preparsed_function (decl1, attrs, /*flags=*/SF_DEFAULT); } /* Returns true iff an EH_SPEC_BLOCK should be created in the body of |