Commit f8ff69ea by Lee Millward Committed by Lee Millward

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
parent 2ee0c1fb
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> 2007-08-02 Nick Clifton <nickc@redhat.com>
* typeck.c: Change copyright header to refer to version 3 of the * typeck.c: Change copyright header to refer to version 3 of the
......
...@@ -11755,6 +11755,8 @@ cp_parser_asm_definition (cp_parser* parser) ...@@ -11755,6 +11755,8 @@ cp_parser_asm_definition (cp_parser* parser)
tree asm_stmt; tree asm_stmt;
bool volatile_p = false; bool volatile_p = false;
bool extended_p = false; bool extended_p = false;
bool invalid_inputs_p = false;
bool invalid_outputs_p = false;
/* Look for the `asm' keyword. */ /* Look for the `asm' keyword. */
cp_parser_require_keyword (parser, RID_ASM, "`asm'"); cp_parser_require_keyword (parser, RID_ASM, "`asm'");
...@@ -11808,6 +11810,9 @@ cp_parser_asm_definition (cp_parser* parser) ...@@ -11808,6 +11810,9 @@ cp_parser_asm_definition (cp_parser* parser)
&& cp_lexer_next_token_is_not (parser->lexer, && cp_lexer_next_token_is_not (parser->lexer,
CPP_CLOSE_PAREN)) CPP_CLOSE_PAREN))
outputs = cp_parser_asm_operand_list (parser); 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 /* If the next token is `::', there are no outputs, and the
next token is the beginning of the inputs. */ next token is the beginning of the inputs. */
...@@ -11827,6 +11832,9 @@ cp_parser_asm_definition (cp_parser* parser) ...@@ -11827,6 +11832,9 @@ cp_parser_asm_definition (cp_parser* parser)
&& cp_lexer_next_token_is_not (parser->lexer, && cp_lexer_next_token_is_not (parser->lexer,
CPP_CLOSE_PAREN)) CPP_CLOSE_PAREN))
inputs = cp_parser_asm_operand_list (parser); 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)) else if (cp_lexer_next_token_is (parser->lexer, CPP_SCOPE))
/* The clobbers are coming next. */ /* The clobbers are coming next. */
...@@ -11850,6 +11858,8 @@ cp_parser_asm_definition (cp_parser* parser) ...@@ -11850,6 +11858,8 @@ cp_parser_asm_definition (cp_parser* parser)
/*consume_paren=*/true); /*consume_paren=*/true);
cp_parser_require (parser, CPP_SEMICOLON, "`;'"); cp_parser_require (parser, CPP_SEMICOLON, "`;'");
if (!invalid_inputs_p && !invalid_outputs_p)
{
/* Create the ASM_EXPR. */ /* Create the ASM_EXPR. */
if (parser->in_function_body) if (parser->in_function_body)
{ {
...@@ -11867,6 +11877,7 @@ cp_parser_asm_definition (cp_parser* parser) ...@@ -11867,6 +11877,7 @@ cp_parser_asm_definition (cp_parser* parser)
} }
else else
cgraph_add_asm_node (string); cgraph_add_asm_node (string);
}
} }
/* Declarators [gram.dcl.decl] */ /* Declarators [gram.dcl.decl] */
...@@ -15645,12 +15656,14 @@ cp_parser_asm_specification_opt (cp_parser* parser) ...@@ -15645,12 +15656,14 @@ cp_parser_asm_specification_opt (cp_parser* parser)
each node is the expression. The TREE_PURPOSE is itself a each node is the expression. The TREE_PURPOSE is itself a
TREE_LIST whose TREE_PURPOSE is a STRING_CST for the bracketed TREE_LIST whose TREE_PURPOSE is a STRING_CST for the bracketed
string-literal (or NULL_TREE if not present) and whose TREE_VALUE 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 static tree
cp_parser_asm_operand_list (cp_parser* parser) cp_parser_asm_operand_list (cp_parser* parser)
{ {
tree asm_operands = NULL_TREE; tree asm_operands = NULL_TREE;
bool invalid_operands = false;
while (true) while (true)
{ {
...@@ -15682,6 +15695,11 @@ cp_parser_asm_operand_list (cp_parser* parser) ...@@ -15682,6 +15695,11 @@ cp_parser_asm_operand_list (cp_parser* parser)
/* Look for the `)'. */ /* Look for the `)'. */
cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'"); 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. */ /* Add this operand to the list. */
asm_operands = tree_cons (build_tree_list (name, string_literal), asm_operands = tree_cons (build_tree_list (name, string_literal),
expression, expression,
...@@ -15694,7 +15712,7 @@ cp_parser_asm_operand_list (cp_parser* parser) ...@@ -15694,7 +15712,7 @@ cp_parser_asm_operand_list (cp_parser* parser)
cp_lexer_consume_token (parser->lexer); cp_lexer_consume_token (parser->lexer);
} }
return nreverse (asm_operands); return invalid_operands ? error_mark_node : nreverse (asm_operands);
} }
/* Parse an asm-clobber-list. /* Parse an asm-clobber-list.
......
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> 2007-08-02 Rask Ingemann Lambertsen <rask@sygehus.dk>
* gcc.dg/tree-ssa/gen-vect-2.c: Use "char" for vector elements if * gcc.dg/tree-ssa/gen-vect-2.c: Use "char" for vector elements if
//PR c++/30849
void foo()
{
asm("" : 0); // { dg-error "numeric constant|token" }
}
//PR c++/30850
void foo()
{
asm("" :: 0); // { dg-error "numeric constant|token" }
}
//PR c++/30851
void foo()
{
asm ("%[x]" : [0](x)); // { dg-error "numeric constant|token" }
}
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