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'");
&& 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. */
&& 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. */
/*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] */
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)
{
/* 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,
cp_lexer_consume_token (parser->lexer);
}
- return nreverse (asm_operands);
+ return invalid_operands ? error_mark_node : nreverse (asm_operands);
}
/* Parse an asm-clobber-list.