From f8ff69ea9a57722ddf980ea9834682c2137ea8db Mon Sep 17 00:00:00 2001 From: Lee Millward Date: Thu, 2 Aug 2007 17:50:55 +0000 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 11 ++++++++ gcc/cp/parser.c | 46 +++++++++++++++++++++---------- gcc/testsuite/ChangeLog | 11 ++++++++ gcc/testsuite/g++.dg/parse/asm1.C | 6 ++++ gcc/testsuite/g++.dg/parse/asm2.C | 6 ++++ gcc/testsuite/g++.dg/parse/asm3.C | 6 ++++ 6 files changed, 72 insertions(+), 14 deletions(-) create mode 100644 gcc/testsuite/g++.dg/parse/asm1.C create mode 100644 gcc/testsuite/g++.dg/parse/asm2.C create mode 100644 gcc/testsuite/g++.dg/parse/asm3.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2697da3938e..26edb7dfdcf 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,14 @@ + +2007-08-02 Lee Millward + + 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 * typeck.c: Change copyright header to refer to version 3 of the diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 4e4242290c1..530ddbae8a2 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. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a03a6d138be..07d751b5d7a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,14 @@ +2007-08-02 Lee Millward + + 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 * gcc.dg/tree-ssa/gen-vect-2.c: Use "char" for vector elements if diff --git a/gcc/testsuite/g++.dg/parse/asm1.C b/gcc/testsuite/g++.dg/parse/asm1.C new file mode 100644 index 00000000000..009ffbd3ad3 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/asm1.C @@ -0,0 +1,6 @@ +//PR c++/30849 + +void foo() +{ + asm("" : 0); // { dg-error "numeric constant|token" } +} diff --git a/gcc/testsuite/g++.dg/parse/asm2.C b/gcc/testsuite/g++.dg/parse/asm2.C new file mode 100644 index 00000000000..09924c9c7c3 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/asm2.C @@ -0,0 +1,6 @@ +//PR c++/30850 + +void foo() +{ + asm("" :: 0); // { dg-error "numeric constant|token" } +} diff --git a/gcc/testsuite/g++.dg/parse/asm3.C b/gcc/testsuite/g++.dg/parse/asm3.C new file mode 100644 index 00000000000..91f19e48cd5 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/asm3.C @@ -0,0 +1,6 @@ +//PR c++/30851 + +void foo() +{ + asm ("%[x]" : [0](x)); // { dg-error "numeric constant|token" } +} -- 2.30.2