On 15/11/2019 00:49, Luc Van Oostenryck wrote: > 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 > Hi Luc, Just a quick heads up (since I can't look at this much for a few days now ...) that the current 'master' branch, when applied to git, causes 8 additional warnings. I have created a cut-down version of the code, thus: $ cat -n git-noreturn.c 1 #include <stdarg.h> 2 #include <unistd.h> 3 #include <stdlib.h> 4 5 #define NORETURN __attribute__((__noreturn__)) 6 #define NORETURN_PTR __attribute__((__noreturn__)) 7 8 void set_die_routine(NORETURN_PTR void (*routine)(const char *err, va_list params)); 9 10 static void NORETURN child_die_fn(const char *err, va_list params) 11 { 12 _exit(2); 13 } 14 15 static void somefunc(void) 16 { 17 set_die_routine(child_die_fn); 18 } 19 20 static NORETURN void die_builtin(const char *err, va_list params) 21 { 22 exit(128); 23 } 24 25 static NORETURN_PTR void (*die_routine)(const char *err, va_list params) = die_builtin; $ ... which causes the following warnings: $ ./sparse git-noreturn.c git-noreturn.c:17:25: warning: incorrect type in argument 1 (different modifiers) git-noreturn.c:17:25: expected void ( [noreturn] *routine )( ... ) git-noreturn.c:17:25: got void ( [noreturn] * )( ... ) git-noreturn.c:25:76: warning: incorrect type in initializer (different modifiers) git-noreturn.c:25:76: expected void ( *static [toplevel] [noreturn] die_routine )( ... ) git-noreturn.c:25:76: got void ( [noreturn] * )( ... ) $ The explanation of the two NORETUN macros is given in commit 18660bc96ec (add NORETURN_PTR for function pointers, 2009-09-30), which reads: commit 18660bc96ec0419cc096a53998d3197f2b905e8a Author: Erik Faye-Lund <kusmabite@xxxxxxxxx> Date: Wed Sep 30 18:05:50 2009 +0000 add NORETURN_PTR for function pointers Some compilers (including at least MSVC and ARM RVDS) supports NORETURN on function declarations, but not on function pointers. This patch makes it possible to define NORETURN for these compilers, by splitting the NORETURN macro into two - one for function declarations and one for function pointers. Signed-off-by: Erik Faye-Lund <kusmabite@xxxxxxxxx> Signed-off-by: Jeff King <peff@xxxxxxxx> ... Sorry to just dump and run ... (hopefully, the above is useful information - I will add the test file as an attachment). ATB, Ramsay Jones
#include <stdarg.h> #include <unistd.h> #include <stdlib.h> #define NORETURN __attribute__((__noreturn__)) #define NORETURN_PTR __attribute__((__noreturn__)) void set_die_routine(NORETURN_PTR void (*routine)(const char *err, va_list params)); static void NORETURN child_die_fn(const char *err, va_list params) { _exit(2); } static void somefunc(void) { set_die_routine(child_die_fn); } static NORETURN void die_builtin(const char *err, va_list params) { exit(128); } static NORETURN_PTR void (*die_routine)(const char *err, va_list params) = die_builtin;