| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
| |
A follow up change to parse the wide char string.
It currently only parse and store it like normal strings.
Need more change to reflect the base type and size etc.
Signed-off-by: Christopher Li <sparse@chrisli.org>
|
|
|
|
|
|
|
|
|
| |
It is nasty that L'\0' start from an identifier letter. I try my best
not to slow down the hot path. The test is done inside get_one_identifier()
after the ident hash is built. It look a little bit out of palace but
faster than testing 'L' before hand.
Signed-off-by: Christopher Li <sparse@chrisli.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Keep storage class (and "is it inline") explicitly in decl_state;
translate to modifiers only when we are done with parsing. That
avoids the need to separate MOD_STORAGE bits while constructing
the type (e.g. in alloc_indirect_symbol(), etc.). It also allows
to get rid of MOD_FORCE for good - instead of passing it to typename()
we pass an int * and let typename() tell whether we'd got a force-cast.
Indication of force-cast never makes it into the modifier bits at all.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Christopher Li <chrisl@hera.kernel.org>
|
|
|
|
|
|
|
|
|
|
|
| |
There's no point whatsoever in constructing modifiers for chosen
type when decoding integer constant only to have them picked
apart by ctype_integer(). Seeing that the former is the only
caller of the latter these days, we can bloody well just pass
the rank and signedness explicitly and save a lot of efforts.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Christopher Li <chrisl@hera.kernel.org>
|
|
|
|
|
|
|
|
|
| |
sizeof (typename){initializers}.foo is nice and valid C99 - it's parsed
as sizeof primary.foo <- sizeof postfix.foo <- sizeof postfix <- sizeof unary
<- unary. Current type_info_expression() stops too early.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Christopher Li <sparse@chrisli.org>
|
|
|
|
|
|
|
|
|
| |
On "Syntax error in unary expression", the output parameter "tree" would be left
uninitialized and subsequently used in unary_expression(), leading to segfault.
Caught by valgrind and fixed by me ;-)
Signed-off-by: Vegard Nossum <vegardno@ifi.uio.no>
|
|
|
|
| |
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
|
|
|
|
| |
Signed-off-by: Richard Knutsson <ricknu-0@student.ltu.se>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
|
| |
Treat it as normal binary operation, taint the value, check the taint.
We can do other kind of value tainting with the same infrastructure
as well...
Review and testing would be welcome; AFAICS, it works, but...
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
| |
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>
|
|
|
|
| |
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
|
|
|
|
| |
Signed-off-by: Josh Triplett <josh@freedesktop.org>
|
|
|
|
|
|
|
| |
Remove two double inclusions.
Signed-off-by: Nicolas Kaiser <nikai@nikai.net>
Signed-off-by: Josh Triplett <josh@freedesktop.org>
|
|
|
|
|
|
|
|
|
|
|
| |
Parse and support GCC's __builtin_types_compatible_p extension, which takes
two types as arguments, and returns 1 for compatible types or 0 for
incompatible types. Since sparse already supports comparisons with types as
the operands, just transform __builtin_types_compatible_p(a, b) into the
comparison a == b.
Signed-off-by: Josh Triplett <josh@freedesktop.org>
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>
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This means that we can do
#if defined(TOKEN) && TOKEN > 1
and we will _not_ warn even with -Wundef, since the "TOKEN > 1" test
will never even be expanded if TOKEN isn't defined.
Al Viro gets credit for the algorithm changes, I just did the actual coding.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
|
|
|
|
|
| |
We used to parse it with a NULL left side, which just doesn't make
any sense. Refuse to recognize it instead.
|
|
|
|
|
|
|
|
|
| |
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
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
| |
up for various system deficiencies.
This makes sparse easier to port to silly things like
MinGW or Solaris. In particular:
- strtold() is a C99 thing, not everybody has it
- MinGW has problems with mmap(MAP_ANONYMOUS) and doesn't zero it.
- st_ino/st_dev is POSIX identity testing, not supported by MinGW
|
|
|
|
|
|
|
|
|
|
|
| |
warn->warning
error->error_die
new error
lib.h:
warn->warning
error->error_die
new error
Add gcc format checking to warning/error/...
|
|
|
|
|
| |
Associate them with each computed goto, and copy them properly
when inlining.
|
|
|
|
|
|
|
| |
Also fix the type return of initializer evaluation, so that we
get the right size in the right place.
Add the necessary lines to parse the thing too.
|
|
|
|
| |
FP handling added, everything straightforward by now.
|
|
|
|
|
|
|
| |
Also, while we're here, be more careful about the
exact limits, and concatenation: we want to have
the ending NUL character even when we concatenate
too much.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
| |
This updates the type semantics of "get_number_value()" to C99 semantics
rather than the previous gcc/C90 type expansion semantics.
Now regular decimal integers (without suffixes) that are too big to fit
in "long" expand to "long long" rather than "unsigned long".
It also uses "strtoull()" rather than open-coding the conversion.
|
|
|
|
|
| |
unsigned stays as an (unsigned) int. Otherwise it becomes
a long.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This function was the top performance offender in sparse.
We really want it inlined, since all it really does is
to do an indirect call or two, and if inlined that call
turns into a direct call.
Making it a macro allows us to pass in the operation
comparison as code rather than as a list of integers,
which again allows the compiler to do a much better
job.
|
|
|
|
| |
following unary expressions.
|
|
|
|
|
|
| |
Thus 0x1234_5678 is a valid constant, as is 100_000_ul.
The parser doesn't care where they are.
|
|
|
|
|
|
|
|
|
| |
just TOKEN_NUMBER.
This matches how tokenization is supposed to be done, and simplifies
the code.
Expression evaluation changed to cope with the new rules.
|
|
|
|
|
|
|
|
|
| |
We'd incorrectly test the right type of a compatible
pointer expression for "void *" without dropping off
the node information.
This allows us to fix a casting bug, where we used
to drop the node information at the cast.
|
|
|
|
|
|
| |
So let's make that explicit in the parse tree, and avoid
carrying the special cases around further. This makes the
evaluation phase only have one case to worry about.
|
|
|
|
| |
This makes it a lot easier to see what's up.
|
|
|
|
| |
rename them lower cased to match standard C naming rules.
|
|
|
|
|
|
|
|
| |
We now require square brackets around the type, to avoid
any confusion with casts or variable declarations:
if ([typeof(x)] == [int])
...
|
|
|
|
|
|
|
|
|
|
| |
comparisons etc:
if (typeof(a) == int) {
...
(although right now I don't actually do the proper comparison
expansion and all comparisons return "true").
|
|
|
|
|
|
| |
I think I'll allow type expressions at some point, since
it shouldn't actually be all that hard, and would even clean
some stuff up. But for now, we'll just warn about non-C code.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This patch makes a cast expression followed by an initializer list into
a postfix expression that can be dereferenced as a structure or an array.
There are approximately 7 instances of these expressions in the Linux kernel,
that give warnings about "expected lvalue for member dereference".
The approach involved introducing a new "stack-based temporary" symbol
of the same type as the cast expression, and using this as the target
of the initialization expression. The subsequent array or structure
member dereferences are made to that temporary symbol.
show-parse.c need modification to display a symbol expression with
an initializer list that is NOT in a symbol declaration list.
An example of this form with structure member dereference is:
typedef struct { long t1; long t2; long t3; } longstruct_t;
long test;
int
main(void)
{
int a, b, c;
test = (longstruct_t){a, b, c}.t3;
return 0;
}
An example of this form with array member dereference is:
typedef int iarray[2];
int pgp;
main(void)
{
int index;
int a, b;
pgp = (iarray){a,b}[index];
}
|
|
|
|
| |
isn't the sole copyright owner these days.
|
|
|
|
| |
actually handle them correctly later on yet.
|
|
|
|
|
|
|
|
| |
(&&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).
|