| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
| |
The change started from Bernd Petrovitsch's patch but
get mostly rewritten using accociatived array.
It fix the modifier_string() function and check the string
length for the string.
Signed-off-by: Christopher Li <sparse@chrisli.org>
Signed-off-by: Bernd Petrovitsch <bernd@sysprog.at>
|
|
|
|
|
| |
Signed-off-by: Bernd Petrovitsch <bernd@sysprog.at>
Signed-off-by: Christopher Li <sparse@chrisli.org>
|
|
|
|
|
|
|
|
|
|
| |
GCC provides a 128 bit type called internally as TImode (__int128_t)on 64 bit
platforms (at least x86_64 and Sparc64). These types are used by OpenBIOS.
Add support for types "long long long", __mode__(TI) and __(u)int128_t.
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Christopher Li <sparse@chrisli.org>
|
|
|
|
| |
Signed-off-by: Alexey Zaytsev <alexey.zaytsev@gmail.com>
|
|
|
|
|
|
| |
Signed-off-by: David Given <dg@cowlark.com>
[negative value division fixed by alexey.zaytsev@gmal.com]
Signed-off-by: Alexey Zaytsev <alexey.zaytsev@gmail.com>
|
|
|
|
|
|
|
|
|
|
|
|
| |
* postfix stuff had been applied in wrong order (e.g. int a[2][3] generated
int [addressable][toplevel] a[3][2])
* after fixing that, we've no need for recursion anymore, a bunch of arguments
go away and turn into local variables and we get an easy way to get rid of
bogus space in the show_typename() result.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
[Josh: fix test suite to match]
Signed-off-by: Josh Triplett <josh@kernel.org>
|
|
|
|
|
|
|
|
|
| |
* 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>
|
|
|
|
|
|
| |
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
[Josh: update test suite to match output changes.]
Signed-off-by: Josh Triplett <josh@freedesktop.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
| |
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
| |
For inline functions, Sparse inlines the function body at evaluation. It is
very hard to find out the original function call. This change preserves the
original call as an annotation.
Signed-Off-By: Christopher Li <sparse@chrisli.org>
|
|
|
|
|
|
|
|
| |
I found it very useful for debug_symbol to show the builtin
type name.
Signed-off-by: Christopher Li <sparse@chrisli.org>
Signed-off-by: Josh Triplett <josh@freedesktop.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>
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
| |
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
|
|
|
|
| |
This patch add static declare to make sparse happy of checking itself.
|
| |
|
|
|
|
|
|
| |
Much prettier than "input_streams[x].name", since most
users really don't want to know about the internals of
how the preprocessor lays out its stream tracking.
|
|
|
|
|
|
|
|
|
| |
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
|
| |
|
|
|
|
|
|
|
|
|
| |
I used to think I needed it. That's no longer the case: we just
follow the "bit_offset" in the type information.
There may be cases where we inadvertently cast the information
away, and those places will break now, but that's a bug really,
not an excuse for EXPR_BITFIELD.
|
|
|
|
|
|
| |
This also makes our evaluation simplification only happen
for the implied ones. If you put an explicit cast somewhere,
it does _not_ get combined with an implied one.
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
| |
We turn it into a proper (tmp = x, tmp ? tmp : y) at evaluation
time, so later phases never have to worry about the issue. But
some of the old code lingered.
|
|
|
|
|
|
|
|
|
|
| |
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).
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
| |
Use FOR_EACH_PTR() instead, or the much fancier iterators
for basic blocks.
|
|
|
|
|
| |
It just ends up propagating the expression to the linearizer,
which creates an internal "context" instruction for it.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
returns the size of the underlying object.
This is different from "sizeof(*expr)" for arrays, where
the array would degenerate to a pointer to one member, and
thus "sizeof(*expr)" gives the size of one entry in the
array.
Why do this? It's useful for things like
#define memset(a,b,c) ({ \
(void) __builtin_warning(__sizeof_ptr__(a) > 1, __sizeof_ptr__(a) != (c), "check memset size"); \
memset(a, b, c); })
where we really want to check the size of the object we're
doing the "memset()" on, but the regular sizeof() just doesn't
cut it.
|
|
|
|
| |
Since our enum's can have strange types, we should show them.
|
|
|
|
|
| |
It got corrupted when we added more symbol types and moved
things around.
|
|
|
|
|
|
| |
We've converted them to anonymous symbols of type "array of char"
earlier, but we don't actually want to _show_ them as symbols,
we want to show them as the string.
|
|
|
|
| |
Again, this allows us to continue past errors.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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).
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
| |
Make "label_type" be a real ctype, rather than an uninitialized
mess.
|
|
|
|
|
|
| |
..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 non-lvalue compound objects:
We introduce a new primitive - EXPR_SLICE. Meaning is "that many bits
from that offset in that non-lvalue struct or union". It is used when
we try to get a member out of a non-lvalue struct or union (subsequent .<field>
just narrow the slice). And as far as scalar, struct and union fields count,
that's it. The only subtle point is handling of array fields. And there
I'm doing what C99 requires - they *do* decay to real, honest pointers,
causing a copy of object to memory if needed. We get an anonymous object
that lives until the next sequence point; optimizer is certainly free to
get rid of it completely if it can make do with the value we'd copied there.
Note that you _are_ allowed to say
foo().a[1] = 0;
It doesn't make sense, since the value you've assigned will be immediately
lost (and any optimizer will turn that into f()), but it is legitimate and
it avoids a *lot* of PITA in describing semantics.
It covers only array decay - any other member of non-lvalue struct or union
is *not* an lvalue and in
struct foo {int x; int y[2];};
struct foo a(void);
...
a().x = 0; /* not allowed, non-lvalue */
a().y[0] = 1; /* allowed, but pointless */
you will get an error from the first assignment, but not from the second
one.
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]".
|
|
|
|
|
| |
Make linearize.h show the right ops for the logical (as opposed to
binary) and/or EXPR_BINOP.
|
|
|
|
|
|
|
|
|
| |
expression.
This is just a very high-level cost, mainly distinguishing
between "safe" and "unsafe" operations, so that we can
determine if we can turn a C conditional into a select
statement, or a logical op into one without short-ciruiting.
|
|
|
|
|
|
| |
It's the same as a regular C conditional, except you could
evaluate both sides first. Right now we treat it exactly
the same as an EXPR_CONDITIONAL.
|
|
|
|
| |
FP handling added, everything straightforward by now.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This teaches sparse what __alignof__ really means, instead of just using
the same code as "__sizeof__"
It gets rid of the warnings in ebtables that does:
struct ebt_entries {
...
char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)));
};
Which caused warning because sparse was evaluating __alignof__ as the same as sizeof,
and sizeof was 57 (ie non-power of 2).
This is just based on the existing code and a peek at the data
structures in expression and symbol.
|