fun with declarations and definitions
There are several interesting problems caused by the fact that
we create a separate symbol for each declaration of given function.
1)
static inline int f(void);
static int g(void)
{
return f();
}
static inline int f(void)
{
return 0;
}
gives an error, since the instance of f in g is not associated with anything
useful. Needless to say, this is a perfectly valid C. Moreover,
static inline int f(void)
{
return 0;
}
static inline int f(void);
static int g(void)
{
return f();
}
will step on the same thing. Currently we get the former case all over the
place in the kernel, thanks to the way DEFINE_SYSCALLx() is done.
I have a kinda-sorta fix for that (basically, add a reference to external
definition to struct symbol and update it correctly - it's not hard).
However, that doesn't cover *another* weirdness in the same area -
gccisms around extern inline. There we can have inline and external
definitions in the same translation unit (and they can be different,
to make the things even more interesting). Anyway, that's a separate
story - as it is, we don't even have a way to tell 'extern inline ...'
from 'inline ...'
2) More fun in the same area: checks for SYM_FN in external_declaration()
do not take into account the possibility of
void f(int);
typeof(f) g;
Ergo, we get linkage-less function declarations. Fun, innit? No patch.
3) Better yet, sparse does _NOT_ reject
typeof(f) g
{
...
}
which is obviously a Bloody Bad Idea(tm) (just think what that does to
argument list). Similar crap is triggerable with typedef. IMO, we really
ought to reject _that_ - not only 6.9.1(2) explicitly requires that, but
there's no even remotely sane way to deal with arguments.
4)
static void f(void);
...
void f(void);
triggers "warning: symbol 'f' was not declared. Should it be static?"
which is at least very confusing - it *is* declared and it *is* static.
IOW, we do not collect the linkage information sanely. (2) will make
fixing that one very interesting.
Anyway, proposed patch for (1) follows:
Subject: [PATCH] Handle mix of declarations and definitions
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Christopher Li <sparse@chrisli.org>