Commit 5fde62e2 by Paolo Carlini Committed by Paolo Carlini

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
parent 1d77bc54
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> 2013-07-03 Jakub Jelinek <jakub@redhat.com>
PR c++/57771 PR c++/57771
......
...@@ -5206,8 +5206,9 @@ extern void finish_enum_value_list (tree); ...@@ -5206,8 +5206,9 @@ extern void finish_enum_value_list (tree);
extern void finish_enum (tree); extern void finish_enum (tree);
extern void build_enumerator (tree, tree, tree, location_t); extern void build_enumerator (tree, tree, tree, location_t);
extern tree lookup_enumerator (tree, tree); extern tree lookup_enumerator (tree, tree);
extern void start_preparsed_function (tree, tree, int); extern bool start_preparsed_function (tree, tree, int);
extern int start_function (cp_decl_specifier_seq *, const cp_declarator *, tree); extern bool start_function (cp_decl_specifier_seq *,
const cp_declarator *, tree);
extern tree begin_function_body (void); extern tree begin_function_body (void);
extern void finish_function_body (tree); extern void finish_function_body (tree);
extern tree outer_curly_brace_block (tree); extern tree outer_curly_brace_block (tree);
......
...@@ -12993,7 +12993,7 @@ check_function_type (tree decl, tree current_function_parms) ...@@ -12993,7 +12993,7 @@ check_function_type (tree decl, tree current_function_parms)
error_mark_node if the function has never been defined, or error_mark_node if the function has never been defined, or
a BLOCK if the function has been defined somewhere. */ a BLOCK if the function has been defined somewhere. */
void bool
start_preparsed_function (tree decl1, tree attrs, int flags) start_preparsed_function (tree decl1, tree attrs, int flags)
{ {
tree ctype = NULL_TREE; tree ctype = NULL_TREE;
...@@ -13090,10 +13090,14 @@ start_preparsed_function (tree decl1, tree attrs, int flags) ...@@ -13090,10 +13090,14 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
by push_nested_class.) */ by push_nested_class.) */
if (processing_template_decl) if (processing_template_decl)
{ {
/* FIXME: Handle error_mark_node more gracefully. */
tree newdecl1 = push_template_decl (decl1); tree newdecl1 = push_template_decl (decl1);
if (newdecl1 != error_mark_node) if (newdecl1 == error_mark_node)
decl1 = newdecl1; {
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. */ /* We are now in the scope of the function being defined. */
...@@ -13204,7 +13208,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags) ...@@ -13204,7 +13208,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
/* This function may already have been parsed, in which case just /* This function may already have been parsed, in which case just
return; our caller will skip over the body without parsing. */ return; our caller will skip over the body without parsing. */
if (DECL_INITIAL (decl1) != error_mark_node) if (DECL_INITIAL (decl1) != error_mark_node)
return; return true;
/* Initialize RTL machinery. We cannot do this until /* Initialize RTL machinery. We cannot do this until
CURRENT_FUNCTION_DECL and DECL_RESULT are set up. We do this 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) ...@@ -13366,17 +13370,19 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
start_fname_decls (); start_fname_decls ();
store_parm_decls (current_function_parms); store_parm_decls (current_function_parms);
return true;
} }
/* Like start_preparsed_function, except that instead of a /* Like start_preparsed_function, except that instead of a
FUNCTION_DECL, this function takes DECLSPECS and DECLARATOR. FUNCTION_DECL, this function takes DECLSPECS and DECLARATOR.
Returns 1 on success. If the DECLARATOR is not suitable for a function Returns true on success. If the DECLARATOR is not suitable
(it defines a datum instead), we return 0, which tells for a function, we return false, which tells the parser to
yyparse to report a parse error. */ skip the entire function. */
int bool
start_function (cp_decl_specifier_seq *declspecs, start_function (cp_decl_specifier_seq *declspecs,
const cp_declarator *declarator, const cp_declarator *declarator,
tree attrs) tree attrs)
...@@ -13385,13 +13391,13 @@ start_function (cp_decl_specifier_seq *declspecs, ...@@ -13385,13 +13391,13 @@ start_function (cp_decl_specifier_seq *declspecs,
decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1, &attrs); decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1, &attrs);
if (decl1 == error_mark_node) if (decl1 == error_mark_node)
return 0; return false;
/* If the declarator is not suitable for a function definition, /* If the declarator is not suitable for a function definition,
cause a syntax error. */ cause a syntax error. */
if (decl1 == NULL_TREE || TREE_CODE (decl1) != FUNCTION_DECL) if (decl1 == NULL_TREE || TREE_CODE (decl1) != FUNCTION_DECL)
{ {
error ("invalid function declaration"); error ("invalid function declaration");
return 0; return false;
} }
if (DECL_MAIN_P (decl1)) if (DECL_MAIN_P (decl1))
...@@ -13400,9 +13406,7 @@ start_function (cp_decl_specifier_seq *declspecs, ...@@ -13400,9 +13406,7 @@ start_function (cp_decl_specifier_seq *declspecs,
gcc_assert (same_type_p (TREE_TYPE (TREE_TYPE (decl1)), gcc_assert (same_type_p (TREE_TYPE (TREE_TYPE (decl1)),
integer_type_node)); integer_type_node));
start_preparsed_function (decl1, attrs, /*flags=*/SF_DEFAULT); return start_preparsed_function (decl1, attrs, /*flags=*/SF_DEFAULT);
return 1;
} }
/* Returns true iff an EH_SPEC_BLOCK should be created in the body of /* Returns true iff an EH_SPEC_BLOCK should be created in the body of
......
2013-07-04 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/38634
* g++.dg/template/crash116.C: New.
2013-07-04 Joern Rennecke <joern.rennecke@embecosm.com> 2013-07-04 Joern Rennecke <joern.rennecke@embecosm.com>
* gcc.dg/tree-ssa/vrp66.c: Make conditional on { target { ! int16 } } . * gcc.dg/tree-ssa/vrp66.c: Make conditional on { target { ! int16 } } .
......
// PR c++/38634
template<int> struct A
{
A();
};
template<int N, char> A<N>::A() // { dg-error "template|required" }
{
struct B {};
}
A<0> a;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment