[PATCH 1/2] Add support for GCC's __builtin_types_compatible_p extension

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxxxxxxx>
---
The Linux -rt tree uses this extension, so sparse needs this change in
order to run on the -rt tree.

 expression.c |   49 +++++++++++++++++++++++++++++++++++++++++++++++--
 ident-list.h |    1 +
 2 files changed, 48 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
 	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 
 		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);
 
diff --git a/ident-list.h b/ident-list.h
index 3051e56..4381a4b 100644
--- a/ident-list.h
+++ b/ident-list.h
@@ -35,6 +35,7 @@ IDENT_RESERVED(__asm);
 IDENT_RESERVED(__alignof);
 IDENT_RESERVED(__alignof__); 
 IDENT_RESERVED(__sizeof_ptr__);
+IDENT_RESERVED(__builtin_types_compatible_p);
 
 /* Attribute names */
 IDENT(defined); IDENT(packed); IDENT(__packed__);


-
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Newbies FAQ]     [LKML]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Trinity Fuzzer Tool]

  Powered by Linux