The syntax of extended ASM statements requires that the bodies & constraints are given via a literal string. However, at parsing time more general expressions are accepted and it's checked only at evaluation time if these are effectively string literals. This has at least two drawbacks: *) evaluate_asm_statement() is slightly more complicated than needed, mixing these checks with the real evaluation code *) in case of error, the diagnostic is issued later than other syntaxic warnings. Fix this by checking at parse-time that ASM bodies & constraints are string literals and not some arbitrary expressions. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx> --- evaluate.c | 14 +++----------- parse.c | 7 ++++--- validation/asm-bad0.c | 6 +++--- 3 files changed, 10 insertions(+), 17 deletions(-) diff --git a/evaluate.c b/evaluate.c index 70d76523e..634da4b93 100644 --- a/evaluate.c +++ b/evaluate.c @@ -3523,20 +3523,15 @@ static void evaluate_asm_statement(struct statement *stmt) struct symbol *sym; expr = stmt->asm_string; - if (!expr || expr->type != EXPR_STRING) { - sparse_error(stmt->pos, "need constant string for inline asm"); + if (!expr) return; - } FOR_EACH_PTR(stmt->asm_outputs, op) { /* Identifier */ /* Constraint */ expr = op->constraint; - if (!expr || expr->type != EXPR_STRING) { - sparse_error(expr ? expr->pos : stmt->pos, "asm output constraint is not a string"); - op->constraint = NULL; - } else + if (expr) verify_output_constraint(expr, expr->string->data); /* Expression */ @@ -3553,10 +3548,7 @@ static void evaluate_asm_statement(struct statement *stmt) /* Constraint */ expr = op->constraint; - if (!expr || expr->type != EXPR_STRING) { - sparse_error(expr ? expr->pos : stmt->pos, "asm input constraint is not a string"); - op->constraint = NULL; - } else + if (expr) verify_input_constraint(expr, expr->string->data); /* Expression */ diff --git a/parse.c b/parse.c index 401f91a1f..23c0ee012 100644 --- a/parse.c +++ b/parse.c @@ -2050,7 +2050,8 @@ static struct token *parse_asm_operands(struct token *token, struct statement *s op->name = token->next->next->ident; token = token->next->next->next; } - token = primary_expression(token->next, &op->constraint); + token = token->next; + token = string_expression(token, &op->constraint, "asm constraint"); token = parens_expression(token, &op->expr, "in asm parameter"); add_expression(inout, op); } while (match_op(token, ',')); @@ -2101,7 +2102,7 @@ static struct token *parse_asm_statement(struct token *token, struct statement * token = token->next; } token = expect(token, '(', "after asm"); - token = parse_expression(token, &stmt->asm_string); + token = string_expression(token, &stmt->asm_string, "inline asm"); if (match_op(token, ':')) token = parse_asm_operands(token, stmt, &stmt->asm_outputs); if (match_op(token, ':')) @@ -2118,7 +2119,7 @@ static struct token *parse_asm_declarator(struct token *token, struct decl_state { struct expression *expr; token = expect(token, '(', "after asm"); - token = parse_expression(token->next, &expr); + token = string_expression(token, &expr, "inline asm"); token = expect(token, ')', "after asm"); return token; } diff --git a/validation/asm-bad0.c b/validation/asm-bad0.c index fcd9b1c4d..aa9bf28d7 100644 --- a/validation/asm-bad0.c +++ b/validation/asm-bad0.c @@ -30,12 +30,12 @@ static void iexpr(void) * check-name: asm-bad0 * * check-error-start +asm-bad0.c:6:13: error: string literal expected for inline asm +asm-bad0.c:11:32: error: string literal expected for asm constraint +asm-bad0.c:16:49: error: string literal expected for asm constraint asm-bad0.c:21:41: error: Expected ] at end of array dereference asm-bad0.c:21:41: error: got ) asm-bad0.c:26:59: error: Expected ] at end of array dereference asm-bad0.c:26:59: error: got ) -asm-bad0.c:6:9: error: need constant string for inline asm -asm-bad0.c:11:32: error: asm output constraint is not a string -asm-bad0.c:16:49: error: asm input constraint is not a string * check-error-end */ -- 2.23.0