Powered by Linux
[PATCH] function attributes apply to the function declaration — Semantic Matching Tool

[PATCH] function attributes apply to the function declaration

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

 



Function attributes relate to the function declaration they
appear in. Sparse ignore most these attributes but a few ones
have a semantic value: 'pure', 'noreturn' & 'externally_visible'.

Due to how Sparse parse attributes and how these attributes
are stored for functions, the attributes 'pure' & 'noreturn'
are applied not to the function itself but its return type
if the function returns a pointer.

Fix this by extracting these attributes from the declaration
context and ensure they're applied to the declarator.

Reported-by: John Levon <john.levon@xxxxxxxxxx>
Reported-by: Alex Kogan <alex.kogan@xxxxxxxxxx>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx>
---
 parse.c                         | 17 ++++++++++++++++-
 symbol.h                        |  2 ++
 validation/function-attribute.c | 19 +++++++++++++++++++
 3 files changed, 37 insertions(+), 1 deletion(-)
 create mode 100644 validation/function-attribute.c

diff --git a/parse.c b/parse.c
index fa92fae68..37ffede72 100644
--- a/parse.c
+++ b/parse.c
@@ -2900,6 +2900,21 @@ static struct token *toplevel_asm_declaration(struct token *token, struct symbol
 	return token;
 }
 
+static unsigned long declaration_modifiers(struct decl_state *ctx)
+{
+	unsigned long mods;
+
+	// Storage modifiers only relates to the declaration
+	mods = storage_modifiers(ctx);
+
+	// Function attributes also only relates to the declaration
+	// and must not be present in the function/return type.
+	mods |= ctx->ctype.modifiers & MOD_FUN_ATTR;
+	ctx->ctype.modifiers &=~ MOD_FUN_ATTR;
+
+	return mods;
+}
+
 struct token *external_declaration(struct token *token, struct symbol_list **list,
 		validate_decl_t validate_decl)
 {
@@ -2920,7 +2935,7 @@ struct token *external_declaration(struct token *token, struct symbol_list **lis
 
 	/* Parse declaration-specifiers, if any */
 	token = declaration_specifiers(token, &ctx);
-	mod = storage_modifiers(&ctx);
+	mod = declaration_modifiers(&ctx);
 	decl = alloc_symbol(token->pos, SYM_NODE);
 	/* Just a type declaration? */
 	if (match_op(token, ';')) {
diff --git a/symbol.h b/symbol.h
index 4e7e437bf..516b61361 100644
--- a/symbol.h
+++ b/symbol.h
@@ -251,6 +251,8 @@ struct symbol {
 #define MOD_PTRINHERIT	(MOD_QUALIFIER | MOD_NODEREF | MOD_NORETURN | MOD_NOCAST)
 /* modifiers preserved by typeof() operator */
 #define MOD_TYPEOF	(MOD_QUALIFIER | MOD_NOCAST | MOD_SPECIFIER)
+/* modifiers for funtion attributes */
+#define MOD_FUN_ATTR	(MOD_PURE|MOD_NORETURN)
 
 
 /* Current parsing/evaluation function */
diff --git a/validation/function-attribute.c b/validation/function-attribute.c
new file mode 100644
index 000000000..0f2c75922
--- /dev/null
+++ b/validation/function-attribute.c
@@ -0,0 +1,19 @@
+#define __pure __attribute__((pure))
+
+struct s {
+	int x;
+};
+
+static __pure struct s *grab(struct s *ptr)
+{
+	return ptr;
+}
+
+static void foo(struct s *ptr)
+{
+	struct s *ptr = grab(ptr);
+}
+
+/*
+ * check-name: function-attribute
+ */
-- 
2.24.0




[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux