| Age | Commit message (Collapse) | Author | Files | Lines |
|
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
On arm, int32_t & uint32_t seem to be differently defined on bare-metal.
Fix this in the target-specific file.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Now that the OS can be specified to sparse via an option (--os=$OS)
and that sparse knows about their specificities, it's no more
needed or useful to also define them in cgcc.
So, remove from cgcc the OS-specificities known to sparse (a few
few exotic ones remain for now) but ensure that the info about
the correct OS is passed to sparse.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
For CygWin, GCC defines some pseudo-specifiers like '__cdecl',
'__stdcall' or '_thiscall'. Some of these are already defined by cgcc.
So, add these predefines to sparse itself.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Predefine macros like '__OpenBSD__', ... for the three BSDs,
CygWin and Darwin (those for Linus and SunOS were already defined).
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
On Solaris, at least on sparc32, chars are unsigned.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
On NetBSD & OpenBSD, some types are not defined like on Linux.
Fix this.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
On Darwin, '__unix__' & '__unix' doesn't seem to be predefined.
Don't ask me why.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
These are already defined in cgcc but not yet by sparse
itself. So, add them now.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
This is not needed when doing native 'compilation' but is
quite handy when testing the predefined types & macros.
The supported OSes are: 'linux', 'freebsd', 'openbsd', 'netbsd'
'darwin', 'sunos', 'cygwin' and a generic 'unix'.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Currently, the maximum number of displayed errors is 100.
This is nice to not be flooded with error messages when things
are really broken but in some situation, for example testing,
it is desirable to have all error messages.
So, teach sparse about '-fmax-errors=COUNT'.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
The problem is seems to be related with evaluate_dereference()
where all mods are dropped when the type is a node.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Those are cases that sparse should warn about but doesn't.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
You can assign a '<type>[]' to a 'const <type> *'. Likewise,
you can assign a '<type>[][N]' to a 'const <type> (*)[N]' but
sparse doesn't like this.
Analyzed-by: Ard Biesheuvel <ardb@kernel.org>
Reported-by: Herbert Xu <herbert@gondor.apana.org.au>
Link: https://lore.kernel.org/linux-crypto/20200709120937.GA13332@gondor.apana.org.au/
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
More, specifically, split the 'init' method into a common part
and add one for each of the i386 (32-bit) and another one for 64-bit.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Most keywords have a variant with the leading nd trailing
double-underscore. Some have also a variant with only the
leading underscores. But only the identifier change, the
remaining of the information is duplicated for them.
So, use some macros to define the corresponding entries
without duplication.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Reorder the keywords to make them even more logically organized.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
With time, the keyword table has become quite hard to read.
So, split the table in 2: one for NS_TYPEDEF and one for NS_KEYWORD.
This allows to remove one argument, making more place for those
that really matter.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Depending on the endianness, predefine '__ARMEL__' or '__ARMEB__'.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Depending on the endianness, predefine '__AARCH64EL__' or '__AARCH64EB__'.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
It seems that in the next version of the standard, the
second argument of _Static_assert() will be optional.
Nice. Let sparse already support this now.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
For Nios2, some predefines with the trailing double underscores
were added but the variant with only the leading ones are also
used. So add these too.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
On Nios2, long double are (of course) only 64 bits width.
Specify this in the target file.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
* predefine: fix multi-token predefine
* predefine: add helper predefine_{strong,weak}()
* predefine: avoid add_pre_buffer() for targets
* predefine: simplify add_pre_buffer()
|
|
The RISC-V architecture has some predefined macros
to specify which extensions are supported.
So, now that these extensions are known via the '-march'
options, add the corresponding predefines.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
The RISC-V architecture has quite a bit of extensions.
Some of these correspond to a predefined macro and thus
parsing correctly the '-march' flag can be important.
So, teach sparse how to parse this flag for RISC-V.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
The option '-march' is not one of the common option but is
architecture specific.
So, teach sparse to delegate the parsing of this option to
the targets.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
pre_buffer_begin & pre_buffer_end are the head and the tail of
a singly chained list. As such, it's slightly easier to not
keep a pointer on the last element but a pointer where the
next element should be written.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Avoid add_pre_buffer() and use one of the predefine...()
variant instead.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
A lot of predefined macros are just set to the value '1' and
of them have a name that is not statically known. OTOH, the
function predefine() is designed for a statically known name
but a variable value.
Add a set of helpers to cover the first case: predefine_strong()
and predefine_weak().
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
The function predefine() and its variants are only valid
if they define a single-token value.
However, when a type is signed, predefine_min() will produce
a multi-token value.
Fix this by using add_pre_buffer() instead of predefine().
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
The function predefine() and its variants are only valid
if they define a single-token value.
Add a testcase for this.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
When doing a shift operation, both arguments are subjected to
integer promotion and the type of the result is simply the type
of the promoted left operand. Easy.
But for a shift-assignment, things are slightly more complex:
-) 'a >>= n' should be equivalent to 'a = a >> n'
-) but the type of the result must be the type of the left
operand *before* integer promotion.
Currently, the linearization code use the type of the right
operand to infer of the type of the operation. But simply changing
the code to use the type of the left operand will also be wrong
(for example for signed/unsigned divisions). Nasty.
For example, the following C code:
int s = ...;
s >>= 11U;
is linearized as a logical shift:
lsr.32 %r2 <- %arg1, $11
while, of course it's an arithmetic shift that is expected:
asr.32 %r2 <- %arg1, $11
So, add a testcase for these.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
The Kernel Test Robot reports a problem on microblaze.
The cause is that __MICROBLAZEEL__ is not defined. However, the real
problem is that sparse has no support at all for this architecture.
So, add the minimal support for microblaze.
Link: https://lore.kernel.org/lkml/202007060542.hNfoTcsC%25lkp@intel.com
Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
A lot of content in lib.c have been added by just appending at the
bottom of what was already present. As consequence, things are now
not well organized at all, especially when related to the options.
So, reorganize things a little bit here:
* move all helpers on top
* keep things alphabetically sorted
* move options parsing in a separate file
* move predefine-related stuff in a separate file
|
|
Now lib.c contains almost nothing else than library entrypoints.
Move a small utility, hexval(), to utils.c to complete this cleanup.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
lib.c contains 2-3 helpers for parsing. Move them to parse.c.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
The test-inspect tool uses GTK to visualize symbol nodes. It turns
out that gtk_init() implicitly sets the locale to the system locale,
and since Sparse uses strtod()/strtold() for parsing floating-point
numbers in expressions, parsing becomes locale-dependent.
Since the system's locale may be different from "C", test-inspect
may be unable to parse float numbers.
Steps to reproduce:
$ echo "int main(void){3.14;}" > test.c
$ LC_ALL="fr_FR.UTF-8" test-inspect test.c
Output:
test.c:1:16: error: constant 3.14 is not a valid number
Fix this by resetting the locale right after gtk_init().
Signed-off-by: Davidson Francis <davidsondfgl@gmail.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
* sindex: avoid a warning with 'case -1:'
|
|
When parsing the format, there is a 'case -1:' which:
* seems to be there only for the following label (but mixing
labels with cases, like here, is OK).
* on architectures where chars are unsigned, the compiler complains:
warning: case label value is less than minimum value for type
So, remove the unneeded 'case -1:' and use an explicit 'default:'
to catch invalid formats. Also, align the label with the cases,
it looks nicer so.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
Reviewed-by: Alexey Gladkov <gladkov.alexey@gmail.com>
|
|
* teach sparse about arch specific asm constraints
* teach sparse about memory operand constraints for ppc & s390
|
|
* remove pre-C99 compatibility layer for BSD & Solaris
|
|
The 'Q', 'R', 'S' & 'T'' asm constraint are used for for memory
operands on S390 but only 'Q' belong to the 'common constraints'.
Fix this by handling the 3 others with an arch-specific method.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
The 'Z' asm constraint is used for doing IO accessors on PPC but
isn't part of the 'common constraints'. It's responsible for
more than half of all warnings (with defconfig + allyesconfig).
Fix this by handling this constraint in a specific method for PPC.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
When evaluating asm operands it must be known if they correspond
to a memory operand or not in order to process/ignore the 'noderef'
attribute.
This is done for operands specified with the common constraints
but not for the machine specific constraints.
So, add support for processing machine specific constraints.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
This flag facilitates the creation of testcases for preprocessing.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
When inlining multiple times a function which contains an undeclared
function call, multiple error messages are issued. More annoyingly,
only the first one is meaningful, the other ones doesn't even show
the incriminated identifier:
error: undefined identifier '...'
error: not a function <noident>
Part of the problem is that the first message is displayed with
expression_error() which also sets the expression to &bad_ctype.
This change the way how the expression is handled when re-evaluated.
Fix this by avoiding the evaluation of function calls that already
evaluate to bad_ctype: it's known that an error message have already
been issued for them and that nothing good can done with them.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Now that option parsing have moved to a separate file, move
everything related to predefined macros to a separate file too.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
The declarations and definitions of the variables corresponding to
the options half-sorted half-unsorted.
Sort them a little more.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
lib.c contains to much things and is too hard to keep tidy.
So, move everything related to option parsing in it's own file.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
This is just to isolate the details about which switch need an
extra 'finalization' in a separate function in preparation
to moving all the parsing code in a separate file.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
'tabstop' is unusual in the sense that it's one the few (the only?)
variable defined via an option flag which is not declared in "lib.h"
but in "token.h". This for to have to include "token.h" in the code
doing the parsing of the options ...
Move this declaration to "lib.h".
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
It's a stylistic detail but a lot of the strcmp() calls used for
the processing of the options are written 'strcmp (...)'. Two
other functions calls are also in the case.
Reformat them to the usual style for function calls: without
the space between the function name and the arguments.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
These function have probably been added in 'historical order' and
as result it's not easy to quickly see where they're defined.
Change this arranging them in asciibetical order.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
The helpers for parsing the options are often situated just above the
first function using them. As result, these helpers can be found a bit
everywhere in the code, it's messy and doesn't help to reuse these helpers.
So, move all these helpers to the top.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
So, use 'flag' instead of 'warning' for variable and function names.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
-Wsparse-error should not be enabled with -Wsparse-all, this is
special cased in the condition in loop handling -Wsparse-all.
However, the condition already handle warnings forced to off.
So instead of explicitly checking for &Wsparse_error, it's enough
to force Wsparse_error off.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
This allows to reuse these enums in earlier helpers.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Since handle_onoff_switch() can be used for other flags than the
warnings, the processing of -Wsparse-all should move elsewhere.
So move it into handle_switch_W().
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
This makes things slightly easier to use.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
None of the BSDs need "compat-bsd.c" anymore. Same for
Solaris and "compat-solaris.c", even for Solaris 10.
The only problem was lacking C99's strtold() but it seems
that this was solved many years ago and they're all doing
quite fine with "compat-linux.c".
So, simply replace the content of these file by an include of
"compat-linux.c".
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
The subcommand 'format help' is broken because the of the way
arguments are parsed without validating the number of arguments.
Fix this by parsing all arguments (even if there is only one)
and validate the number of arguments at the end of the loop.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
It seems that some system libraries expect __STDC_HOSTED__ to
be always defined.
So, teach sparse the options flags -f[no-]{hosted,freestanding}
and define __STDC_HOSTED__ accordingly.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
When evaluation generic selections, it is tested if the type in
the selection is a SYM_NODE or not, but:
* all these are SYM_NODE
* the variable for the base type would be uninitialized
if not a SYM_NODE.
So, remove the test and unconditionally set the base type.
Reported-by: Ramsay Jones <ramsay@ramsayjones.plus.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Update the release notes with the changes since v0.6.2-rc1.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Add some info about:
* how to get sparse
* how to install it,
* the mailing list and how to report bugs.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
The generated documentation used Sphinx's classic/default theme
but the one from readthedocs ('rtd', the same as used for the kernel)
looks nicer, especially in the sidebar, and is not as large.
So, for now, switch to the 'rtd' theme.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
|
|
The type in a generic association must correspond to a complete
type and not a variably modified type.
Add validation for this.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Following the resolution of DR481, the controlling expression
of a generic selection must be array-to-pointer converted and
function-to-pointer converted.
Do this by adding a call to degenerate().
Reported-by: Marco Elver <elver@google.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Following the resolution of DR481, the controlling expression
of a generic selection must be lvalue converted. In other words,
the qualifiers must be ignored.
Reported-by: Marco Elver <elver@google.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Use a temporary variable for 'map->type' to make the expressions
in the following patches more readable.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Following the resolution of DR481, the controlling expression
is subject to a few different rules.
Add the testcases from this defect report.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
* support for builtin macros with arguments
* support for __has_feature() & __has_extension()
|
|
The macros __has_atribute() & __has_builtin() are only expanded
in the context of a preprocessor conditional but they should
be expanded like usual user defined macros.
Fix this by using the new infrastructure for builtin macros.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Add the trivial methods for the expansion of these macros with:
c_alignas, c_alignof, c_generic_selections and c_static_assert.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
These comments were wrongly added and then forgotten.
So, remove them.
Signed-off-by: Garrit Franke <garritfranke@gmail.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
|
|
Sparse support the expansion of one-symbol-builtin macros like __FILE__.
It also support builtin macros with an argument, like 'defined()'
or '__has_attribute()'.
However, these last one are only expanded inside a pre-processor
conditional expression. This is correct for 'defined()' but macros
like '__has_attribute()' should be expanded in all contexts,
like user defined macros.
So, add support for the general expansion of such macros.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Sparse support the expansion of one-symbol-builtin macros like
__FILE__ or the pre-processor operator 'defined'. It also supports the
expansion of builtin macros with arguments, like __has_attribute()
but only inside a pre-processor conditional expression.
In preparation of adding the general expansion of these macros,
rename the method 'expander' into 'expand_simple'.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
The support for these builtin macros is incoming.
So, add some testcases for them.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
For some testcases, the testsuite use the command 'timeout'
to ensure that the test finish after a reasonable amount of
time. This is mainly used for some testcases which, in the past,
were stuck in an infinite loop. This the command 'timeout' is
used with an extra option (-k 1s) to issue a second kill signal
in case the first one would have been ignored.
However, this extra option is not supported on all implementations
(Alpine) and its use seems a bit paranoid for sparse.
So, remove this extra option.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
By default, the C compiler is 'gcc' but it can be overridden
on the command line via 'make CC=...'.
However, the C++ compiler (only needed for sparse-llvm) is
hardcoded to 'g++'.
Fix this by allowing to specify the C++ compiler via 'CXX=...'
but keeping 'g++' as the default.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
|
|
One of the item wasn't even grammatical. Reformulate it.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Literal text was marked with ``` but that's a bit excessive.
Fix that by replacing these with ``.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Fix some silly typos.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Support for __builtin_unreachable() was added in commit
d2be323e25c3 ("teach sparse to linearize __builtin_unreachable()")
So, remove this item from the TODO list.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
The releases notes of the versions previously released
are stored on the wiki.
Copy them here too (with minimal changes in the markup),
so that everything is centralized here.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
The wiki has a small introduction but there is none here.
So, copy this introduction from the wiki into the entrypoint
of the documentation (and convert the wikimedia markup
into restructuredtext).
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Because of the changes needed after the removal of the obsolete
sphinx.ext.autodoc.AutodocReporter, the minimal version of Sphinx
is 1.7 (the first one containing switch_source_input()).
So, update this information in the conf file.
Fixes: b741a793e63c0fd4a333cd575ac2339f5a9b2698
Reported-by: Ramsay Jones <ramsay@ramsayjones.plus.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
The small code example at the top was in normal text-style
(which is fine) but was lacking the newline between the two
statements (which is much less fine).
Fix this by using a '::' instead of a ':' to trigger the
literal-code-block-and-more style.
Reported-by: Ramsay Jones <ramsay@ramsayjones.plus.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Currently, sparse is confused when encountering an enum attribute.
Teach sparse about these attributes and, for now, ignore them.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
The html-generated version of the release notes looked
terrible because the used indentation was too small.
Fix this by indenting the sublists by 4 instead of 2
Reported-by: Ramsay Jones <ramsay@ramsayjones.plus.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Signed-off-by: Ramsay Jones <ramsay@ramsayjones.plus.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
sindex use C99 for-loops:
for (int i = 0, ....)
No problem with this but sparse doesn't use this elsewhere yet
and older compilers don't allow C99 by default.
Fix this by adding '-std=gnu99' to the sindex-specific CFLAGS.
Cc: Alexey Gladkov <gladkov.alexey@gmail.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
sindex uses the sqlite3_str API which is only present since version
3.24 of SQLite3.
Fix this by adding some checks in the Makefile and refuse to build
it if the requirement is not met.
Cc: Alexey Gladkov <gladkov.alexey@gmail.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
With the configured theme, 'classic', the table of contents
didn't show up in the sidebar.
It seems it was because 'html_sidebars' was partially set in
conf.py, overhidding the theme defaults.
Fix this by removing 'html_sidebars' from the config.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Currently, the release notes are kept on the wiki which
contains nothing else but a small intro.
The docs are certainly as good as this wiki to keep these
release notes. So, let try this for now.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
The generated doc is hosted on readthedocs.io since a little
while but:
* it wasn't much publicised
* it's now also live on sparse.docs.kernel.org
So, add a link to this doc on the manpage.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
The documentation about the documentation is in the middle of the
documentation about sparse itself.
Move it to its own section.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Sparse's type system, or more exactly the way types are encoded
in Sparse's data structures, is not hard but is also not exactly
immediate to grok.
Here is a modest attempt to document this.
The corresponding generated documentation can be find at:
https://sparse.docs/kernel.org
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
In struct ctype, 'modifiers' & 'base_type' are, by far,
the 2 most frequently used members.
However, `base_type`, the most used, is defined as the last one.
Change this by moving `base_type` as the first one.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
* add support for arch-specific builtins
|
|
In standard C, plain chars are either signed or unsigned but are only
compatible with themselves, not with signed chars nor with unsigned ones.
However, Sparse has this wrong and make them compatible with the
corresponding sign-qualified chars.
So, add a testcase for this.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
The real goal here is in fact to move the alpha-specfic
builtins out of the main builtins table.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
The real goal here is in fact to move the bfin-specfic
builtins out of the main builtins table.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
The real goal here is, in fact, to move the nios2-specfic
builtins out of the main builtins table.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Now that a table is used for the declaration of builtin functions
it's easy to support arch-specific builtins.
The main objective is to not 'pollute' the main table with
arch-specfic entries for uncommon architectures.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Till now, 2 tables are used to initialize builtin functions:
* an older, small one, without type information, used to set
a symbol_op to evaluate and/or expand the ones that have
some associated behaviour.
* a newer and bigger one which only contains what is effectively
the prototype for these builtins in order to avoid warnings
about undeclared functions.
It's kinda annoying to have 2 tables for this, even more so
because most entries in the first table also need to be in the
second one (for arguments type and number checking).
Fix this by:
* adding a field in the second table for the symbol_op
* merging or moving the entries in the first table into
the second one.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
The curent way to declare the builtins is not by using a table
but via a (variadic) function call, one for each builtin.
A table is preferable but a complication for doing this
is that some elements are not constant. For example, 'size_t_ctype'
is dynamically set in the early steps of the type initialization.
Doing a series of function calls allowed to circumvent this.
Fix this by:
* Using a constant temporary alias for non-constant entries. It's the
value of these alias that will be used when registering the builtins.
* using a table to declare the builtin functions.
Note: the motivation for doing this is to be able to add sub-tables
for the arch-specific builtins (and use the same mechanism
as for the main table).
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
The initialization of the buitins can be done later, after
the types have been initialized.
So move the call to init_builtins() to just before declare_builtins().
This will allow some other small improvements.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
These 2 are used for the kernel and the lack of a
declaration is causing problems.
So add the declarations for these 2 builtins.
At the same time also add one for '__builtin_custom_ini()'
since this one may also be used in the kernel.
Note: a better fix should be to move this to target-nios2.c
Link: https://lore.kernel.org/lkml/20200609151329.GU23011@xsang-OptiPlex-9020/
Reported-by: kbuild test robot <lkp@intel.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
The code for the generic selection doesn't take in account
the fact that the default entry could be absent.
Catch the case where nothing matches and issue an error.
Fixes: c100a7ab2504f9e6fe6b6d3f9a010a8ea5ed30a3
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Remove this declaration which follows the definition.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
On cygwin, the <ctype.h> header is written in such a way as to cause
a gcc compiler warning if a plain 'char' is passed to the character
classification macros (in this case isdigit). The result is defined
only if the parameter is representable as an unsigned char, or if it
is EOF.
When passing a 'char' type argument to isdigit(), the compiler warns
like so:
CC pre-process.o
In file included from pre-process.c:33:
pre-process.c: In function ‘predefine’:
pre-process.c:1429:18: warning: array subscript has type ‘char’ [-Wchar-subscripts]
1429 | if (isdigit(buf[0])) {
| ~~~^~~
In order to suppress the warning, cast the argument of isdigit() to
an 'unsigned char' type.
Signed-off-by: Ramsay Jones <ramsay@ramsayjones.plus.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
'{ 0 }' is the standard idiom for the universal zero initializer '{ }'.
But if the '0' is taken literally, warnings can be issued, for exemple
for 'using 0 as NULL pointer' or for 'using a positional initializer'
when the attribute 'designated_init' is used.
These warnings were not intended to be issued for this initializer
and are confusing and annoying when people have to use or want to
use standard code or ignore that '{ }' is fine to use with GCC,
clang or Sparse.
So, set sparse default to -Wno-universal-initializer, suppressing
any warnings caused by using '{ 0 }' instead of '{ }'.
Reference: https://lore.kernel.org/git/e6796c60-a870-e761-3b07-b680f934c537@ramsayjones.plus.com/
Reference: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95379
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Currently, -Wno-universal-initializer is simply implemented
by simply replacing '{ 0 }' by '{ }'.
However, this is a bit too simple when it concerns scalars
initialized with '{ 0 }' because:
* sparse & GCC issued warnings for empty scalar initializers
* initializing a pointer with '{ }' is extra bad.
So, restore the old behaviour for scalar initializers.
This is done by leaving '{ 0 }' as-is at parse time and changing
it as '{ }' only at evaluation time for compound initializers.
Fixes: 537e3e2daebd37d69447e65535fc94e82b38fc18
Thanks-to: Ramsay Jones <ramsay@ramsayjones.plus.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Commit c100a7ab (add support for _Generic, 2020-05-28) added the
function evaluate_generic_selection() as an external symbol, without
providing an external declaration in a header file. This causes
sparse to issue a warning as part of the 'selfcheck' target.
Since this function does not (currently) need to be an external symbol,
mark it as static.
Signed-off-by: Ramsay Jones <ramsay@ramsayjones.plus.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
It's slightly tested but is fine for the latest kernels
like https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git locking/kcsan
Note: a known difference with GCC is that it doesn't make the
distinction between 'signed char' and a plain 'char'
(on platforms where plain char are signed) since it's using
the usual type compatbility like used for assignements.
Reference: lore.kernel.org/r/20200527235442.GC1805@zn.tnic
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Sparse warn when a top-level object is initialized multiple
times but doesn't warn when it's a local object.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Some platforms have some of their system header files missing the
ending newline. Sparse will then warn about it, again and again,
and more important warnings can easily be lost in the noise.
So, add an option flag '-W[no-]newline-eof' to conditionalize
this warning.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
* conditionally accept { 0 } without warnings
|
|
* warn when jumping into statement expressions
* warn when using undefined labels
* warn on defined but unused labels
It's not allowed to do a goto into an expression statement.
For example, it's not well defined what should happen if such
an expression is not otherwise reachable and/or can be optimized
away. For such situations GCC issues an error, clang doesn't
and produce a valid IR but Spare produce an invalid IR with
branches to unexisting BBs.
The goals of the patches in this series are:
*) to detect such gotos at evaluation time;
*) issue a sensible error message;
*) avoid the linearization of functions with invalid gotos.
The implementation principle behind these is to add a new kind
of scope (label_scope), one for the usual function scope of
labels one for each statement expressions. This new scope,
instead of being used as a real scope for the visibility of
labels, is used to mark where labels are defined and where
they're used.
Using this label scope as a real scope controling the
visibility of labels was quite appealing and was the initial
drive for this implementation but has the problem of inner
scope shadowing earlier occurence of labels identically
named. This is of course desired for 'normal' symbols but for
labels (which are normally visible in the whole function
and which may be used before being declared/defined)
it has the disadvantage of:
*) inhibiting the detecting of misuses once an inner scope
is closed
*) allowing several distinct labels with the same name
in a single function (this can be regarded as a feature
but __label__ at block scope should be used for this)
*) create diffrences about what is permssble or not between
sparse and GCC or clang.
|
|
In standard C '{ 0 }' is valid to initialize any compound object.
OTOH, Sparse allows '{ }' for the same purpose but:
1) '{ }' is not standard
2) Sparse warns when using '0' to initialize pointers.
Some projects (git) legitimately like to be able to use the
standard '{ 0 }' without the null-pointer warnings
So, add a new warning flag (-Wno-universal-initializer) to
handle '{ 0 }' as '{ }', suppressing the warnings.
Reference: https://lore.kernel.org/git/1df91aa4-dda5-64da-6ae3-5d65e50a55c5@ramsayjones.plus.com/
Reference: https://lore.kernel.org/git/e6796c60-a870-e761-3b07-b680f934c537@ramsayjones.plus.com/
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
* improve handling of function attributes
* separate modifiers into type/declaration
* add support for attributes 'unused' & 'gnu_inline'
* simplify parsing of inline/__tls/__visible
|
|
* doc: do not use obsolete sphinx's AutodocReporter
|
|
Currently, attributes on labels were simply ignored. This was fine
since nothing was done wth them anyway.
But now that Sparse can give a warning for unused labels it would
be nice to also support the attribute 'unused' not to issues the
warning when not desired.
So, add a small helper around handle_attributes() and use this
instead of skipping the attributes.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
In most cases symbols are automatically marked as being used via
a successfull call to lookup_symbols(), the idea being that the
symbol will be created at its declaration and then any (successfull)
lookup will correspond to an use.
For labels, things are slightly different because labels are
created on-demand via label_symbol() and their use can precede their
'declaration'. And of, course, label_symbol() has no ways to know
if it is used for a definition or an use.
So, fix this by adding an argument to label_symbol(), explictly
telling if the call correspond to an use or not.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Issue a warning if a label is defined but not used.
Note: this should take in account the attribute 'unused'.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Issue an error when taking the address of an undeclared label
and mark the function as improper for linearization since
the resulting IR would be invalid.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Extract this helper from evaluate_goto_statement().
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
More exactly, what is undefined is to jump inside the statement
expression with a computed goto.
Of course, once the address of such a label is taken, it's generaly
impossible to track if it will be used or not to jump inside the
statement expression.
So, for now, handle taking the address of such a label from outside
the statement expression, exactly as if a computed goto is effectively
done from there and so issue an error message and also mark the function
as useless for linearization.
Note: this is only partially correct since:
1) the address could be taken from outside the statement
and never used for a computed goto.
2) the address could be taken from outside the statement
but the corresponding computed goto only done from
inside, which is perfectly fine.
3) the address could be taken from inside but a computed
goto done from outside.
Note: the real problem, like for the regular goto, is that the
statement expression can be eliminated before linearization,
the correspondng gotos corresponding then to branches to
unexistent BBs.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
It's invalid to jump inside a statement expression.
So, detect such jumps, issue an error message and mark the
function as useless for linearization since the resulting IR
would be invalid.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
One way of detecting gotos inside an statement expression
is to use a new kind of scope for the gotos & labels.
Since gotos don't need to have their label predeclared,
nothing can be checked at parsing time but later it can
be checked that a goto doesn't jump inside one of the
label scope created by statement expressions.
So, add additional scope information to gotos and labels
to allow such check to be done.
Note: the label's symbols are still created in the function
scope since they belong to a single namespace.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Add an helper to check if a scope is included into another one.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
It's invalid to jump inside a statement expression.
So, concerning labels & gotos, a statement expression is
like a kind of scope.
So, in preparation for the detection of such jumps, create
these new scopes and open/close them when entering/leaving
statement expressions.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
The functions {start,end}_symbol_scope() haven't been renamed
when separated scope have been introduced for functions & blocks.
But these functions only start & end a block scope.
So, rename them to their more direct name: {start,end}_block_scope().
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Labels declared wth __label__ are special because they must follow
the block scope normally used for variables instad of using the
scope used for labels.
So, use bind_symbol_with_scope() instead of first using bind_symbol()
and then changing the namespace.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
__func__ needs to be in the namepsace for symbols: NS_SYMBOL
but doesn't follow the usual scope rules of them: it always
needs to be declared in the function scope.
So, use bind_symbol_with_scope() instead of first using bind_symbol()
and then changing the namespace.
Also change the comment to better express that it's the scope
that is the unusual thing.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
In most cases, the scope that must be used for a symbol is
given by its namespace.
However, in some situations a different scope must be used.
This is then set, for example by doing the lookup with
the wrong namespace (but corresponding to the desired scope)
and changing it just after to its correct value.
To avoid these contortions, extract from bind_symbol() a version
where the scope can be explicitly given: bind_symbol_with_scope().
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
A compound statement starts and ends a block scope, so
it's better to start & end this scope inside the function
parsing the statement: compound_statement.
The only exception is for the body of a function where
the scope also enclose the parameter declaration but that
is fine since the function is special anyway.
Move the calls to start & close the block scope inside
compound_statement() and directly call statement_list()
for the function body.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
When starting some scopes, the newly allocated struct is
memset'ed with zero but this is unneeded since the allocator
always returns zeroed memory.
Remove the unneeded call to memset().
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
If a reserved name is used as the destination of a goto,
its associated label won't be valid and at linearization
time no BB will can be created for it, resulting in an
invalid IR.
So, catch such gotos at evaluation time and mark the
function to not be linearized.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
It's not possible to produce a valid & correct IR if
the function contains a goto to an undeclared label.
So, try to catch these situations and mark the function
as such, the linearization will then simply ignore it.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
There is no need to do a lookup: checking if the label's
symbol is in the NS_LABEL namespace and is lacking an
associated statement is enough and much simpler.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
No functional changes here, only changing the code structure
to prepare more incoming changes.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
In some error cases, it's not possible to produce a valid &
correct IR for the concerned function. For exemple, if the
AST contains invalid gotos, the CFG will either be invalid
or won't correspond to the erroneous source code.
So, refuse to linearize such functions.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Reorganize the testcases related to the 'scope' of labels
and add a few new ones.
Also, some related testcases have some unreported errors other
than the features being tested. This is a problem since such
tescases can still fail after the feature being tested is fixed
or implemented. So, fix these testcases or split them so that
they each test a unique feature.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
A goto to a reserved or a undeclared label will generate
an IR with a branch to a non-existing BB. Bad.
Add a testcase for these.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
A goto done into an piece of code discarded at expand or
linearize time will produce an invalid IR.
Add a testcase for it.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
At evaluation time and at expansion time, current_fn is set
to the function's base type (SYM_FN) but at parse time it's
set to its parent type (SYM_NODE).
Since current_fn is used to access the corresponding ident,
it should be set to the node type, not the base.
So, always set current_fn to the node type.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
In evaluate_return_expression(), it's checked if the type of
the return statement match the function return type.
But, the variable used to hold this type is named 'fntype'
which is slightly confusing.
So, rename the variable holding the return type to 'rettype'
and only use 'fntype' for the one holding the full function type.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
This testcase was marked as known-to-fail but it was
simply the expected error messages that were missing.
So, slightly reorganize the test a little bit, add the
expected messages and remove the 'known-to-fail' tag.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Sparse doesn't really support nested functions but is
able to parse them correctly.
Add some testcases with them so that it continue to
catch possible errors concerning them.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Now that the distinction is made between type modifiers and
'declaration' modifiers, there is no more reasons to parse
this attribute differently than other attributes/modifiers.
Even more so because this special casing made this attribute
to be ignored when placed after the declarator.
So, use the the generic code for 'declaration modifiers'
to parse this attribute.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Now that the distinction is made between type modifiers and
'declaration' modifiers, there is no more reasons to parse
this attribute differently than other attributes/modifiers.
So, use the the generic code for 'declaration modifiers'
to parse this attribute.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Now that the distinction is made between type modifiers and
'declaration' modifiers, there is no more reasons to parse
this attribute differently than other attributes/modifiers.
So, use the the generic code for 'declaration modifiers'
to parse this attribute.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
But for the moment do nothing special with it.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
When parsing a declaration, type specifiers, qualifiers and other
modifiers are handled by declaration_specifiers(). Some of these
are part of the type being declared but some others only concern
the object in itself. For example, the storage specifiers pertains
to the objects being declared but not their type. Because of this
the storage specifiers need to be processed separately in order to
be correctly applied to the object node. This is done via the helper:
storage_modifier().
However, some attributes are exactly in the same situation (an
obvious example is something like the section attribute).
These attributes should also be moved to the declaration and it's
only because they are currently ignored/without effect that they're
not causing problem in the type.
So generalize storage_modifiers() into decl_modifiers() to extract
all modifiers not pertaining to the type of the declared object.
The modifiers currently concerned are the attributes:
- unused
- pure
- noreturn
- externally_visible
Note: currently this change shouldn't have any effects other
than not showing anymore the "[unused]" when displaying
the type differences in diagnostics.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Add support for the attribute 'unused' (and its double underscore
variant. There is no semantic attached to it but it's now at least
parsed and added to the modifiers.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
A warning is issued when a qualifier or another modifier
is present more than once in a declaration.
This is fine but in the kernel some attributes, for example
'unused' & 'gnu_inline', are sometimes present multiple times
in the same declaration (mainly they are added in the define
used for 'inline'). This then creates a lot of useless noise.
So, use a (now empty) white list to not warn when these attributes
are present multiple times in the same declaration.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
to avoid duplicated code checking for ... duplicated modifiers!
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
It easier to search an item if sorted and this avoid needless
conflict when new items are always added at the end of the table.
So, sort the table but keep the storage modifers first so
that show_typename() & friends still display types as usual.
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>
|
|
It seems that Markdown is now parsed slightly differently and
now generate some warnings.
So tweak the .md files to shut up the warnings.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
sphinx.ext.autodoc.AutodocReporter is obsolete since Sphinx 1.7
and removed in some later versions.
So, replace it by the code suggested in the release notes when
it was obsoleted.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
In do_show_type() the first if statement allows passing null
pointers, which can cause a null pointer dereference in some
cases, which I believe is not the desired behavior.
Fix this by changing the first if statement comparison.
Signed-off-by: Davidson Francis <davidsondfgl@gmail.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
The regex match used for detecting the LLVM version works for versions
with a single-digit major number. Now that LLVM v10 is out, detection
can fail, resulting in sparse-llvm not being built.
Fix detection by extracting the major version number to compare with the
minimum supported.
Signed-off-by: Quentin Monnet <quentin@isovalent.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
* fix type compatibility of _Atomic types
|
|
expr->left & expr->conditional are unioned but 'left'
should only be used for binary operators.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Despite the similarity with typeof, the approach taken here
is relatively different. A specific symbol type (SYM_TYPEOF)
is not used, instead a new flag is added to decl_state, another
one in the declared symbol and a new internal type is used:
'autotype_ctype'. It's this new internal type that will be
resolved to the definitive type at evalution time.
It seems to be working pretty well, maybe because it
hasn't been tested well enough.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
* generate OP_UNREACH from __builtin_unreachable()
* add OP_UNREACH after calls to __noreturn functions
|
|
__builtin_unreachable() is one of the builtin that shouldn't
be ignored at IR level since it directly impact the CFG.
So, add the infrastructure put in place in the previous patch
to generate the OP_UNREACH instruction instead of generating
a call to a non-existing function "__builtin_unreachable()".
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Sparse ignores most builtins. A few of them are directly
interpreted at parsing time (types_compatible_p, offsetof).
Some others are expanded if their argument(s) are constant
but that's all.
However, some of the builtins are significant at the IR
level and shouldn't thus be ignored.
This patch add the support needed for the linearization of
these builtins.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
The semantic of a __noreturn function is that ... it doesn't return.
So, insert an instruction OP_UNREACH after calls to such functions.
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>
|
|
To create plugin for text editor, it may be useful to be able to search
by position in a file.
$ sindex search -l include/uapi/linux/msdos_fs.h:91:8
(---) fs/fat/dir.c 759 1 fat_ioctl_filldir FAT_IOCTL_FILLDIR_FUNC(fat_ioctl_filldir, __fat_dirent)
(r--) fs/fat/dir.c 759 1 fat_ioctl_filldir FAT_IOCTL_FILLDIR_FUNC(fat_ioctl_filldir, __fat_dirent)
(m--) fs/fat/dir.c 759 1 fat_ioctl_filldir FAT_IOCTL_FILLDIR_FUNC(fat_ioctl_filldir, __fat_dirent)
(def) include/uapi/linux/msdos_fs.h 91 8 long d_ino;
$ sindex search -l -m w include/uapi/linux/msdos_fs.h:91:8
(m--) fs/fat/dir.c 759 1 fat_ioctl_filldir FAT_IOCTL_FILLDIR_FUNC(fat_ioctl_filldir, __fat_dirent)
Another use is to get the full name of symbol in case of a high level
of nesting:
$ sindex search -e fs/dcache.c:567
(--r) fs/dcache.c 567 9 __dentry_kill dentry->d_op->d_prune(dentry);
(--r) fs/dcache.c 567 15 __dentry_kill dentry->d_op->d_prune(dentry);
$ sindex search -e --format='%n' fs/dcache.c:567
dentry.d_op
dentry_operations.d_prune
$ sindex search -e --format='%n' fs/dcache.c:567:9
dentry.d_op
Signed-off-by: Alexey Gladkov <gladkov.alexey@gmail.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
The presence of preprocessor directives within the arguments
of a macro invocation is Undefined Behaviour but most of
these directives, like the conditionals, are well-defined
and harmless.
OTOH, the redefinition of a macro during its own expansion makes
much less sense. However, it can be given a reasonable meaning:
* use the initial definition for the macro body
* use the new defintion for its arguments, in text order.
It's what gcc & clang do but Sparse can't handle this
because, during the expansion, a reference to the initial
macro's body is not kept. What is used instead is what is
currently associated with the macro.
Fix this by using the body associated with the macro at
the time of its invocation.
Testcase-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
During macro expansion, Sparse doesn't strip newlines from
the arguments as required by 6.10.3p10 and done by gcc & clang.
So, remove these newlines.
Note: the current behaviour may make the preprocessed output
more readable (and so may be considered as a feature).
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
The presence of preprocessor directives within the arguments
of a macro invocation is Undefined Behaviour [6.10.3p11].
However, conditional directives are harmless here and are
useful (and commonly used in the kernel).
So, relax the warning by restricting it to non-conditional
directives.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
The presence of preprocessor directives within the arguments
of a macro invocation is Undefined Behaviour [6.10.3p11].
Sparse issues an error for this but most often the result is
well defined and is not a problem, processing can continue
(for example, when the directive is one of the conditional ones).
So, downgrade this sparse_error() to warning() (especially
because issuing an error message can hide those coming later).
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
sindex is the simple to use cscope-like tool based on sparse/dissect.
Unlike cscope it runs after pre-processor and thus it can't index the
code filtered out by ifdef's, but otoh it understands how the symbol
is used and it can track the usage of struct members.
To create an index for your linux kernel configuration:
$ make C=2 CHECK="sindex add --"
Now, to find where a definition of the pid field from the task_struct
structure:
$ sindex search -m def task_struct.pid
(def) include/linux/sched.h 793 11 pid_t pid;
default output format:
SOURCE-FILE \t LINE-NUMBER \t COLUMN \t IN FUNCTION NAME \t CODE LINE
To find where this field changes:
$ sindex search -m w task_struct.pid
(-w-) fs/exec.c 1154 6 de_thread tsk->pid = leader->pid;
(-w-) kernel/fork.c 2155 3 copy_process p->pid = pid_nr(pid);
To get only filenames and line number you can change output format:
$ sindex search -f '%f:%l' -m w task_struct.pid
fs/exec.c:1154
kernel/fork.c:2155
Current limitations:
* inline functions are ignored;
* enums are ignored;
* unknown #include leads to a fatal error.
Suggested-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Alexey Gladkov <gladkov.alexey@gmail.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
A separate change for documentation purposes.
Test-case:
void func(void)
{
struct UNDEFINED x;
x.member = 0;
}
output:
1:6 def f func void ( ... )
3:26 func def . v x struct UNDEFINED
4:9 func -w- . v x struct UNDEFINED
4:10 func -w- . m UNDEFINED.member bad type
but in this case is_sym_local(UNDEFINED) = F makes more sense, most
probably this struct was defined somewhere else but __sparse() didn't
see its definition.
Change lookup_member() to set type->scope = file_scope if !symbol_list.
This is not 100% correct, but struct_union_enum_specifier() does the
same check with the following comment:
// The following test is actually wrong for empty
// structs, but (1) they are not C99, (2) gcc does
// the same thing, and (3) it's easier.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Now that struct_union_enum_specifier() always sets sym->scope we can
simplify sym_is_local(sym) and rely on toplevel() even if sym is type.
Test-case:
// copied from linux kernel
# define __force __attribute__((force))
#define WRITE_ONCE(x, val) \
({ \
union { typeof(x) __val; char __c[1]; } __u = \
{ .__val = (__force typeof(x)) (val) }; \
__write_once_size(&(x), __u.__c, sizeof(x)); \
__u.__val; \
})
void func(int *p)
{
WRITE_ONCE(*p, 0);
}
before this patch the widely used WRITE_ONCE() generates a lot of spam which
can't be filtered out using sym_is_local(),
11:6 def f func void ( ... )
11:11 func def . v p int *
13:9 def s :__u
13:9 --- . v p int *
13:9 def m :__u.__val int
13:9 def m :__u.__c char [1]
13:9 func def . v __u union :__u
13:9 func -w- . v __u union :__u
13:9 func -w- m :__u.__val int
13:9 func --- . v p int *
13:9 func --r f __write_once_size bad type
13:9 func -r- . v p int *
13:9 func -r- . v __u union :__u
13:9 func m-- m :__u.__c char [1]
13:9 func --- . v p int *
13:9 func --- . v __u union :__u
13:9 func --- m :__u.__val int
plus it triggers warning("no context") in test-dissect.c. With this patch
the only "nonlocal" report is __write_once_size() call.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Currently it is not possible to figure out the scope of the private
struct/union/enum type, its ->scope is NULL because bind_symbol() is
not called.
Change struct_union_enum_specifier() to set sym->scope = block_scope
in this case, this is what bind_symbol() does when type has a name.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
It is trivial and has a single caller, lookup_member().
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
no_member() sets ->ident = built_in_ident("?") for the case when dissect()
can't figure out the name of initialized member. For example:
struct EMPTY {} var = { 10 };
the output:
1:25 var -w- m EMPTY.? bad type
This is useful, but dissect should not dictate the policy. Let r_member()
decide how this case should be reported.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
I didn't know show_ident() uses 4 buffers for the string it returns and
thus it is safe to call it twice in a row.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
This is more flexible. For example, we can change dissect() to inspect
file_scope->symbols too without changing its callers.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Can be used to filter out the usage of local variables.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
A separate change for documentation purposes.
dissect() tries to work even if the parsed code is buggy or incomplete,
thus it makes sense to change expr_symbol() to set kind = 'f' when it
likely looks like a function name.
We can safely abuse EXPR_SYMBOL->op to pass the hint to expr_symbol(),
it must be 0.
Test-case:
void call(void)
{
func();
}
before this patch
1:14 def f call void ( ... )
3:17 call --r v func bad type
after:
1:14 def f call void ( ... )
3:17 call --r f func bad type
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|