aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/parse.c
diff options
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2019-09-29 17:09:10 +0200
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2019-09-30 03:45:53 +0200
commitd466a02815b8109ea007736590bdd97f5d0aeb2f (patch)
tree5dd27f9401831f45ab77c6c31591327ec52c45a5 /parse.c
parentfded889cd4b3e0b5eef95440d3f96723e76a78e9 (diff)
parent5d0c4d96bdf4ab5df4ef0e31ab433e605299aabd (diff)
downloadsparse-dev-d466a02815b8109ea007736590bdd97f5d0aeb2f.tar.gz
Merge branch 'fix-expand-asm' into tip
Currently, ASM operands aren't expanded or even evaluated. This causes Sparse to emit warnings about 'unknown expression' during the linearization of these operands if they contains, for example, calls to __builtin_compatible_types_p(). Note: the correct handling of ASM operands needs to make the distinction between 'memory' operands and 'normal' operands. For this, it is needed to look at the constraints and these are architecture specific. The patches in this series only consider the constraints m, v, o & Q as being for memory operands and, happily, these seems to cover most usage for the most common architectures. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
Diffstat (limited to 'parse.c')
-rw-r--r--parse.c22
1 files changed, 9 insertions, 13 deletions
diff --git a/parse.c b/parse.c
index b01c876e..ac795bd7 100644
--- a/parse.c
+++ b/parse.c
@@ -2049,22 +2049,23 @@ static struct token *expression_statement(struct token *token, struct expression
}
static struct token *parse_asm_operands(struct token *token, struct statement *stmt,
- struct expression_list **inout)
+ struct asm_operand_list **inout)
{
/* Allow empty operands */
if (match_op(token->next, ':') || match_op(token->next, ')'))
return token->next;
do {
- struct expression *op = alloc_expression(token->pos, EXPR_ASM_OPERAND);
+ struct asm_operand *op = __alloc_asm_operand(0);
if (match_op(token->next, '[') &&
token_type(token->next->next) == TOKEN_IDENT &&
match_op(token->next->next->next, ']')) {
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);
+ add_ptr_list(inout, op);
} while (match_op(token, ','));
return token;
}
@@ -2113,7 +2114,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, ':'))
@@ -2130,7 +2131,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;
}
@@ -2144,14 +2145,9 @@ static struct token *parse_static_assert(struct token *token, struct symbol_list
if (!cond)
sparse_error(token->pos, "Expected constant expression");
token = expect(token, ',', "after conditional expression in _Static_assert");
- token = parse_expression(token, &message);
- if (!message || message->type != EXPR_STRING) {
- struct position pos;
-
- pos = message ? message->pos : token->pos;
- sparse_error(pos, "bad or missing string literal");
+ token = string_expression(token, &message, "_Static_assert()");
+ if (!message)
cond = NULL;
- }
token = expect(token, ')', "after diagnostic message in _Static_assert");
token = expect(token, ';', "after _Static_assert()");