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)). This patch makes the following warnings disappear: arch/x86/boot/compressed/misc.c:339:27: warning: symbol 'extract_kernel' was not declared. Should it be static? arch/x86/entry/common.c:272:16: warning: symbol 'do_syscall_64' was not declared. Should it be static? arch/x86/entry/common.c:345:16: warning: symbol 'do_int80_syscall_32' was not declared. Should it be static? arch/x86/entry/common.c:353:16: warning: symbol 'do_fast_syscall_32' was not declared. Should it be static? arch/x86/mm/extable.c:105:16: warning: symbol 'ex_handler_fprestore' was not declared. Should it be static? arch/x86/mm/extable.c:120:16: warning: symbol 'ex_handler_uaccess' was not declared. Should it be static? arch/x86/mm/extable.c:131:16: warning: symbol 'ex_handler_ext' was not declared. Should it be static? arch/x86/mm/extable.c:143:16: warning: symbol 'ex_handler_rdmsr_unsafe' was not declared. Should it be static? arch/x86/mm/extable.c:160:16: warning: symbol 'ex_handler_wrmsr_unsafe' was not declared. Should it be static? arch/x86/mm/extable.c:176:16: warning: symbol 'ex_handler_clear_fs' was not declared. Should it be static? arch/x86/mm/extable.c:25:16: warning: symbol 'ex_handler_default' was not declared. Should it be static? arch/x86/mm/extable.c:35:16: warning: symbol 'ex_handler_fault' was not declared. Should it be static? arch/x86/mm/extable.c:50:16: warning: symbol 'ex_handler_refcount' was not declared. Should it be static? arch/x86/xen/enlighten_pv.c:1192:34: warning: symbol 'xen_start_kernel' was not declared. Should it be static? arch/x86/xen/irq.c:27:36: warning: symbol 'xen_save_fl' was not declared. Should it be static? arch/x86/xen/irq.c:45:16: warning: symbol 'xen_restore_fl' was not declared. Should it be static? arch/x86/xen/irq.c:67:27: warning: symbol 'xen_irq_disable' was not declared. Should it be static? arch/x86/xen/irq.c:78:27: warning: symbol 'xen_irq_enable' was not declared. Should it be static? arch/x86/xen/mmu_pv.c:1550:17: warning: symbol 'xen_make_pte_init' was not declared. Should it be static? arch/x86/xen/mmu_pv.c:375:20: warning: symbol 'xen_pte_val' was not declared. Should it be static? arch/x86/xen/mmu_pv.c:383:20: warning: symbol 'xen_pgd_val' was not declared. Should it be static? arch/x86/xen/mmu_pv.c:389:17: warning: symbol 'xen_make_pte' was not declared. Should it be static? arch/x86/xen/mmu_pv.c:397:17: warning: symbol 'xen_make_pgd' was not declared. Should it be static? arch/x86/xen/mmu_pv.c:404:20: warning: symbol 'xen_pmd_val' was not declared. Should it be static? arch/x86/xen/mmu_pv.c:462:17: warning: symbol 'xen_make_pmd' was not declared. Should it be static? arch/x86/xen/mmu_pv.c:470:20: warning: symbol 'xen_pud_val' was not declared. Should it be static? arch/x86/xen/mmu_pv.c:476:17: warning: symbol 'xen_make_pud' was not declared. Should it be static? arch/x86/xen/smp_pv.c:89:27: warning: symbol 'cpu_bringup_and_idle' was not declared. Should it be static? kernel/extable.c:44:26: warning: symbol 'main_extable_sort_needed' was not declared. Should it be static? kernel/locking/qspinlock_paravirt.h:492:1: warning: symbol '__pv_queued_spin_unlock_slowpath' was not declared. Should it be static? kernel/panic.c:665:16: warning: symbol '__stack_chk_fail' was not declared. Should it be static? kernel/sched/core.c:3733:35: warning: symbol 'preempt_schedule_irq' was not declared. Should it be static? Signed-off-by: Jann Horn <jannh@xxxxxxxxxx> --- evaluate.c | 2 +- gcc-attr-list.h | 1 - parse.c | 16 +++++++++++++++- symbol.h | 4 +++- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/evaluate.c b/evaluate.c index cedd133..7c63d78 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 8da3143..c780017 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 7954343..f291e24 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 51e1c86..ac43b31 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 */ -- 2.21.0.392.gf8f6787159e-goog