| Age | Commit message (Collapse) | Author | Files | Lines |
|
They describe how likely the function is to be executed, which can
affect optimization. Also ignore the attributes with underscores.
Signed-off-by: Pavel Roskin <proski@gnu.org>
|
|
This adds -W[no-]declaration-after-statement, which makes warnings about
declarations after statements a command-line option. (The code to implement
the warning was already in there via a #define; the patch just exposes it
at runtime.) Rationale: C99 allows them, C89 doesn't.
Signed-off-by: Geoff Johnstone <geoff.johnstone@googlemail.com>
|
|
This patch enables a very simple form of conditional context tracking,
namely something like
if (spin_trylock(...)) {
[...]
spin_unlock(...);
}
Note that
__ret = spin_trylock(...);
if (__ret) {
[...]
spin_unlock(...);
}
does /not/ work since that would require tracking the variable and doing
extra checks to ensure the variable isn't globally accessible or similar
which could lead to race conditions.
To declare a trylock, one uses:
int spin_trylock(...) __attribute__((conditional_context(spinlock,0,1,0)))
{...}
Note that doing this currently excludes that function itself from context
checking completely.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
|
|
The sparse man page promises that it will check this:
Functions with the extended attribute
__attribute__((context(expression,in_context,out_context))
require the context expression (for instance, a lock) to have the
value in_context (a constant nonnegative integer) when called,
and return with the value out_context (a constant nonnegative
integer).
It doesn't keep that promise though, nor can it, especially with
contexts that can be acquired recursively (like RCU in the kernel.)
This patch makes sparse track different contexts, and also follows
up on that promise, but with slightly different semantics:
* the "require the context to have the value" is changed to require
it to have /at least/ the value if 'in_context',
* an exact_context(...) attribute is introduced with the previously
described semantics (to be used for non-recursive contexts),
* the __context__ statement is extended to also include a required
context argument (same at least semantics),
Unfortunately, I wasn't able to keep the same output, so now you'll
see different messages from sparse, especially when trying to unlock
a lock that isn't locked you'll see a message pointing to the unlock
function rather than complaining about the basic block, you can see
that in the test suite changes.
This patch also contains test updates and a lot of new tests for the
new functionality. Except for the changed messages, old functionality
should not be affected.
However, the kernel use of __attribute__((context(...)) is actually
wrong, the kernel often does things like:
static void *dev_mc_seq_start(struct seq_file *seq, loff_t * pos)
__acquires(dev_base_lock)
{
[...]
read_lock(&dev_base_lock);
[...]
}
rather than
static void *dev_mc_seq_start(struct seq_file *seq, loff_t * pos)
__acquires(dev_base_lock)
{
[...]
__acquire__(dev_base_lock);
read_lock(&dev_base_lock);
[...]
}
(and possibly more when read_lock() is annotated appropriately, such
as dropping whatever context read_lock() returns to convert the context
to the dev_base_lock one.)
Currently, sparse doesn't care, but if it's going to check the context
of functions contained within another function then we need to put the
actual __acquire__ together with acquiring the context.
The great benefit of this patch is that you can now document at least
some locking assumptions in a machine-readable way:
before:
/* requires mylock held */
static void myfunc(void)
{...}
after:
static void myfunc(void)
__requires(mylock)
{...}
where, for sparse,
#define __requires(x) __attribute__((context(x,1,1)))
Doing so may result in lots of other functions that need to be annoated
along with it because they also have the same locking requirements, but
ultimately sparse can check a lot of locking assumptions that way.
I have already used this patch and identify a number of kernel bugs by
marking things to require certain locks or RCU-protection and checking
sparse output. To do that, you need a few kernel patches which I'll
send separately.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
|
|
* don't crap the type->ident for unsigned int just because somebody did
typedef unsigned int x;
only structs, unions, enums and restricted types need it.
* generate saner warnings for restricted, include type name(s) into them.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
|
|
This avoids error messages like this:
error: attribute 'malloc': unknown attribute
Signed-off-by: Emil Medve <Emilian.Medve@Freescale.com>
|
|
This patch fix the sparse breakage triggered by
rcu_read_lock() lockdep annotations.
Now sparse look up the local label in symbol node
name space as well, just like looking up a normal
symbol node. Now a lable symbol can be both
type SYM_LABEL or SYM_NODE with MOD_LABEL.
Singed-Off-By: Christopher Li <sparse@chrisli.org>
|
|
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
|
|
Adding va_end().
Signed-off-by: Richard Knutsson <ricknu-0@student.ltu.se>
|
|
This adds a field in the symbol struct for the position of the end of the
symbol and code to parse.c to fill this in for the various symbol types when
parsing.
Signed-off-by: Rob Taylor <rob.taylor@codethink.co.uk>
|
|
Turn FORCE_MOD into storage class specifier (that's how it's
actually used and that makes for much simpler logics).
Introduce explicit EXPR_FORCE_CAST for forced casts; handle it
properly.
Kill the idiocy in get_as() (we end up picking the oddest things
for address space - e.g. if we have int __attribute__((address_space(1))) *p,
we'll get warnings about removal of address space when we do things like
(unsigned short)*p. Fixed. BTW, that had caught a bunch of very odd
bogosities in the kernel and eliminated several false positives in there.
As the result, get_as() is gone now and evaluate_cast() got simpler.
Kill the similar idiocy in handling pointer assignments; while we are at it,
fix the qualifiers check for assignments to/from void * (you can't assign
const int * to void * - qualifiers on the left side should be no less than
on the right one; for normal codepath we get that checked, but the special
case of void * skips these checks).
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
|
|
The -Wdefault-bitfield-sign is supposed to control a warning, just like
other -W options.
Signed-off-by: Pavel Roskin <proski@gnu.org>
|
|
Hopefully correct handling of integer constant expressions. Please, review.
Rules:
* two new flags for expression: int_const_expr and float_literal.
* parser sets them by the following rules:
* EXPR_FVALUE gets float_literal
* EXPR_VALUE gets int_const_expr
* EXPR_PREOP[(] inherits from argument
* EXPR_SIZEOF, EXPR_PTRSIZEOF, EXPR_ALIGNOF get int_const_expr
* EXPR_BINOP, EXPR_COMPARE, EXPR_LOGICAL, EXPR_CONDITIONAL,
EXPR_PREOP[+,-,!,~]: get marked int_const_expr if all their
arguments are marked that way
* EXPR_CAST gets marked int_const_expr if argument is marked
that way; if argument is marked float_literal but not
int_const_expr, we get both flags set.
* EXPR_TYPE also gets marked int_const_expr (to make it DTRT
on the builtin_same_type_p() et.al.)
* EXPR_OFFSETOF gets marked int_const_expr
When we get an expression from parser, we know that having int_const_expr on
it is almost equivalent to "it's an integer constant expression". Indeed,
the only checks we still have not done are that all casts present in there
are to integer types, that expression is correctly typed and that all indices
in offsetof are integer constant expressions. That belongs to evaluate_expression()
and is easily done there.
* evaluate_expression() removes int_const_expr from some nodes:
* EXPR_BINOP, EXPR_COMPARE, EXPR_LOGICAL, EXPR_CONDITIONAL,
EXPR_PREOP: if the node is marked int_const_expr and some
of its arguments are not marked that way once we have
done evaluate_expression() on them, unmark our node.
* EXPR_IMLICIT_CAST: inherit flags from argument.
* cannibalizing nodes in *& and &* simplifications: unmark
the result.
* EXPR_CAST: unmark if we are casting not to an integer type.
Unmark if argument is not marked with int_const_expr after
evaluate_expression() on it *and* our node is not marked
float_literal (i.e. (int)0.0 is fine with us).
* EXPR_BINOP created (or cannibalizing EXPR_OFFSETOF) by
evaluation of evaluate_offsetof() get int_const_expr
if both arguments (already typechecked) have int_const_expr.
* unmark node when we declare it mistyped.
That does it - after evaluate_expression() we keep int_const_expr only if
expression was a valid integer constant expression.
Remaining issue: VLA handling. Right now sparse doesn't deal with those in
any sane way, but once we start handling their sizeof, we'll need to check
that type is constant-sized before marking EXPR_SIZEOF int_const_expr.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
|
|
mark symbols for enum members, have primary_expression() copy their
->initializer instead of dancing through the EXRP_SYMBOL with
expand_expression() finally getting to the damn thing.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
|
|
get a linked list through fields of struct, skipping unnamed bitfields.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
|
|
Signed-off-by: Josh Triplett <josh@freedesktop.org>
|
|
Signed-off-by: Josh Triplett <josh@freedesktop.org>
|
|
Signed-off-by: Josh Triplett <josh@freedesktop.org>
|
|
Signed-off-by: Josh Triplett <josh@freedesktop.org>
|
|
Signed-off-by: Josh Triplett <josh@freedesktop.org>
|
|
Signed-off-by: Josh Triplett <josh@freedesktop.org>
|
|
In particular, the following identifiers (along with their __X__ variants)
are now accepted as attribute names: fastcall, dllimport and dllexport.
(cdecl and stdcall were added in baf2c5a84e by Michael Stefaniuc).
For now, at least, these attributes are just ignored.
Signed-off-by: Ramsay Jones <ramsay@ramsay1.demon.co.uk>
[josh: modified to fix whitespace damage]
Signed-off-by: Josh Triplett <josh@freedesktop.org>
|
|
The test case for this was abstracted from an example in the "expat.h" header
file:
typedef void (__attribute__((__cdecl__)) *FP)(void *u, const char *n);
void set_FP(void *cb, FP f);
Signed-off-by: Ramsay Jones <ramsay@ramsay1.demon.co.uk>
[josh: modified to apply to current Sparse]
Signed-off-by: Josh Triplett <josh@freedesktop.org>
|
|
Signed-off-by: Josh Triplett <josh@freedesktop.org>
|
|
Wine uses the __stdcall__ attribute extensively. The effects of the
patch on a sparse run on the Wine code are:
- Removes 143000 "attribute '__stdcall__': unknown attribute" errors.
- Removes 116 "attribute '__cdecl__': unknown attribute" errors.
- Reduces the amount of "error: too many errors" from 1992 to 1459.
Signed-off-by: Michael Stefaniuc <mstefani@redhat.com>
|
|
The reason I use bitmask in the keyword so that it can allow the caller
to select a sub set of keywords. If we want, we can fine tune exactly
what keyword is allowed. It also makes the caller of handle_attributes
show exactly what kind of attribute it takes.
[original patch]
Signed-Off-By: Christopher Li <sparse@chrisli.org>
[type fix]
Signed-off-by: Josh Triplett <josh@freedesktop.org>
|
|
Commit aec53c938c34c47cdbdd6824552e0f2a5104b1cb, "handle label attributes",
caused sparse to parse asm after a label as an attribute, not a statement.
Fix this by adding a new allow_asm flag to handle_attributes, and passing 0
when parsing label attributes. Expand validation/asm-volatile.c to include
the test case that demonstrated this bug.
Thanks to Randy Dunlap for reporting the problem.
Signed-off-by: Josh Triplett <josh@freedesktop.org>
|
|
Signed-off-by: Josh Triplett <josh@freedesktop.org>
|
|
On Fri, Mar 23, 2007 at 03:04:59PM -0700, Randy Dunlap wrote:
> 1. net/sched/cls_api.c, lines 593-611:
>
> return 0;
> rtattr_failure: __attribute__ ((unused))
> return -1;
> }
Signed-Off-By: Christopher Li<sparse@chrisli.org>
Signed-off-by: Josh Triplett <josh@freedesktop.org>
|
|
pthreads from glibc 2.5 uses __attribute__ ((__regparm__ (1)) on some
functions (indirectly through the macro __cleanup_fct_attribute). Sparse
already parsed and ignored regparm, but not __regparm__.
Signed-off-by: Josh Triplett <josh@freedesktop.org>
|
|
Expose the FORMAT_ATTR portability macro in lib.h, and use it on the various
printf-like functions in sparse.
Add a new SENTINEL_ATTR portability macro for the GCC sentinel attribute, and
use it on match_idents in parse.c.
match_oplist in expression.c should use SENTINEL_ATTR, but GCC does not accept
an integer 0 as a sentinel, only a pointer 0 like NULL.
Signed-off-by: Josh Triplett <josh@freedesktop.org>
|
|
Signed-off-by: Josh Triplett <josh@freedesktop.org>
|
|
Now we are really parsing the attribute rather than building the
expression tree first.
Signed-Off-By: Christopher Li <sparse@chrisli.org>
Signed-off-by: Josh Triplett <josh@freedesktop.org>
|
|
Signed-Off-By: Christopher Li <sparse@chrisli.org>
Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Josh Triplett <josh@freedesktop.org>
|
|
This change using keyword lookup for statement parsing
instead of a order compare.
Signed-Off-By: Christopher Li <sparse@chrisli.org>
Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Josh Triplett <josh@freedesktop.org>
|
|
This change using symbol_op to contain the specifier parsing
function. It is easier to add new specifiers. We don't need
special bits any more.
Signed-Off-By: Christopher Li <sparse@chrisli.org>
Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Josh Triplett <josh@freedesktop.org>
|
|
This is the preparation step for the keyword table driven
parsing. Those statement parsing function will later
turn into function call back.
The patch should not introduce any functional changes.
Signed-Off-By: Christopher Li <sparse@chrisli.org>
Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Josh Triplett <josh@freedesktop.org>
|
|
Pavel Roskin manage to hit this bug with
struct st {
char c;
} __attribute__ ((aligned(2)));
struct st s1;
struct st s2;
Signed-Off-By: Christopher Li <sparse@chrisli.org>
|
|
Pavel discovered this test case:
void test(void)
{
struct { int foo;; } val;
memset(&val, 0, sizeof(val));
}
That generates this warning:
test.c:5:8: warning: memset with byte count of 0
Sparse ends up creating a node with empty ctype in the member list. Avoid
doing that, which eliminates the warning.
Signed-Off-By: Christopher Li<spase@chrisli.org>
|
|
struct __attribute__((__aligned__(16))) foo {
int a;
};
Signed-Off-By: Christopher Li <sparse@chrisli.org>
|
|
This patch delay the finalized of the abstract int type so it
can take the __attribute__ in the end of declaration.
It complicate the bit field parsing because abstract type can
show up in the base type of bit field.
Signed-off-by: Christopher Li <sparse@chrisli.org>
|
|
They are equivalent to "alias" and "visibility" except that gcc won't
complain about them in ANSI programs.
Original patch from Pavel Roskin, modified by Josh Triplett.
Signed-off-by: Josh Triplett <josh@freedesktop.org>
Signed-off-by: Pavel Roskin <proski@gnu.org>
|
|
git://git.kernel.org/pub/scm/linux/kernel/git/viro/sparse
|
|
Does it necessarily make sense? Dunno, but it does tend to be bad
practice, or at least result in code that can be hard to mentally parse.
Maybe that mental parsing is just me. Or maybe it should be warned
about. You decide.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
|
|
This stuff comes from handling smaller-than-int bitwise types (e.g. __le16).
The problem is in handling things like
__be16 x, y;
...
if (x == (x & ~y))
The code is bitwise-clean, but current sparse can't deduce that. Operations
allowed on bitwise types have the following property: (type)(x <op> y) can
be substituted for x <op> y in any expression other than sizeof. That allows
us to ignore usual arithmetical conversions for those types and treat e.g.
| as __be16 x __be16 -> __be16, despite the promotion rules; resulting
semantics will be the same. However, ~ on smaller-than-int does not have
such property; indeed, ~y is guaranteed to _not_ fit into range of __be16
in the example above.
That causes a lot of unpleasant problems when dealing with e.g. networking
code - IP checksums are 16bit and ~ is often used in their (re)calculations.
The way to deal with that is based on the observation that even though we do
get junk in upper bits, it normally ends up being discarded and sparse can
be taught to prove that. To do that we need "fouled" conterparts for short
bitwise types. They will be assigned to (sub)expressions that might carry
junk in upper bits, but trimming those bits would result in the value we'd
get if all operations had been done within the bitwise type. E.g. in the
example above y would be __be16, ~y - fouled __be16, x & ~y - __be16 again
and x == (x & ~y) - boolean.
Basically, we delay reporting an error on ~<short bitwise> for as long as
possible in hope that taint will be cleansed later. Exact rules follow:
* ~short_bitwise => corresponding fouled
* any arithmetics that would be banned for bitwise => same warning
as if we would have bitwise
* if t1 is bitwise type and t2 - its fouled analog, then
t1 & t2 => t1, t1 | t2 => t2, t1 ^ t2 => t2.
* conversion of t2 to t1 is silent (be it passing as argument
or assignment). Other conversions are banned.
* x ? t1 : t2 => t2
* ~t2 => t2 (_not_ t1; something like ~(x ? y : ~y) is still fouled)
* x ? t2 : t2 => t2, t2 {&,|,^} t2 => t2 (yes, even ^ - same as before).
* x ? t2 : constant_valid_for_t1 => t2
* !t2 => warning, ditto for comparisons involving t2 in any way.
* wrt casts t2 acts exactly as t1 would.
* for sizeof, typeof and alignof t2 acts as promoted t1. Note that
fouled can never be an lvalue or have types derived from it - can't happen.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
|
|
sparse currently only tracks one global context for __context__ and
__attribute__((context)).
This adds support for parsing an additional argument to each of these
which gives a context expression. For __attribute__((context)), store
each context attribute as a separate context structure containing the
expression, the entry context, and the exit context, and keep a list of
these structures in the ctype. For __context__, store the context
expression in the context instruction. Modify the various frontends to
adapt to this change, without changing functionality.
This change should not affect parsing of programs which worked with
previous versions of sparse, unless those programs use comma expressions
as arguments to __context__ or __attribute__((context)), which seems
highly dubious and unlikely. sparse with -Wcontext generates identical
output with or without this change on Linux 2.6.18-rc4.
Signed-off-by: Josh Triplett <josh@freedesktop.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
|
|
Ignore the GCC attributes no_instrument_function and
__no_instrument_function__, used to turn off instrumentation for a particular
function when using GCC's -finstrument-functions option.
Signed-off-by: Josh Triplett <josh@freedesktop.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
|
|
This makes sparse ignore the "sentinel" attribute.
Signed-off-by: Morten Welinder <terra@gnome.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
|
|
This removes the list of symbols for block statements, and instead makes
a declaration be a statement of its own.
This is necessary to correctly handle the case of mixed statements and
declarations correctly, since the order of declarations and statements
is meaningful.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
|
|
NS_STRUCT symbol gets it's ->pos from alloc_symbol(), it
could be called when sparse sees struct's forward declaration.
This patch ensures that ->pos identifies position where this
struct/union is actually defined.
Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
|
|
Make the warnings about one-bit signed bitfields conditional; default is
the old behaviour
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
|
|
We can have multiple parameters declared with the same base declaration.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
|
|
Mitesh Shah (and others) report that broken libc's will have their own
"error()" that the sparse naming clashes with.
So use a sed-script to rewrite all the occurrences.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
|
|
The K&R argument parsing was a quick hack, and horribly buggy. Because
it used external_declaration() to parse the argument, it bound the name
of the argument at totally the wrong scope.
Noted by Mitsh Shah.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
|
|
The type of an enum is determined by the type of all of its entries,
which means that while we may parse it in one type, it might end up with
another type in the end. We used to just switch the types around, but
that didn't properly upgrade the actual values to the new type.
The trivial fix is to just keep a list of entries around, and then go
back and cast the values at the end.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
|
|
We do enum type handling in two passes: one while parsing the values,
and then afterwards we determine the final type that depends on the
range of the results.
Make sure that the intermediate stages keep the intermediate types big
enough to cover the full range.
(The final type-casting is also buggy, but that's a separate issue)
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
|
|
This replaceq calls to warning() with error() at places where (I think)
the gcc reports an error. Also added a global variable die_if_error
which is set if there is one or more errors. If someone wants to stop
processing further, can check for the variable.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
|
|
We used to get "__user void *" wrong - it ended up with address space 0
instead of address space 1.
What happens is actually pretty simple - we get address_space(1) handled
in declaration_specifiers(), which sets ctype->as to 1. Then we see
"void" and eventually get to
ctype->base_type = type;
}
check_modifiers(&token->pos, s, ctype->modifiers);
apply_ctype(token->pos, &thistype, ctype);
with thistype coming from lookup for "void". And that, of course, has
zero ->as. Now apply_ctype merrily buggers ctype->as and we have 0...
So AFAICS proper fix for sparse should be to check thistype->as to see
if it really has any intention to change ->as.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
|
|
In case of malformed enum definition:
enum E {};
the error will be reported from examine_symbol_type(),
this could be very confusing.
Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
|
|
Incomplete enum type has ->ctype.base_type == NULL, so almost any
usage of it segfaults in is_int_type(), example:
enum E *p;
*p == 0;
It is not possible (and wrong) to fix only the is_int_type(), we
also need valid ->base_type in integer_promotion, get_sym_type, etc.
This patch also "fixes" false error message:
The code:
extern enum E e;
static void *p = &e;
output:
enum.c:1:13: warning: invalid enum type
Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
|
|
This also simplifies the code - don't bother to make it look like a real
function.
Bug pointed out by Oleg Nesterov.
|
|
Instead of having a special case for "post_condition == pre_condition",
make a NULL post_condition mean that it's the same as the pre-condition.
That's how while/for loops work anyway.
This avoids the double warnings for conditionals that Oleg Nesterov
noted.
|
|
Code:
atomic_t v;
v.xxxx = 0;
without patch:
warning: no member 'xxxx' in struct <unnamed>
with patch:
warning: no member 'xxxx' in struct atomic_t
Actually I want this patch because I started the simple libsparse
client, and I don't see the simple way to resolve SYM_STRUCT's
name in typedef case.
Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
|
|
This actually seems to do some sane things when parsing even complex
multiple files. In particular, it actually works right when used for
multiple kernel C files together in limited testing.
|
|
Avoid deferencing a null pointer after parse errors in array designated
initializer.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@looxix.net>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
|
|
Here's a patch that adds stubs for several attributes used in userland.
This version of the patch includes a warning, which defaults to on, if
you use gcc's "transparent_union" attribute, and has a flag
(-Wno-transparent-union) to turn the warning off.
|
|
And, like others, ignore it for now.
Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
|
|
The fix by Linus was half-assed, since it wasn't *p that was NULL, but
'p' itself. Fix it for real this time.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@looxix.net>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
|
|
Noted by Luc Van Oostenryck.
|
|
This patch add static declare to make sparse happy of checking itself.
|
|
Suggested by Bernhard Fischer
|
|
This adds the function name to the warning about 'function with external
linkage has definition'.
This saves me from having to open the file in order to look up the
function name. When the name is printed, i can quickly grep for
possibly other occurances.
|
|
This removes SYM_ENUM as a special case for symbol handling, and
makes it possible to follow the types much better.
|
|
|
|
we did the real definition.
It may have been declared and used as a pointer before.
|
|
|
|
Another gcc format thing...
|
|
The asm_inputs/outputs "expression list" is not really an
expression list any more: it is a list of "triples", where
the first entry is the identifier name, the second one is
the constraint string, and the third one is the expression.
|
|
That makes sparse unhappy if the base type has already been set by
other parts of the declaration - it will refuse to mix base types.
Problem reported by Santtu Hyrkk�
|
|
never actually parsed the string itself properly. Fix it up.
|
|
The named parameter thing is still unsupported. And the format we save
things into is for simple saving rather than real usability.
|
|
It's disgusting how intimate lib.c is with all the types,
and this is slowly trying to split things up a bit. Now
the intimate part is in allocate.c, but maybe we can get
to the point where each allocation user just declares its
own allocation strategy, and just uses the generic routines
in allocate.c
|
|
We don't actually support the crap. Some of it happens to
kind of do the same thing, but we should warn loudly. In
the meantime, it allows more of the gcc testsuit things to
show _real_ problems.
|
|
Currently we warn unconditionally about it.
|
|
|
|
Not only do all users want it, the list of used symbols
is not stable until after the tree has been evaluated.
|
|
from the base type.
This fixes some code that checks the sign of the node
instead of on the base type.
|
|
It's always the same as bit_size now, and having it just confuses
things.
We now check whether we have examined a type by looking at the
"examined" bitfield, which allows us to set bit_size in the early
parsing phase.
|
|
in type evaluation.
This avoids a lot of special cases later on, and makes the
error messages more readable anyway.
We re-use the old "bad_enum_ctype" for this, and just make
it more generic (and rename it).
|
|
case statement which is not in switch scope.
|
|
This way we can have multiple of them, and they
add up correctly.
|
|
It's a way of telling the checker what the input context count is
expected to be, and what the output context should be.
For example, a function that is expected to be called with a spinlock
held, and releases that lock, could have an in_context of 1, and an
out_context of 0.
|
|
It just ends up propagating the expression to the linearizer,
which creates an internal "context" instruction for it.
|
|
Since bind_symbol() now sets it, we don't need to set it by
hand any more.
Also, we really don't need to pass a pointer to a symbol
pointer in the declarator parsing functions, since they
never change it, and depend on it being set anyway. Might
as well just pass in the direct pointer to the symbol
instead.
|
|
We should only look at the value range if not all value
types agree.
|
|
way, and give them a real string.
This means that __func__ actually works as a constant string,
not as a pseudo-symbol, which is wrong. But hey, sue me.
|
|
Will someone please dispatch a firing squad to gcc HQ?
|
|
The current gcc initializer code is too permissive, AFAICS - [0][0] 1
will be rejected by gcc too, so we shouldn't consider it "broken gcc syntax".
There was another bug in there -
*ep = NULL;
token = initializer(ep, token);
if (!expr)
break;
add_expression(list, expr);
would not catch the case when we have e.g. .foo = <bad expression> and we
end up with list polluted by EXPR_IDENTIFIER with NULL ->ident_expression.
Should be if (!*ep) instead.
This also cleans it up by splitting the list handling case up from the
loop, and making the single initializer parsing a function of its own.
|
|
Teach sparse to ignore the "model" (aka "__model__") attribute used by
ia64 linux.
Signed-off-by: davidm@hpl.hp.com
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
|
|
Most of the kernel ones have long since been converted. This might
help convert the last few hold-outs.
|
|
specifiers.
They now parse the same way as __attribute__ node-specifiers. This
simplifies the code, and makes sparse not care about random gcc
rules for exactly where one or the other can be placed.
|
|
a) we allow enum have an equivalent type other than int (it is kept in
->ctype.base_type for SYM_ENUM types). Code adjusted.
b) enum declaration parsing tries to determine the equivalent type; if
such type does not exist we set it to &bad_enum_ctype and
examine_symbol_type() generates a warning when it meets such beast.
The rules for equivalent type follow:
1) if all members have the same bitwise type, it is the
equivalent type of enum.
2) if all members have integer types and there is a single
integer type capable of representing all their values, we pick
the first such type (in the same ordering that is used for e.g.
integer constants).
3) anything else => bad_enum_ctype.
c) enum is compatible with its equivalent type.
d) it is an error to have implied initializer for a member following
that of bitwise type.
There are still issues with float in enums, but since gcc would choke on
those unconditionally, we can be sure that there's no instances in any
code we could deal with (unless we start playing with Plan 9 codebase,
and that would require more work in other places - float enum is not the
only C extension in there). Separate patch...
|
|
they got initialized with.
This is not how standard C works. 'enum's are normally
just integers. Tough.
|
|
positional markers be hierarchical rather than a flat list.
This makes the data structure a bit more complex, but it simplifies
some of the code, and makes it possible to evaluate complex initializers
without going insane.
In particular, we how support
struct xxxx var = {
.a.b[10] = 1;
};
which we couldn't handle at all before (it had to
be written as
struct xxxx var = {
.a = {
.b = { [10] = 1; }
}
}
or similar.
The new code changes all array indexes and structure members
to EXPR_POS expressions offset from the "outer" scope (either
start of the symbol, or an outer EXPR_POS).
|
|
This just parses them, we don't actually handle them correctly
afterwards. One step at a time.
|
|
warn->warning
error->error_die
new error
lib.h:
warn->warning
error->error_die
new error
Add gcc format checking to warning/error/...
|
|
Add s(char|short|int|long|longlong)_ctype.
show-parse.c:
Print "signed" as part of the type names when needed.
parse.c:
Add separate ctypes for signed char, short, int, long, and long long.
Make ctype_integer pick the explicitly signed type as needed.
|
|
Warn for "int foo (...);".
|
|
..and switch us entirely over to the new naming scheme.
All the nasty work of going through the users thanks to Chris Li.
|
|
Handling of __attribute__((bitwise)) in a way that should be easy to extend
afterwards. Example of use:
typedef __u32 __attribute__((bitwise)) __le32;
That will create a new 32bit type that will be assignment-incompatible with
anything else. The set of allowed operations is restricted to bitwise ones,
the only allowed constant is 0 right now. Forced casts are allowed, so is
cast from type to itself and cast to void. Any other cast will give a warning.
Checks are triggered by -Wbitwise in command line; if it's not there,
attribute will be silently ignored.
|
|
* handling of bitfields taken to a helper function.
* reading and handling list of attributes taken to a helper function.
* caller became readable...
|
|
When we take the address of an inline function or otherwise refusing to
inline it, we need to output the now non-inline function properly.
What we do is
a) keeping body and symbol list of inlined function in new fields
b) when expanding inlined call use these fields
c) when evaluating the function itself (which happens if sparse
decides that it can't be [always] inlined) uninline the sucker. I.e.
create ->stmt and ->symbol_list by copying the ->inline_stmt and
->inline_symbol_list same as we would do while expanding a call.
That guarantees that we won't run into trouble with inlined calls coming
afterwards - evaluation doesn't mangle ->inline_stmt anymore.
|
|
Identifiers are unique objects, so we can just compare the pointers
directly, if we just set up the identifiers first.
Identifier setup simplified as suggested by Linus.
|
|
From Dave Jones <davej@redhat.com>.
|
|
declarations.
Complain about extraneous bogus declarations, and make
a better warning for missing ones.
|
|
My silly test file was a bit _too_ simple, and missed the
fact that the parser would have missed the first token in
the function body ;)
|
|
We used to require the "void" thing, but if we parse
K&R we can no longer do that. So just silently allow
an empty parameter type list.
|
|
I didn't even realize that K&R allowed the declaration of the
types to be in a different order than the arguments themselves.
Anyway, that's easy to handle, although we should probably also
check that we don't declare some name that doesn't exist.
|
|
char/short types promote to "int" in K&R function declarations.
|
|
Hey, this is still wrong. A "char" should be promoted
to "int" etc, and we don't do that. So it's kind of
half-K&R, half-ANSI.
|
|
HOWEVER! We don't actually go and apply the types to the
arguments yet, so this is purely a "parse only" fix. To
actually make K&R functions work, we'd need to match up
the re-declared arguments against the argument list.
All the information is there now, though. Somebody more
interestedin K&R could fix it up.
|
|
|
|
into troll.com:/scratch/welinder/sparse-for-linus
|
|
They are used by the Linux kernel for referring to assembler
symbols without a type (you can obviously only take the address
of such a symbol, not use it for anything else).
|
|
Check tags when naming tagged types.
This catches things like...
enum Foo { FOO };
struct Foo x;
|
|
have accepted them in the first place.
|
|
With help from Christopher Li <sparse@chrisli.org>.
|
|
|
|
|
|
Get the right signedness (which broke when the code moved here).
|
|
|
|
Found by Dave Jones and 'valgrind'.
|
|
|
|
|
|
Bitfields in structure declarations can have attributes; teach
parser to handle them.
Signed-off-by: Al Viro <viro@parcelfarce.linux.org.uk>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
|
|
Don't clear MOD_EXPLICITLY_SIGNED in indirect.\
symbol.c:
Add modifier MOD_EXPLICITLY_SIGNED to all versions of "signed".
check for integer bitfields that are just "int foo : 42".
symbol.h:
Define MOD_EXPLICITLY_SIGNED.
This will be used to distinguish "int" and "signed int".
show-parse.c:
Show MOD_EXPLICITLY_SIGNED as "[explicitly-signed]".
|
|
Move bitfield parsing into struct/union parsing where it belongs.
Sanity check bitfield widths.
|
|
Handle __noreturn__ as noreturn (==ignore).
|
|
Disallow "void" parameters and "void" variables.
|
|
Check that "signed", "unsigned", "long", ... only occur where they may.
Notably not as "signed double" or "long struct { ... }".
|
|
Check for multiple storage classes such as "static extern".
|
|
Lack of __word__ noted by Dave Jones.
|
|
This would be handy. ("visibility" is a linkage directive.)
|
|
Don't allow nonsensical type descriptions like
signed unsigned x;
short long x;
double x : 4;
int y : 1 : 2;
|
|
Associate them with each computed goto, and copy them properly
when inlining.
|
|
|
|
Add a few more predefined symbols, and handle "[argname]" syntax for
named inline assembler arguments.
|
|
|
|
Three small hunks:
- new builtin used on ia64 (__builtin_ffs())
- new attribute on ia64 (syscall_linkage)
- drop the -C from the install line, most people have a recent install
which dosn't have this...
|
|
the base type as NULL when no type is specified.
Traditional C makes the incomplete type be "int".
|
|
The non-underscore mode attribute strings should be understood
as well, this is actually used by some of the math emulation
library headers.
|
|
This will allow us to force certain type casts that would
be otherwise illegal (changing address space, for one).
|
|
allow just qualifiers.
|
|
|
|
type specifiers.
|
|
This adds __builtin_memset(), __builtin_stdarg_start() and recognition
of __attribute__((pure)) and __attribute__((always_inline))?
Another thing that is probably worth doing is shifting add_pre_buffer()
of #define __i386__ 1 to target.c, seeing that it is obviouslty
target-dependent ;-)
|
|
same declaration. Noticed by Al Viro.
Parsing something like
int i, __user *p;
used to fail.
This also cleans up some users that expanded "declarator()"
by hand.
|
|
values in pointer-to-pointer situations.
|
|
Prevents tons of attribute 'alias': unknown attribute warnings during a kernel build.
|
|
We parse them as a anonymous function with just an asm statement.
|
|
rename them lower cased to match standard C naming rules.
|
|
Cset exclude: torvalds@ppc970.osdl.org|ChangeSet|20040419183423|24692
|
|
Arrays are not first-class citizens in the C type
system, and a pointer to an array gets demoted to
just a pointer to the first entry.
|
|
We should not allow multiple type specifiers, even
of the same time (we used to silently accept "int int x;").
|
|
These are defined to never be NULL or nontrapping, and could
help code generation, but right now only cause a warning if
they are tested in a conditional.
|
|
|
|
This fixes a context attribute without mask/value expression,
and does a first pass at parsing the gcc __mode__ attribute.
|
|
This doesn't actually get them _right_, but as long as they
end up being constant when used, we at least silently ignore
them until then.
|
|
isn't the sole copyright owner these days.
|
|
member name. So instead of considering it "mixing of types",
just break the type lookup at that point.
|
|
ie make sure that we don't just go to the right place, but that we
also assign the return value to the return variable, and we make
inline functions evaluate properly to the value.
|
|
to get all the symbol replacement stuff right, we just build a
per-function list of all the symbols associated with a function
(except for arguments, which are special anyway due to the
site-specific initializers).
When we inline, we then create the replacement symbols up front,
which makes it trivial to replace them as needed. This means that
we get all the special symbols (return targets etc) automatically
right.
Also fix a few problems with builtin symbols that were uncovered
by the inliner when running over the kernel sources.
|
|
Make the argument declaration use a proper iterator loop, instead of
the old "symbol_iterate()" function pointer thing.
|
|
recognize. Most of them we just throw away, but we'll eventually
need to properly save away the information in the type.
|
|
"The compiler automatically sets the alignment for the
declared variable or field to the largest alignment which
is ever used for any data type on the target machine you
are compiling for"
So add the proper define to "target.h" and make it so.
|
|
|
|
|
|
|
|
to parse it as a type.
|
|
value symbols, of course.
Make the enum symbols have the SYM_ENUM type, and check that properly
at evaluate time (instead of checking the base type, which will be
an enum for regular enum variables too, of course).
|
|
(&&label) and computed goto (goto *expr).
Add label ctype for __label__ identifier. This is still quite broken
(it should create a block-symbol in the NS_LABEL namespace, right now
it creates a regular symbol).
|
|
|
|
into functions of their own. This will make the C99
'for' syntax handling cleaner.
Make 'statement()' static to parse.c.
|
|
|
|
Add a "case" symbol for the switch statement, to let the
statement keep track of all the cases. This cleans up handling
a lot.
|
|
preparing for a public release.
|
|
calculations).
|
|
close the scope properly at the end (we started a new one instead).
Make all non-static functions external.
And always check the declarator against previous symbols when finding
a new symbol. We want to verify that we don't have duplicates.
|
|
are static.
|
|
Parse break-statements inside switch-statements correctly.
Rename break/continue symbols to make switch/iterator statements
have the same naming logic for the break targets.
|
|
|
|
per-iterator anonymous symbols.
Make arrays also gracefully degenerate into "void *".
|
|
move the current attributes to the target of the pointer
(and clear them for the pointer itself).
|
|
show up inside the parse tree if they are actually used.
|
|
|
|
on typedefs.
|
|
this fixes it, and maybe it doesn't.
|
|
(as opposed to definitions) to the top-level symbol list.
|
|
of the full-file parse.
The declarations simply aren't useful to any back-end: they are
only useful as symbol definitions for the front-end to get the
right types, and they are thus better found through evaluation of
the parse tree than as nodes off the root.
|
|
information to the type, instead of throwing it away.
|