aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosh Triplett <josht@vnet.ibm.com>2006-07-05 15:09:21 -0700
committerLinus Torvalds <torvalds@g5.osdl.org>2006-07-05 15:32:30 -0700
commit1c294832c10de9842170f1a9518d9fc04c0262f3 (patch)
tree0d9cd26975d83b6334648c0acad4ef4cd5dfbe75 /expression.c
parentFix NULL ptr dereference with bad type (diff)
downloadsparse-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.c49
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);