| Age | Commit message (Collapse) | Author | Files | Lines |
|
When processing integers to/from pointers, we would like to have
an integer type which has the same size as a pointer.
Currently, it's always the case for [s]size_t but it's preferable
to have a specific type which will always offer this guarantee,
like [u]intptr_t.
Fix this lazily by defining [u]intptr_ctype to [s]size_t_ctype.
Note: this intptr_t is just internal to sparse and can be different
from the type choosen by the libc/platform.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Sparse has support for a subset of GCC's large collection of builtin
functions. As for GCC, it's not easy to know which builtins are
supported in which versions.
clang has a good solution to this problem: it adds the checking macro
__has_builtin(<name>) which evaluates to 1 if <name> is a builtin
function supported by the compiler and 0 otherwise.
It can be used like:
#if __has_builtin(__builtin_clz)
#define clz(x) __builtin_clz(x)
#else
...
#endif
It's possible or probable that GCC will have this soon too:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66970
Add support for this __has_builtin() macro by extending
the evaluation of preprocessor expressions very much like
it is done to support defined().
Note: Some function-like builtin features, like __builtin_offset(), are
considered as a kind of keyword/operator and processed as such.
These are *not* considered as builtins by __has_builtin().
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
These will be needed for __builtin_uadd_overflow() and friends.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
GCC consider these macros as being defined, sparse doesn't.
Also sparse uses a sequence of comparisons, one for each of
__DATE__, __FILE__, ..., which is not ideal.
Fix this by defining and using a table to associate to the
corresponding symbol a method doing the expansion.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
'fix-redef-typedef' and 'fixes' into tip
|
|
It seems that some system headers (Debian x32's glibc) use
these types based on GCC's version without checking one of
the '__STDC_IEC_60559_<something>' macro. This, of course,
creates warnings and errors when using sparse on them.
Avoid these errors & warnings by letting sparse know about
these types.
Note: Full support would require changes in the parsing to
recognize the suffixes for constants ([fF]32, ...),
the conversion rules between these types and the
standard ones and probably and most others things,
all outside the scope of this patch.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
Acked-by: Ramsay Jones <ramsay@ramsayjones.plus.com>
|
|
check_duplicates() is local to evaluate.c and only called via
evaluate_symbol_list().
However, typedefs need exactly the same check logic.
So, make check_duplicates() extern so that it can also be used
directly in other files.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Currently, (most) builtin functions are declared like
normal function prototypes. Furthermore, these declarations
are done via the pre-buffer mechanism and thus need to be
tokenized & parsed like normal code.
This is far from being 'builtin' and involves unnneded
processing.
Change this by skipping this pre-buffer phase and directly creating
the appropriate symbol for them.
Note: the correct mechanism to be used to make them really builtin
is via init_builtins(), used when we have a real semantic
action for the builtin.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
These types are needed to declare builtin functions without
passing by the add_pre_buffer()-tokenization-parsing phases.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
'bad_type' is used for ... bad types instead of NULL
in order to avoid later lots of null-checking.
Alas NULL is also often used and so we have to check
for NULL and 'bad_ctype' when checking a type's validity.
Add an helper: valid_type() to make the code a bit simpler.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
'fix-volatile-simplification', 'struct-asm-ops', 'restricted-pointers', 'fix-f2i-casts', 'symaddr-description', 'flush-stdout' and 'diet-simple' into tip
|
|
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
This only add the parsing and checks as a type qualifier;
there is no operational semantic associated with it.
Note: this only support _Atomic as *type qualifier*, not
as a *type specifier* (partly because there an
ambiguity on how to parse '_Atomic' when followed
by an open parenthesis (can be valid as qualifier
and as specifier)).
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Note: there is still no semantic associated with 'restrict'
but this is a preparatory step.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
This is slightly shorter (and thus may avoid long lines) and
facilitate the introduction of MOD_RETRICT in a later patch.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
MOD_TOPLEVEL & MOD_INLINE are already include in MOD_STORAGE
so there is no need to repeat them in MOD_IGNORE & elsewhere
where MOD_STORAGE is used.
Change this by removing the redundant MOD_TOPLEVEL & MOD_INLINE.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Now they are grouped a bit more logically.
Note: MOD_ASSIGNED & MOD_ADDRESSABLE are not type modifiers
but properties of the symbol. As such they should be
moved to struct symbol. However, as they should be
correctly propagated to the symbol components if any,
better to leave them as is.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
but is used to track which inline functions are
effectively used. So better remove it from the MOD_...
and implement the same functionality via a flag
in struct symbol.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
because the function was already defined as an inline function
in the same header file.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
This member seemed to be used for:
- current value of an enum during parsing
- index into the virtual frame
but is currently not used and never set, it's only
displayed in compile-i386 & show_parse (as zero since never
initialized).
Remove it to make struct symbol a bit more light.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
It's not used, it's never set and .. it seems has never been used.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
This helper was introduced to add some warning in conditionals
which must accept arrays and functions as those degenerate as
pointers in this context.
There was some sign of a bug somewhere but it wasn't seen
and as consequence arrays and function type were added to
scalar type (yeah, brown paper bag).
Now that the bug is solved, fix this by removing array and
function type from is_scalar_type().
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
No functional changes, just move some code around and rename
'eval_init_table[]' to 'builtins_table[]'.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
Signed-off-by: Christopher Li <sparse@chrisli.org>
|
|
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
Signed-off-by: Christopher Li <sparse@chrisli.org>
|
|
Currently when we use typeof() all the modifiers from the source
type are ignored and thus not present in the resulting type.
This give all sort of problems. One simple example is:
const int obj;
typeof(obj) *ptr;
*ptr = 0;
We can expect that 'ptr' will have the type 'const int *' and thus
that sparse will warn on the assignment in the last line but it's
not case because 'ptr' has in fact the type 'int *'.
The patch fix this by preserving some of the modifiers when using
typeof().
WARNING: it may be that the old behaviour was so more or less on
purpose as it provide a way to remove some modifiers by casting
while still being able to use generic macros. For exmaple, it
was possible to write the following macro:
#define noconst(x) (typeof(x))
and use 'noconst()' as a cast to remove 'const' from types.
Of course, the problem with this macros is that it remove
*all* modifiers, not only 'const'.
With the patch, it won't be possible anymore to do this sort of
things, which maybe is fine for 'const' but it's why MOD_NOREFREF
is still dropped as it create problems in the Linew kernel, for example
in the macro to convert back a percpu variable into a plain one.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
Signed-off-by: Christopher Li <sparse@chrisli.org>
|
|
Information about storage is needed for objects but once
you take the address of an object, its storage should be
irrelevant for the resulting pointer.
Trying to keep the storage into the pointer's modifiers
(while it will be available in the base type anyway) only
create corner cases later.
An example of the problem it can create is when the pointer
is dereferenced in an inlined function.
Better to simply not put have the storage informations
for the pointer, which is what this patch does.
To better illustrate the situation, suppose you have the
following variable declaration:
static int var;
var's type should be:
int static [toplevel] [addressable]
if you take its address the resulting pointer will be of type:
int static [toplevel] *
while it should simply be:
int *
Detected-by: Nicolai Stange <nicstange@gmail.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
Signed-off-by: Christopher Li <sparse@chrisli.org>
|
|
With the following code:
typedef unsigned long __nocast cputime_t;
void task_cputime_adjusted(cputime_t *);
void current_task_runtime_100ns(void)
{
cputime_t utime;
task_cputime_adjusted(&utime);
}
sparse emits the following message:
x.c:16:32: warning: incorrect type in argument 1 (different modifiers)
x.c:16:32: expected unsigned long [nocast] [usertype] *<noident>
x.c:16:32: got unsigned long *<noident>
x.c:16:32: warning: implicit cast to nocast type
In other words, when taking the address of 'utime', sparse drops the 'nocast'
modifier and then complains that task_cputime_adjusted() is not given a
'nocast' pointer as expected ...
This feels wrong to me.
The proposed fix is to simply not dropping the 'nocast' modifier when
taking the address, like done for a normal type qualifier.
This gives very reasonable behaviour for all the test cases I could
think of:
- taking the address or dereferencing doesn't drop the nocast
- arithmetic operations on nocast give a nocast result.
- implicit to/from cast is OK only if the base type are the same
- implicit to/from pointer cast is OK only if the base type are the same
This still gives a "leaky" semantic: the nocast modifier can be lost via
an implicit cast to a non-qualified value.
Explicit cast to or from nocast values doesn't give any warning, maybe
it's OK, maybe it's not but it's orthogonal to the current issue.
Is this the wanted semantic for the nocast modifier?
Reported-by: Roman Kagan <rkagan@virtuozzo.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
Signed-off-by: Christopher Li <sparse@chrisli.org>
|
|
This stops warnings in code using socket operations with a modern glibc,
which otherwise result in warnings of the form:
warning: incorrect type in argument 2 (invalid types)
expected union __CONST_SOCKADDR_ARG [usertype] __addr
got struct sockaddr *<noident>
Since transparent unions are only applicable to function arguments, we
create a new function to check that the types are compatible
specifically in this context.
Also change the wording of the existing warning slightly since sparse
does now support them. The warning is left in case people want to avoid
using transparent unions.
Signed-off-by: John Keeping <john@keeping.me.uk>
Signed-off-by: Christopher Li <sparse@chrisli.org>
|
|
The old code was relicensed by Novafora Corporation, successor in interest to
Transmeta Corporation, in 2009. Other authors were also asked about the change
of their contributions to the MIT license and all with copyrightable changes
agreed to it.
Signed-off-by: Franz Schrober <franzschrober@yahoo.de>
Acked-by: Adam DiCarlo <adam@bikko.org>
Acked-by: Al Viro <viro@ZenIV.linux.org.uk>
Acked-by: Alberto Bertogli <albertito@blitiri.com.ar>
Acked-by: Alecs King <alecs@perlchina.org>
Acked-by: Alexander Shishkin <alexander.shishckin@gmail.com>
Acked-by: Alexey Dobriyan <adobriyan@gmail.com>
Acked-by: Alexey Zaytsev <alexey.zaytsev@gmail.com>
Acked-by: Andries E. Brouwer <Andries.Brouwer@cwi.nl>
Acked-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Acked-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Acked-by: Ben Pfaff <blp@nicira.com>
Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Acked-by: Bernd Petrovitsch <bernd@petrovitsch.priv.at>
Acked-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
Acked-by: Blue Swirl <blauwirbel@gmail.com>
Acked-by: Chris Forbes <chrisf@ijw.co.nz>
Acked-by: Chris Wedgwood <cw@f00f.org>
Acked-by: Christopher Li <sparse@chrisli.org>
Acked-by: Damien Lespiau <damien.lespiau@gmail.com>
Acked-by: Dan Carpenter <error27@gmail.com>
Acked-by: Dan McGee <dan@archlinux.org>
Acked-by: Daniel De Graaf <danieldegraaf@gmail.com>
Acked-by: Daniel Sheridan <dan.sheridan@postman.org.uk>
Acked-by: Dave Jones <davej@redhat.com>
Acked-by: David Given <dg@cowlark.com>
Acked-by: David Miller <davem@redhat.com>
Acked-by: David Mosberger-Tang <dmosberger@gmail.com>
Acked-by: David Olien <David.Olien@lsi.com>
Acked-by: Diego Elio Pettenò <flameeyes@flameeyes.eu>
Acked-by: Emil Medve <Emilian.Medve@Freescale.com>
Acked-by: Ethan Jackson <jacksone@nicira.com>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
Acked-by: Frank Zago <fzago@systemfabricworks.com>
Acked-by: Frederic Crozat <fcrozat@suse.com>
Acked-by: Geoff Johnstone <geoff.johnstone@gmail.com>
Acked-by: Hannes Eder <hannes@hanneseder.net>
Acked-by: Jan Pokorný <pokorny_jan@seznam.cz>
Acked-by: Jeff Garzik <jgarzik@redhat.com>
Acked-by: Jiri Slaby <jslaby@suse.cz>
Acked-by: Joe Perches <joe@perches.com>
Acked-by: Joel Soete <rubisher@scarlet.be>
Acked-by: Johannes Berg <johannes@sipsolutions.net>
Acked-by: Jonathan Neuschäfer <j.neuschaefer@gmx.net>
Acked-by: Josh Triplett <josh@kernel.org>
Acked-by: Kamil Dudka <kdudka@redhat.com>
Acked-by: Kim Phillips <kim.phillips@linaro.org>
Acked-by: KOSAKI Motohiro <kosaki.motohiro@gmail.com>
Acked-by: Kovarththanan Rajaratnam <kovarththanan.rajaratnam@gmail.com>
Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
Acked-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
Acked-by: Martin Nagy <nagy.martin@gmail.com>
Acked-by: Masatake YAMATO <yamato@redhat.com>
Acked-by: Mauro Dreissig <mukadr@gmail.com>
Acked-by: Michael Büsch <m@bues.ch>
Acked-by: Michael Stefaniuc <mstefani@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Mika Kukkonen <mikukkon@iki.fi>
Acked-by: Mike Frysinger <vapier@gentoo.org>
Acked-by: Mitesh Shah <Mitesh.Shah@synopsys.com>
Acked-by: Morten Welinder <mortenw@gnome.org>
Acked-by: Namhyung Kim <namhyung@gmail.com>
Acked-by: Nicolas Kaiser <nikai@nikai.net>
Acked-by: Oleg Nesterov <oleg@redhat.com>
Acked-by: Pavel Roskin <proski@gnu.org>
Acked-by: Pekka Enberg <penberg@cs.helsinki.fi>
Acked-by: Peter Jones <pjones@redhat.com>
Acked-by: Peter A Jonsson <pj@sics.se>
Acked-by: Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
Acked-by: Ramsay Jones <ramsay@ramsay1.demon.co.uk>
Acked-by: Randy Dunlap <rdunlap@xenotime.net>
Acked-by: Reinhard Tartler <siretart@tauware.de>
Ached-by: Richard Knutsson <richard.knutsson@gmail.com>
Acked-by: Rob Taylor <rob.taylor@codethink.co.uk>
Acked-by: Rui Saraiva <rmpsaraiva@gmail.com>
Acked-by: Ryan Anderson <ryan@michonline.com>
Acked-by: Sam Ravnborg <sam@ravnborg.org>
Acked-by: Samuel Bronson <naesten@gmail.com>
Acked-by: Santtu Hyrkkö <santtu.hyrkko@gmail.com>
Acked-by: Shakthi Kannan <shakthimaan@gmail.com>
Acked-by: Stephen Hemminger <shemminger@linux-foundation.org>
Acked-by: Thomas Schmid <Thomas.Schmid@br-automation.com>
Acked-by: Tilman Sauerbeck <tilman@code-monkey.de>
Acked-by: Vegard Nossum <vegardno@ifi.uio.no>
Acked-by: Xi Wang <xi.wang@gmail.com>
Acked-by: Yura Pakhuchiy <pakhuchiy@gmail.com>
Signed-off-by: Christopher Li <sparse@chrisli.org>
|
|
It will indicate this argument will skip the type compatible check.
It allow PTR_ERR() to accept __iomem pointer without complaining.
Signed-off-by: Christopher Li <sparse@chrisli.org>
|
|
This patch fixes __builtin_safe_p() to work properly for calls to pure
functions.
Cc: Christopher Li <sparse@chrisli.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
Signed-off-by: Christopher Li <sparse@chrisli.org>
|
|
Without this commit, sizeof(_Bool) provokes an error with "cannot size
expression" because _Bool is a 1-bit type and thus not a multiple of a full
byte in size. But sizeof(_Bool) is valid C that should evaluate to 1, so
this commit fixes the problem and adds a regression test.
Signed-off-by: Ben Pfaff <blp@nicira.com>
Signed-off-by: Christopher Li <sparse@chrisli.org>
|
|
Some structure types provide a set of fields of which most users will
only initialize the subset they care about. Users of these types should
always use designated initializers, to avoid relying on the specific
structure layout. Examples of this type of structure include the many
*_operations structures in Linux, which contain a set of function
pointers; these structures occasionally gain a new field, lose an
obsolete field, or change the function signature for a field.
Add a new attribute designated_init; when used on a struct, it tells
Sparse to warn on any positional initialization of a field in that
struct.
The new flag -Wdesignated-init controls these warnings. Since these
warnings only fire for structures explicitly tagged with the attribute,
enable the warning by default.
Includes documentation and test case.
Signed-off-by: Josh Triplett <josh@joshtriplett.org>
Signed-off-by: Christopher Li <sparse@chrisli.org>
|
|
It is causing compiler warning on 32 bit systems.
Move it to lower bits fix it.
Signed-off-by: Christopher Li <sparse@chrisli.org>
|
|
Hello,
enclosed is a simple patch adding support for attribute 'noreturn' to the
parser. The enhancement makes it possible to optimize walk through CFG and
thus help us to fight with the state explosion. The benefit is demonstrated
on a simple real-world example.
Generated CFG before patch:
http://dudka.cz/devel/html/slsparse-before/slplug.c-handle_stmt_assign.svg
Generated CFG after patch:
http://dudka.cz/devel/html/slsparse-after/slplug.c-handle_stmt_assign.svg
It's one of the key features I am currently missing in SPARSE in contrast
to gcc used as parser. Thanks in advance for considering it!
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
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>
|
|
In gcc extern inline function has special meaning. The inline
function will never emit stand alone copy of the function. It also
allow multiple implementations cross different file. That effectively
makes the extern inline has file scope.
Signed-off-by: Christopher Li <sparse@chrisli.org>
|
|
GCC supports a __thread storage class, used to indicate thread-local
storage. It may be used alone, or with extern or static.
This patch makes sparse aware of it, and check those restrictions.
Signed-off-by: Alberto Bertogli <albertito@blitiri.com.ar>
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>
|
|
a) __label__ in gcc is not a type, it's a statement. Accepted in the beginning
of compound-statement, has form __label__ ident-list;
b) instead of crapping into NS_SYMBOL namespace (and consequent shadowing
issues), reassign the namespace to NS_LABEL after we'd bound it. We'll get
block scope and label namespace, i.e. what we get in gcc.
c) MOD_LABEL can be dropped now.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Christopher Li <sparse@chrisli.org>
|
|
... at least to the extent we used to do it. It still does _not_
cover the perversions gcc can do with that, but at least it deals
with regressions. Full solution will have to wait for full-blown
imitation of what gcc people call __attribute__ semantics, the
bastards...
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Christopher Li <sparse@chrisli.org>
|
|
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Christopher Li <sparse@chrisli.org>
|
|
Other than for attributes of labels (completely ignored, and we can
simply use skip_attributes() there), all callers of handle_attributes
actually get ctype == &ctx->ctype for some ctx. Ditto for ->declarator().
Switch both to passing ctx instead (has to be done at the same time,
since we have handle_attributes() called from ->declarator() for struct).
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Christopher Li <sparse@chrisli.org>
|
|
... and don't do full-blown apply_ctype() every damn time.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Christopher Li <sparse@chrisli.org>
|
|
Make sure that we accept the right set; kill ad-hackery around checks
for banned combinations. Instead of that we keep a bitmap describing
what we'd already seen (with several extra bits for 'long long' and
for keeping track of can't-combine-with-anything stuff), check and
update it using the values in ..._op and keep track of size modifiers
more or less explicitly.
Testcases added. A _lot_ of that used to be done wrong.
Note that __attribute__((mode(...))) got more broken by this one;
the next several changesets will take care of that.
One more thing: we are -><- close to getting rid of MOD_SPECIFIER bits
for good.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Christopher Li <sparse@chrisli.org>
|
|
... and yes, right now it's ucking fugly. Will get sanitized shortly.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Christopher Li <sparse@chrisli.org>
|
|
Introduce struct decl_state that will hold the declaration parser
state. Pass it to declarator() and direct_declarator(). Note
that at this stage we are putting more stuff on stack *and* get
extra copying; that's temporary and we'll deal with that in subsequent
patches.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Christopher Li <sparse@chrisli.org>
|
|
Was:Re: Initializing float variables without type suffix)
> cast_to() seems fine.
>
> In expanding stage, cast_value() did not cast the constant
> correctly.
You're right, I also noticed this in the meantime.
The decision, whether newtype is int_type or fp_type is not made
correctly.
The following patch seems to work:
Fix implicit cast to float
Patch modified by Chris.
Signed-Off-By: Thomas Schmid <Thomas.Schmid@br-automation.com>
Signed-Off-By: Christopher Li <sparse@chrisli.org>
|
|
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>
|
|
> Do you want to resend your change which revert the context changes?
> Make it base on Josh's git's tree and I will merge your changes in my
> branch.
Below. Or I can give it to you in git if you prefer. I still think we
should redo this in some form so that annotations with different
contexts can work properly, but I don't have time to take care of it
right now.
johannes
>From ca95b62edf1600a2b55ed9ca0515d049807a84fc Mon Sep 17 00:00:00 2001
From: Johannes Berg <johannes@sipsolutions.net>
Date: Tue, 23 Dec 2008 10:53:19 +0100
Subject: [PATCH] Revert context tracking code
|
|
It was only used to check if the symbol was already bound, and would
cause significant complication in the serialization code.
Signed-off-by: Alexey Zaytsev <alexey.zaytsev@gmail.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>
|
|
* new helper: examine_pointer_target(). Examine target, find address_space
et.al. If the target is SYM_NODE - merge it, etc.
* new helper: target_qualifiers(). Pointers to any array are considered
as pointers to unqualified type as far as implicit conversions are
concerned; handle that right.
* SYM_TYPEOF can be handled sanely now: don't copy the node, just convert
SYM_TYPEOF to SYM_NODE and examine that.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
|
|
a) qualifiers should not be ignored beyond the top layer
b) qualifiers *should* be ignored in top layer of function arguments
c) change prototype - pass ctype * instead of symbol * and pass
"what to add to modifiers in that ctype" instead of "what to ignore".
We are still not quite done (there are incomplete types, there
are array size comparisons, there is lifting of signedness logics
into compatible_assignment_types()), but it's a much better approximation.
BTW, it's already good enough for kernel ARRAY_SIZE(), which
has become a major source of noise lately...
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
[Josh: prototype fix]
Signed-off-by: Josh Triplett <josh@freedesktop.org>
|
|
Adds function get_type_name to symbol.h to get a string representation of a given type.
Signed-off-by: Rob Taylor <rob.taylor@codethink.co.uk>
|
|
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>
|
|
AFAICS, that should do null pointer constants right. We assign
special instance of void * (&null_ctype) to (void *)<zero integer
constant expression> and replace it with normal void * when we
don't want null pointer constant. is_zero_constant() checks if
we have an integer constant expression, does conservative expand
(i.e. instead of generating an error on 1/0, etc. leaves the
node unreplaced) and checks if we have reduced the sucker to
EXPR_VALUE[0] without comma taint.
Implemented all (AFAICS) special cases involving null pointer
constants; most changes in evaluate_compare() and evaluate_conditional().
Both are still incomplete; handling of qualifiers is still missing,
but that's a separate story.
Note that we get two new sets of warnings on the kernel build; one is
due to wrong size_t (handled in the next patch; didn't show up until
now since we didn't warn on comparison of pointers to incompatible
types) and another is a pile of warnings about integer 0 used as NULL
on
if (p == 0)
where p is a pointer. Additionally, there's an idiotic
(p>0)
in one place (again, p is a pointer). Bugger if I know how gcc doesn't
warn on that one, it's certainly a standard violation and bloody pointless
even as extension...
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>
|
|
Improve the dot files generated by graph.c to put the basic blocks for
each function into their own labelled subgraph cluster and to
distinguish between branches and function calls using different edge
types. Requires a change to struct symbol to keep track of the
entrypoint associated with a given function identifier.
Currently, no attempt is made to handle indirect function calls -- they
are just ignored.
Signed-off-by: Dan Sheridan <djs@adelard.com>
|
|
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: 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>
|
|
The following case causes a warning about different signedness of pointer.
The pointer should not have signedness at all.
struct sk_buff;
struct sock;
extern int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb,
int getfrag(void *from, char *to, int offset,
int len,int odd, struct sk_buff *skb),
void *from, int length);
int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb,
int (*getfrag)(void *from, char *to, int offset,
int len,int odd, struct sk_buff *skb),
void *from, int length)
{
return 0;
}
Signed-Off-By: Christopher Li <sparse@chrisli.org>
Acked-By: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Josh Triplett <josh@freedesktop.org>
|
|
The back end need to generate some storage for anonymous string.
This simplify testing of anonymous string.
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>
|
|
Here is my attempt to write a Ctags base on sparse.
It depends on the result from actually preprocessing the C source file.
It can handle the tags from macro expansion.
It works well enough for me to locate "int32_t" and "clear_token_alloc".
This is the updated ctags that actually generates output to a tags file.
Signed-Off-By: Christopher Li <sparse@chrisli.org>
Signed-Off-By: Josh Triplett <josh@freedesktop.org>
|
|
Example
#strong_define FOO 1
#undef FOO // silently ignored
#define FOO 2 // silently ignored
This allows (for example) to override CONFIG_XXX values without
editing include/linux/autoconf.h
I think this is useful. If you think differently, I will appreciate
your comments on this patch correctness.
Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru>
|
|
This patch renames symbol->weak to symbol->attr and adds
symbolic names for it's values.
I don't like the new name, and will be happy to rename if
you suggest me something different.
Probably it is also better to move ->attr into the NS_MACRO
part of the union and make it integer.
No changes in pre-process.o
Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru>
|
|
When NS_MACRO symbol is used, sparse clears it's 'weak' flag.
This is bad for multifile parsing, and wrong:
#weak_define FOO 1
FOO
#weak_define FOO 2 // silently ignored
After this patch sparse never writes to NS_MACRO symbols from
another scope (except ->used_in).
Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru>
|
|
With this patch handle_undef() doesn't corrupt the builtin macros.
This (imho) cleanups the code and is used in the next patches.
Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru>
|
|
|
|
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>
|
|
that bugger is weird; _no_ type modifications are
done to arguments (no promotions, no degeration,
void accepted, etc.). Implemented, testcase added.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
|
|
symbol.h uses the standard multiple-inclusion guard, with the symbol SYMBOL_H,
but the comment on the final #endif says /* SEMANTIC_H */. Change this to the
correct symbol.
Signed-off-by: Josh Triplett <josh@freedesktop.org>
|
|
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 adds a warning when enums of different types are mixed. I found a
handful of problems with this in my own code -- nothing that testing
could have revealed at this point, but if someone has added an extra
flag to an enum, things would have gone "boom!"
typedef enum { A1, A2 } enumA;
typedef enum { B1 = 10, B2 } enumB;
static void Afunc (enumA a) { }
int
main (int argc, char **argv)
{
enumA a = A1;
switch (A1) {
case A1: break;
case A2: break;
case B1: break; // Warn
case B2: break; // Warn
default: break;
}
switch (1) {
case A1: break;
case A2: break;
case B1: break; // Warn
case B2: break; // Warn
default: break;
}
switch (1) {
case A1 ... B2: break; // Warn
default: break;
}
(void)(1 ? a : B1); // Warn
(void)(A1 == B1); // Warn
(void)(A1 << B1); // No warning wanted
a = B1; // Warn
Afunc (B1); // Warn
return 0;
}
Signed-off-by: Morten Welinder <terra@gnome.org>
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 avoids evaluating already evaluated symbols. I think if the symbol
is already evaluated once, there is no change in the conditions so it
should not be evaluated again. This helps when we are evaluating for
multiple files.
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>
|
|
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.
|
|
Examining a pointer should not cause us to examine what it points to.
However, that means that we'll have to be more careful later on when we
look at the base type of a pointer.
|
|
This patch add static declare to make sparse happy of checking itself.
|
|
We weren't checking the types properly, only the sizes. That
made us incorrectly ignore implicit casts between integers
and pointers if they just had the right size and sign.
|
|
|
|
They don't have to be MOD_EXTERN to be visible to others, MOD_TOPLEVEL
does the same thing. So add a MOD_NONLOCAL helper #define to remind us
what we're really after.
|
|
Not only do all users want it, the list of used symbols
is not stable until after the tree has been evaluated.
|
|
We add a per-symbol pseudo, and just track them that way.
|
|
They work like weak symbols: they get used if nobody defines
anything else for them, and re-defining them doesn't cause a
warning.
|
|
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).
|
|
While __builtin_constant_p() tells you whether an expression is
constant, __builtin_safe_p() tells you whether it has side effects.
NOTE! A "safe" expression can still access pointers and generally
cause SIGSEGV and chaos. But it's useful to check whether a macro
argument can safely be used multiple times, for example.
Suggested use something like
#define MY_MACRO(a) do { \
__builtin_warning(!__builtin_safe_p(a), "Macro argument with side effects"); \
... use 'a' multiple times ...
which does the obvious thing.
|
|
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.
|
|
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.
|
|
The only thing they do is to refuse to bind to the regular
C namespaces (NS_TYPEDEF | NS_STRUCT | NS_LABEL | NS_SYMBOL)
with a warning.
You can mark any identifier you want reserved by just setting
ident->reserved = 1. Sparse won't care.
|
|
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...
|
|
Such a structure does not have its size padded up by the alignment,
since arrays of such structures are meaningless anyway.
|
|
so common that we might as well make it a proper operation.
|
|
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.
|
|
It's also used by SYM_MACRO preprocessor symbols (the
regular "lookup_symbol()" sets it), and thus it has to
be shared, not in a private part of a union.
|
|
Make "label_type" be a real ctype, rather than an uninitialized
mess.
|
|
This all started with I want to remove match_string_ident in preprocessor.
I decide that I don't want to search a pointer in the list. There is faster
way which is register a symbol with a new name space which contain the
handler.
This changes:
1) changed name of NS_PRECESSOR to NS_MACRO and give it a new meaning
for preprocessor command. Now NS_MACRO means a macro name, and the
new NS_PREPROCESSOR means a preprocessor command.
2) The ctype and preprocessor can put into one union. They are on
different name space so they _should_ never collapse. I did that and
made struct symbol 8 bytes smaller. Nothing blew up for me so it
must be correct ;)
And a question:
3) When to initialize the preprocessor command symbol. Should we make
it part of the init_symbol or let the caller(check.c) initialize it?
Do we want to remove the preprocessor command afterwords?
|
|
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.
|
|
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.
|
|
Check tags when naming tagged types.
This catches things like...
enum Foo { FOO };
struct Foo x;
|
|
|
|
With help from Christopher Li <sparse@chrisli.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]".
|
|
Don't allow nonsensical type descriptions like
signed unsigned x;
short long x;
double x : 4;
int y : 1 : 2;
|
|
Ideally we should probably allocate an error code for recursive expand,
so the caller can know that the inline did not expand at all.
But the evaluate_symbol_call don't care about that so I just make it
reutrn 0.
|
|
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.
|
|
This makes things a bit more readable, and also, if the lazy
evaluation is never actually done, we still en dup with a valid
type (the lazy marker is a special, but valid, "void *" type).
|
|
the base type as NULL when no type is specified.
Traditional C makes the incomplete type be "int".
|
|
This will allow us to force certain type casts that would
be otherwise illegal (changing address space, for one).
|
|
type specifiers.
|
|
This makes "-m64" actually work.
|
|
This fixes the linearization of "return", to use the proper symbol
target that the front end has already set up for it:
- linearize_statement(), case "STMT_COMPOUND" needs to create a label
at the _end_ (aftre doing the linearization of all the other stuff) if
"stmt->ret" is non-NULL.
- STMT_RETURN needs to move the return expression to the return variable,
and goto the return label.
|
|
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.
|
|
Here is the updated version of the patch.
I tried to do as well on the iterator flattening as the old code, but
then realized that the end result will be about as complex as what was
there from before. So instead I wrote a simple pass to stitch the basic
blocks together. It does two things: ff it is an empty block with a
goto, it transfers the outgoing edge directly to the target. And if the
only parent ends with a goto, it combines the block with the parent.
There is also dead code elimination. So I removed the previous entry
point hack for while loops. There is no need for that any more, and the
end result is that we generate very compact basic blocks, often better
than the previous approach did.
The extra pass can almost certainly be reused for other back end passes.
I also did:
- add some lib functions to delete a point from the ptr_list while
iterating.
- Ignore labels which are not used
- some minor bug fixing to the previous patch
Know problem:
- it doesn't deal with phi correctly, I need to redo the phi base
on Tommy's suggestion.
|
|
Export "type_difference()" for type equality testing
in expand.c.
Evaluate the type in a EXPR_TYPE expression.
|
|
comparisons etc:
if (typeof(a) == int) {
...
(although right now I don't actually do the proper comparison
expansion and all comparisons return "true").
|
|
by making the namespace thing a bitmap.
|
|
This is required for any kind of efficient liveness
analysis.
|
|
This required making the inter-BB trampoline to be done
using indirection through a symbol, rather than as direct
pointers from one BB to another. Fix up code to match.
Avoid a few warnings by handling GOTO_BB in the case
statements.
|
|
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.
|
|
This adds support support for variable macro arguments:
#define msg(fmt, ...) printf(fmt, __VA_ARGS__)
#define msg(fmt, arg...) printf(fmt, arg)
make ARCH=um will hit that kind of macros.
|
|
isn't the sole copyright owner these days.
|
|
does type evaluation, the second one does value evaluation
and inline expansion.
This has the advantage that by the time we do value evaluation
and inline expansion, we have traversed the tree fully once,
which allows us to take advantage of function-global information,
ie we know whether symbols have ever been accessed etc.
|
|
replace the symbols encounterd durign an expression copy, and
this is the first step showing how.
This doesn't get the multi-level inlining right, we'll get there
some day. Also, it currently complains about subexpressions it can't
copy yet, causing way too much verbosity for the kernel.
|
|
This patch removes the type-names on the anonymous structures. This
fixes compilation when using gcc-3.3 (Debian). Credit for identifying
the fix goes to Arnaldo Carvalho de Melo <acme@conectiva.com.br>.
|
|
path to eventually start parsing them.
Basic approach: we'll replace the pragma line with some kind
of internal attribute-looking thing for the front end.
|
|
through typedefs.
|
|
(&&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).
|
|
to return a success marker for it.
|
|
This should also do the inline function expansion, but we still
don't do that. For now we just do the "__builtin_constant_p()"
as the only such function. We'll expand the repertoire some day.
|
|
anything uses it yet, but it's clearly the rigth thing
to do.
|
|
parenthood. I desperately tried to avoid expanding the size of a token
by using other means, but I couldn't fix the problems that led to.
The pre-processor is still a pile of crud and gets multi-token pasting
quite wrong (and probably other cases too). I should try to find some
test-suite, but I'm afraid of what it would find.
|
|
preparing for a public release.
|
|
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.
|
|
to be independent and could share the same storage. Right now that
doesn't work, so just keep them separate and let "struct symbol" be
a bit too large.
Will need to fix this later, there are lots of symbols around.
|
|
for doing same-id symbol type-checks.
|
|
Use the existing type merging function.
|
|
|
|
|
|
per-iterator anonymous symbols.
Make arrays also gracefully degenerate into "void *".
|
|
symbol information for when type parsing gets too confusing.
|
|
Add inline symbols to the "used_list" if they get marked as accessed.
|
|
Show (simple) initializers properly.
|
|
as addressable (and warn if they were claimed to be "register").
|
|
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.
|
|
That's really more descriptive of what it is, and it avoids
confusion with the other uses of "type".
Add "address space" ID to types. It could be segments (yuck!)
or it could be a "kernel" vs "user" thing, hint hint.
|
|
alignment gotten from the "aligned()" or "packed" attributes.
|
|
The last one gives a "context mask" and "context value" to a symbol,
which can be used to verify that the symbol is only used in a certain
context.
|
|
so that type parsing gets access to it.
|
|
the real one when it goes out the door.
|
|
(or NULL) rather than just 1 (or 0).
Make "examine_symbol_type()" follow 'typeof's, and return the result.
|
|
with lazy evaluation of expressions.
|
|
This still gets the nesting scope wrong, though. Labels
should use function scope, not block scope.
|
|
add them to the parse tree. We now do.
|
|
to it, instead of having everybody have pointers to "struct token"
only because they wanted to have the position.
Fix array addition type degeneration.
|
|
the size of the array is also unsized.
|
|
|
|
switch and case-statements).
Handle varying functions.
|
|
users to match.
Examine array type sizes.
Evaluate 'sizeof()', and realize that you can dereference arrays
as well as pointers.
|
|
dangling anonymous "int_type" types with magic modifiers,
but turn all types into explicit C types.
|
|
etc. Add a function call expression type. Make expression type
evaluation return a success/failure value.
|
|
abstract types that type parser already knows about).
Make constant string expressions have some almost-proper type.
|
|
Add 'target.h' to describe size of target-dependent types.
Add parsing of size information to gather the size for simple
types, pointers and structures/unions.
|
|
specifiers parsing (which is a proper superset of the much more limited
parsing that we wanted at this point).
Parse void and ellipsis arguments in function argument lists.
Parse named structure member initializers.
|
|
Show more detail about nested types.
|
|
type definitions (they always go to the outernmost entry).
Make type and symbol printout a lot prettier, and more
C-like.
|
|
proper values.
Make macro re-declaration legal if the new and old
values match.
|
|
placeholder LICENSE file.
|
|
confused and ugly, but it will slowly be getting there. I think.
|
|
the entry is the first or last.
Make printouts prettier by using the new iterator functionality.
|
|
Fix up function argument list to use a proper symbol list.
|
|
|
|
EXPR_SIZEOF with the token being "alignof").
Remove stale debug printouts.
|
|
parse is right.
|
|
|
|
symbol expansion (ie no argument-handling yet).
Mark the EOF token as being on a new line, to make preprocessing simpler.
|
|
conditional expression ( x ? y : z ) and gcc statement expressions. Fix
complex typenames. Add some rudimentary parsing of inline asms.
This parses most of a kernel "sched.c" with all header files. It still gets
some declarations wrong, though (in particular, it accepts type specifiers
in the pointer declaration that should only accept type _qualifiers_).
|
|
|
|
'switch' statements.
|
|
|
|
function pointers). Still missing enum initializer parsing, but we
fake it for now.
This actually parses the header files, and stumbles only when it starts
seeing its first real statements (it can do expression statements, but
that's about it).
|
|
|