| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
| |
I've probably encountered a bug within compile-i386.c. It generates
an infinite loop for 'while' statement. My testing example and proposed
patch are enclosed.
Kamil
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
Acked-by: Jeff Garzik <jgarzik@redhat.com>
Signed-off-by: Christopher Li <sparse@chrisli.org>
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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: Josh Triplett <josh@freedesktop.org>
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Start off with
sparse_initialize(argc, argv);
which will return the number of filenames found. You can then use that,
or just check if *argv is NULL in a loop like
while (*argv)
list = sparse(argv);
where you get the declaration list for each file in turn.
|
|
|
|
|
|
|
|
| |
This makes some needlessly global code static so that sparse don't
complain when self checking.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@looxix.net>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
|
|
|
|
|
|
| |
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
|
|
|
|
| |
untyped "struct ptr_list **", we use properly typed ones.
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
| |
Use FOR_EACH_PTR() instead, or the much fancier iterators
for basic blocks.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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/...
|
|
|
|
|
|
| |
..and switch us entirely over to the new naming scheme.
All the nasty work of going through the users thanks to Chris Li.
|
|
|
|
| |
Use the existing access macro instead.
|
|
|
|
|
|
|
|
|
|
|
| |
In particular:
- we should only test (and not mark busy) the things a
register aliases when we allocate it. This bug kept
us from using %edx, because when we used %eax, we
bogusly marked the 64-bit combination %eax:%edx as
being busy, and refused to use %edx later.
- "get_reg_value()" should take a regclass, so that we
can allocate a new reg from a valid class.
|
|
|
|
| |
into a 16-bit one, and into the "high byte" version.
|
| |
|
|
|
|
|
|
| |
If we are loading something into a register, and another
register has that value already cached, used the cached
register value.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
This still does just mainly EXPR_SELECT, since that
is what I'm familiar with. It's also extremely lazy
about invalidating register content info, since any
code that hasn't been moved to the new format won't
do things properly.
Very much a work-in-progress, designed to eventually
allow us to generate some kind of half-readable code
from the SSA form.
|
|
|
|
|
|
|
| |
Instead of using fixed register names, we keep track of
busy registers, and allocate them as needed.
Also changed EXPR_SELECT to actually use this.
|
|
|
|
|
|
| |
We don't actually _use_ any of them yet, but this lists them,
and adds the information about which register conflicts with
which register (eg %al conflicts with %eax, but not with %ah)
|
|
|
|
|
|
|
|
|
| |
code emitter. Don't make the code emission have to know
about symbol lists etc.
Thus the code emitter can do whatever it wants to do to
the symbols as they are encountered, as part of the main loop
rather than as a separate phase afterwards. Straightforward.
|
|
|
|
|
|
|
| |
It gets them wrong right now: we can't just use "and" and "or",
we need to convert to canonical logical form (0/1) too.
But it's documentation.
|
|
|
|
|
| |
They are valid now that we have a EXPR_SELECT type for
safe conditionals.
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
By virtue of attempting to be too smart, the conditional expression
handling ("x ? foo : bar") would evaluate both 'foo' and 'bar', and
then use the cmov instruction to determine the result, avoiding a
branch in the process.
Unfortunately this only makes sense for simple things (EXPR_VALUE,
EXPR_SYMBOL) and is quite wrong for everything else.
Changed so that 'if' statements and conditional expressions use
largely the same code.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Mostly revert function call stack frame construction
("correctly generate push* instruction")
* Add comment regarding ABI-dictated function call argument size
* Clamp function call arg size to 32-bit minimum. This will copy
the correct value to the stack at the correct alignment, but
(SECURITY/FIXME) will also copy extra bits (24 bits for an
8-bit value, 16 bits for a 16-bit value).
* Add EXPR_FVALUE to the 'unhandled' portion of the master
emit-expression 'switch' statement.
|
|
|
|
|
|
| |
Assumptions that values are 32-bit still remain in places, but
some simple test cases involving 8-bit and 16-bit variables
seem much more sane now.
|
|
|
|
|
|
|
|
|
|
| |
Pay attention to size of function arguments when pushing them to stack.
Generate "pushb" for char, "pushw" for short, ...
[ Linus' note: this is likely "wrong". In a real x86 compiler, we'd
expand the width of the argument to 32 bits regardless, but from
a demonstration standpoint this is better ]
|
|
|
|
| |
We already have a function that adds correct {b,w,l,q} suffix.
|
|
|
|
| |
{'b', 'w', 'l', 'q'} instead of {ascii 8, ascii 16, ' ', '@'}
|
|
|
|
|
| |
Quite frankly, anybody who uses assert() should be shot. It's
a fundamentally broken thing.
|
|
|
|
|
|
|
|
|
|
|
| |
simplify_int_binop() was completely broken for comparisons - there the
signedness of (converted) arguments can not be obtained from type of
result. IOW, we had all comparisons in constant expressions done as
signed ones.
Fixed by introducing new primitives for unsigned versions of
comparions (SPECIAL_UNSIGNED_LT, etc.) and remapping in evaluate_compare()
once we know the types. That also fixes similar mess in compile-i386 and
linearize.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
| |
Shown by running sparse on itself.
|
|
|
|
|
| |
This actually showed a bug ("assignment in conditional")
in evaluate.c.
|
|
|
|
| |
rename them lower cased to match standard C naming rules.
|
|
|
|
|
|
|
|
|
|
| |
comparisons etc:
if (typeof(a) == int) {
...
(although right now I don't actually do the proper comparison
expansion and all comparisons return "true").
|
|
|
|
|
| |
They were only used for the original pre-instruction
linearization.
|