re PR c++/30849 (ICE with invalid asm statement)

PR c++/30849
	PR c++/30850
	PR c++/30851
	* parser.c (cp_parser_asm_definition): Detect and discard asm
	statements with invalid inputs or outputs.
        (cp_parser_asm_operand_list): Return error mark node if any
        of the operands are invalid. Adjust documentation.

	PR c++/30849
	* g++.dg/parse/asm1.C: New test.

	PR c++/30850
	* g++.dg/parse/asm2.C: Likewise.

	PR c++/30851
	* g++.dg/parse/asm3.C: Likewise.

From-SVN: r127167
This commit is contained in:
Lee Millward 2007-08-02 17:50:55 +00:00 committed by Lee Millward
parent 2ee0c1fb57
commit f8ff69ea9a
6 changed files with 72 additions and 14 deletions

View File

@ -1,3 +1,14 @@
2007-08-02 Lee Millward <lee.millward@gmail.com>
PR c++/30849
PR c++/30850
PR c++/30851
* parser.c (cp_parser_asm_definition): Detect and discard asm
statements with invalid inputs or outputs.
(cp_parser_asm_operand_list): Return error mark node if any
of the operands are invalid. Adjust documentation.
2007-08-02 Nick Clifton <nickc@redhat.com>
* typeck.c: Change copyright header to refer to version 3 of the

View File

@ -11755,6 +11755,8 @@ cp_parser_asm_definition (cp_parser* parser)
tree asm_stmt;
bool volatile_p = false;
bool extended_p = false;
bool invalid_inputs_p = false;
bool invalid_outputs_p = false;
/* Look for the `asm' keyword. */
cp_parser_require_keyword (parser, RID_ASM, "`asm'");
@ -11808,6 +11810,9 @@ cp_parser_asm_definition (cp_parser* parser)
&& cp_lexer_next_token_is_not (parser->lexer,
CPP_CLOSE_PAREN))
outputs = cp_parser_asm_operand_list (parser);
if (outputs == error_mark_node)
invalid_outputs_p = true;
}
/* If the next token is `::', there are no outputs, and the
next token is the beginning of the inputs. */
@ -11827,6 +11832,9 @@ cp_parser_asm_definition (cp_parser* parser)
&& cp_lexer_next_token_is_not (parser->lexer,
CPP_CLOSE_PAREN))
inputs = cp_parser_asm_operand_list (parser);
if (inputs == error_mark_node)
invalid_inputs_p = true;
}
else if (cp_lexer_next_token_is (parser->lexer, CPP_SCOPE))
/* The clobbers are coming next. */
@ -11850,23 +11858,26 @@ cp_parser_asm_definition (cp_parser* parser)
/*consume_paren=*/true);
cp_parser_require (parser, CPP_SEMICOLON, "`;'");
/* Create the ASM_EXPR. */
if (parser->in_function_body)
if (!invalid_inputs_p && !invalid_outputs_p)
{
asm_stmt = finish_asm_stmt (volatile_p, string, outputs,
inputs, clobbers);
/* If the extended syntax was not used, mark the ASM_EXPR. */
if (!extended_p)
/* Create the ASM_EXPR. */
if (parser->in_function_body)
{
tree temp = asm_stmt;
if (TREE_CODE (temp) == CLEANUP_POINT_EXPR)
temp = TREE_OPERAND (temp, 0);
asm_stmt = finish_asm_stmt (volatile_p, string, outputs,
inputs, clobbers);
/* If the extended syntax was not used, mark the ASM_EXPR. */
if (!extended_p)
{
tree temp = asm_stmt;
if (TREE_CODE (temp) == CLEANUP_POINT_EXPR)
temp = TREE_OPERAND (temp, 0);
ASM_INPUT_P (temp) = 1;
ASM_INPUT_P (temp) = 1;
}
}
else
cgraph_add_asm_node (string);
}
else
cgraph_add_asm_node (string);
}
/* Declarators [gram.dcl.decl] */
@ -15645,12 +15656,14 @@ cp_parser_asm_specification_opt (cp_parser* parser)
each node is the expression. The TREE_PURPOSE is itself a
TREE_LIST whose TREE_PURPOSE is a STRING_CST for the bracketed
string-literal (or NULL_TREE if not present) and whose TREE_VALUE
is a STRING_CST for the string literal before the parenthesis. */
is a STRING_CST for the string literal before the parenthesis. Returns
ERROR_MARK_NODE if any of the operands are invalid. */
static tree
cp_parser_asm_operand_list (cp_parser* parser)
{
tree asm_operands = NULL_TREE;
bool invalid_operands = false;
while (true)
{
@ -15682,6 +15695,11 @@ cp_parser_asm_operand_list (cp_parser* parser)
/* Look for the `)'. */
cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'");
if (name == error_mark_node
|| string_literal == error_mark_node
|| expression == error_mark_node)
invalid_operands = true;
/* Add this operand to the list. */
asm_operands = tree_cons (build_tree_list (name, string_literal),
expression,
@ -15694,7 +15712,7 @@ cp_parser_asm_operand_list (cp_parser* parser)
cp_lexer_consume_token (parser->lexer);
}
return nreverse (asm_operands);
return invalid_operands ? error_mark_node : nreverse (asm_operands);
}
/* Parse an asm-clobber-list.

View File

@ -1,3 +1,14 @@
2007-08-02 Lee Millward <lee.millward@gmail.com>
PR c++/30849
* g++.dg/parse/asm1.C: New test.
PR c++/30850
* g++.dg/parse/asm2.C: Likewise.
PR c++/30851
* g++.dg/parse/asm3.C: Likewise.
2007-08-02 Rask Ingemann Lambertsen <rask@sygehus.dk>
* gcc.dg/tree-ssa/gen-vect-2.c: Use "char" for vector elements if

View File

@ -0,0 +1,6 @@
//PR c++/30849
void foo()
{
asm("" : 0); // { dg-error "numeric constant|token" }
}

View File

@ -0,0 +1,6 @@
//PR c++/30850
void foo()
{
asm("" :: 0); // { dg-error "numeric constant|token" }
}

View File

@ -0,0 +1,6 @@
//PR c++/30851
void foo()
{
asm ("%[x]" : [0](x)); // { dg-error "numeric constant|token" }
}