summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorJann Horn <jannh@google.com>2019-03-27 21:10:38 +0100
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2019-03-27 22:12:24 +0100
commit1ed0955919913ad4f314e867fcbc76535acf010c (patch)
treecf38b8d8908664d0b0c78b43a40b951e4d9b027d
parent7fd3778e2d3a7b17aefea66819bf07feb7a257d3 (diff)
downloadsparse-1ed0955919913ad4f314e867fcbc76535acf010c.tar.gz
evaluate: externally_visible functions don't need a declaration
sparse warns for non-static functions that don't have a separate declaration. The kernel contains several such functions that are marked as __attribute__((externally_visible)) to mark that they are called from assembly code. Assembly code doesn't need a header with a declaration to call a function. Therefore, suppress the warning for functions with __attribute__((externally_visible)). Signed-off-by: Jann Horn <jannh@google.com> Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
-rw-r--r--evaluate.c2
-rw-r--r--gcc-attr-list.h1
-rw-r--r--parse.c16
-rw-r--r--symbol.h4
4 files changed, 19 insertions, 4 deletions
diff --git a/evaluate.c b/evaluate.c
index cedd1330..7c63d788 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -3387,7 +3387,7 @@ void check_duplicates(struct symbol *sym)
}
if (!declared) {
unsigned long mod = sym->ctype.modifiers;
- if (mod & (MOD_STATIC | MOD_REGISTER))
+ if (mod & (MOD_STATIC | MOD_REGISTER | MOD_EXT_VISIBLE))
return;
if (!(mod & MOD_TOPLEVEL))
return;
diff --git a/gcc-attr-list.h b/gcc-attr-list.h
index 8da31435..c7800175 100644
--- a/gcc-attr-list.h
+++ b/gcc-attr-list.h
@@ -42,7 +42,6 @@ GCC_ATTR(either)
GCC_ATTR(error)
GCC_ATTR(exception)
GCC_ATTR(exception_handler)
-GCC_ATTR(externally_visible)
GCC_ATTR(far)
GCC_ATTR(fast_interrupt)
GCC_ATTR(fastcall)
diff --git a/parse.c b/parse.c
index 79543432..f291e247 100644
--- a/parse.c
+++ b/parse.c
@@ -82,6 +82,7 @@ typedef struct token *attr_t(struct token *, struct symbol *,
static attr_t
attribute_packed, attribute_aligned, attribute_modifier,
+ attribute_ext_visible,
attribute_bitwise,
attribute_address_space, attribute_context,
attribute_designated_init,
@@ -373,6 +374,10 @@ static struct symbol_op attr_mod_op = {
.attribute = attribute_modifier,
};
+static struct symbol_op ext_visible_op = {
+ .attribute = attribute_ext_visible,
+};
+
static struct symbol_op attr_bitwise_op = {
.attribute = attribute_bitwise,
};
@@ -562,6 +567,8 @@ static struct init_keyword {
{"const", NS_KEYWORD, MOD_PURE, .op = &attr_mod_op },
{"__const", NS_KEYWORD, MOD_PURE, .op = &attr_mod_op },
{"__const__", NS_KEYWORD, MOD_PURE, .op = &attr_mod_op },
+ {"externally_visible", NS_KEYWORD, .op = &ext_visible_op },
+ {"__externally_visible__", NS_KEYWORD, .op = &ext_visible_op },
{ "mode", NS_KEYWORD, .op = &mode_op },
{ "__mode__", NS_KEYWORD, .op = &mode_op },
@@ -1106,6 +1113,12 @@ static struct token *attribute_modifier(struct token *token, struct symbol *attr
return token;
}
+static struct token *attribute_ext_visible(struct token *token, struct symbol *attr, struct decl_state *ctx)
+{
+ ctx->is_ext_visible = 1;
+ return token;
+}
+
static struct token *attribute_bitwise(struct token *token, struct symbol *attr, struct decl_state *ctx)
{
if (Wbitwise)
@@ -1343,7 +1356,8 @@ static unsigned long storage_modifiers(struct decl_state *ctx)
[SRegister] = MOD_REGISTER
};
return mod[ctx->storage_class] | (ctx->is_inline ? MOD_INLINE : 0)
- | (ctx->is_tls ? MOD_TLS : 0);
+ | (ctx->is_tls ? MOD_TLS : 0)
+ | (ctx->is_ext_visible ? MOD_EXT_VISIBLE : 0);
}
static void set_storage_class(struct position *pos, struct decl_state *ctx, int class)
diff --git a/symbol.h b/symbol.h
index 51e1c867..ac43b314 100644
--- a/symbol.h
+++ b/symbol.h
@@ -110,6 +110,7 @@ struct decl_state {
struct ident **ident;
struct symbol_op *mode;
unsigned char prefer_abstract, is_inline, storage_class, is_tls;
+ unsigned char is_ext_visible;
};
struct symbol_op {
@@ -237,6 +238,7 @@ struct symbol {
#define MOD_NOCAST 0x04000000
#define MOD_NODEREF 0x08000000
#define MOD_NORETURN 0x10000000
+#define MOD_EXT_VISIBLE 0x20000000
#define MOD_ACCESS (MOD_ASSIGNED | MOD_ADDRESSABLE)
@@ -246,7 +248,7 @@ struct symbol {
#define MOD_LONG_ALL (MOD_LONG | MOD_LONGLONG | MOD_LONGLONGLONG)
#define MOD_SPECIFIER (MOD_CHAR | MOD_SHORT | MOD_LONG_ALL | MOD_SIGNEDNESS)
#define MOD_SIZE (MOD_CHAR | MOD_SHORT | MOD_LONG_ALL)
-#define MOD_IGNORE (MOD_STORAGE | MOD_ACCESS | MOD_USERTYPE | MOD_EXPLICITLY_SIGNED)
+#define MOD_IGNORE (MOD_STORAGE | MOD_ACCESS | MOD_USERTYPE | MOD_EXPLICITLY_SIGNED | MOD_EXT_VISIBLE)
#define MOD_QUALIFIER (MOD_CONST | MOD_VOLATILE | MOD_RESTRICT | MOD_ATOMIC)
#define MOD_PTRINHERIT (MOD_QUALIFIER | MOD_NODEREF | MOD_NORETURN | MOD_NOCAST)
/* modifiers preserved by typeof() operator */