diff options
author | Josh Triplett <josht@vnet.ibm.com> | 2006-07-05 15:09:21 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-07-05 15:32:30 -0700 |
commit | 1c294832c10de9842170f1a9518d9fc04c0262f3 (patch) | |
tree | 0d9cd26975d83b6334648c0acad4ef4cd5dfbe75 /expression.c | |
parent | Fix NULL ptr dereference with bad type (diff) | |
download | sparse-1c294832c10de9842170f1a9518d9fc04c0262f3.tar.gz sparse-1c294832c10de9842170f1a9518d9fc04c0262f3.tar.bz2 sparse-1c294832c10de9842170f1a9518d9fc04c0262f3.zip |
[PATCH] Add support for GCC's __builtin_types_compatible_p extension
Parse and support GCC's __builtin_types_compatible_p extension, which takes
two types as arguments, and returns 1 for compatible types or 0 for
incompatible types. Since sparse already supports comparisons with types as
the operands, just transform __builtin_types_compatible_p(a, b) into the
comparison a == b.
Signed-off-by: Josh Triplett <josh@freedesktop.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'expression.c')
-rw-r--r-- | expression.c | 49 |
1 files changed, 47 insertions, 2 deletions
diff --git a/expression.c b/expression.c index aabea6c..b1ffa6c 100644 --- a/expression.c +++ b/expression.c @@ -114,6 +114,45 @@ static int convert_function(struct token *next) return retval; } +static struct token *parse_type(struct token *token, struct expression **tree) +{ + struct symbol *sym; + *tree = alloc_expression(token->pos, EXPR_TYPE); + token = typename(token, &sym); + if (sym->ident) + sparse_error(token->pos, + "type expression should not include identifier " + "\"%s\"", sym->ident->name); + (*tree)->symbol = sym; + return token; +} + +static struct token *builtin_types_compatible_p_expr(struct token *token, + struct expression **tree) +{ + struct expression *expr = alloc_expression( + token->pos, EXPR_COMPARE); + expr->op = SPECIAL_EQUAL; + token = token->next; + if (!match_op(token, '(')) + return expect(token, '(', + "after __builtin_types_compatible_p"); + token = token->next; + token = parse_type(token, &expr->left); + if (!match_op(token, ',')) + return expect(token, ',', + "in __builtin_types_compatible_p"); + token = token->next; + token = parse_type(token, &expr->right); + if (!match_op(token, ')')) + return expect(token, ')', + "at end of __builtin_types_compatible_p"); + token = token->next; + + *tree = expr; + return token; +} + static struct token *string_expression(struct token *token, struct expression *expr) { struct string *string = token->string; @@ -314,8 +353,14 @@ struct token *primary_expression(struct token *token, struct expression **tree) struct symbol *sym = lookup_symbol(token->ident, NS_SYMBOL | NS_TYPEDEF); struct token *next = token->next; - if (!sym && convert_function(token)) - goto handle_string; + if (!sym) { + if (convert_function(token)) + goto handle_string; + if (token->ident == &__builtin_types_compatible_p_ident) { + token = builtin_types_compatible_p_expr(token, &expr); + break; + } + } expr = alloc_expression(token->pos, EXPR_SYMBOL); |