aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/parser.c
diff options
context:
space:
mode:
authorLee Millward <lee.millward@gmail.com>2007-08-02 17:50:55 +0000
committerLee Millward <lmillward@gcc.gnu.org>2007-08-02 17:50:55 +0000
commitf8ff69ea9a57722ddf980ea9834682c2137ea8db (patch)
tree82375a521dcc73acb141e68c2640f8efff29abdb /gcc/cp/parser.c
parent2ee0c1fb57b65ecef76c0fb14c9d05c4fbec2980 (diff)
downloadgcc-f8ff69ea9a57722ddf980ea9834682c2137ea8db.zip
gcc-f8ff69ea9a57722ddf980ea9834682c2137ea8db.tar.gz
gcc-f8ff69ea9a57722ddf980ea9834682c2137ea8db.tar.bz2
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
Diffstat (limited to 'gcc/cp/parser.c')
-rw-r--r--gcc/cp/parser.c46
1 files changed, 32 insertions, 14 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 4e42422..530ddba 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -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.