diff options
author | Lee Millward <lee.millward@gmail.com> | 2007-08-02 17:50:55 +0000 |
---|---|---|
committer | Lee Millward <lmillward@gcc.gnu.org> | 2007-08-02 17:50:55 +0000 |
commit | f8ff69ea9a57722ddf980ea9834682c2137ea8db (patch) | |
tree | 82375a521dcc73acb141e68c2640f8efff29abdb /gcc/cp/parser.c | |
parent | 2ee0c1fb57b65ecef76c0fb14c9d05c4fbec2980 (diff) | |
download | gcc-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.c | 46 |
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. |