Age | Commit message (Collapse) | Author | Files | Lines |
|
lintian (a linter for Debian packages) warns:
N: This manual page uses the \' groff sequence. Usually, the intent to
N: generate an apostrophe, but that sequence actually renders as a an acute
N: accent.
N:
N: For an apostrophe or a single closing quote, use plain '. For single
N: opening quote, i.e. a straight downward line ' like the one used in
N: shell commands, use \(aq.
I'm not following its advice but stick to ' as is done in other places
of sindex.1.
Signed-off-by: Uwe Kleine-König <uwe@kleine-koenig.org>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
Acked-by: Alexey Gladkov <gladkov.alexey@gmail.com>
|
|
Hurd doesn't define PATH_MAX but is needed by pre-process.c
and sindex.c.
pre-process.c had already its local define but sindex doesn't.
So, allow sindex to build on Hurd and avoid possible problems
with some future tools by moving the default define of 4096
for it to lib.h where it will be visible for all code.
Reported-by: Uwe Kleine-König <uwe@kleine-koenig.org>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Inlining in sparse works slightly differently than what my
mental model is: the body is only evaluated after the inline
expansion. IOW, an inline function is not evaluated until it
is effectively inlined. That's fine but it means that generic
expressions also need to be handled during the inlining.
However, since the body of inline functions is evaluated just
after inline expansion, so (recursively) copying the expression
and its type - expression map is quite useless here.
So, just copy the expression itself and its control expression
to 'isolate' them from evaluation, evaluate it and then just
copy the selected expression.
Reported-by: kernel test robot <lkp@intel.com>
Reported-by: Peter Zijlstra <peterz@infradead.org>
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>
|
|
Change dissect to report ctags-like kind passed in sym->kind.
Currently only v,f,s and m kinds are possible.
SYM_UNION doesn't differ from SYM_STRUCT and has ->kind = 's'.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Currently, the tree inlining is done very early, during the
evaluation phase. This means that the inlining is done even
if the corresponding call belong to a sub-expression that
will be discarded during the expansion phase.
Usually this is not a problem but in some pathological
cases it can lead to a huge waste of memory and CPU time.
So, move this inline expansion to ... the expansion phase.
Also, re-expand the resulting expression since constant
arguments may create new opportunities for simplification.
Note: the motivation for thsi is a pathological case in the
kernel where a combination of max_t() + const_ilog2() +
roundup_pow_of_two() + cpumask_weight() + __const_hweight*()
caused Sparse to use 2.3Gb of memory. With this patch
the memory consumption is down to 247Mb.
Link: https://marc.info/?l=linux-sparse&m=158098958501220
Link: https://lore.kernel.org/netdev/CAHk-=whvS9x5NKtOqcUgJeTY7dfdAHc
Reported-by: Randy Dunlap <rdunlap@infradead.org>
Originally-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Now that we have dissect_ctx do_statement(STMT_RETURN) can use
base_type(dissect_ctx->ctype.base_type) instead.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
examine_fn_arguments() silently degenerates function arguments into
pointers but dissect doesn't do evaluate_symbol_list(), that is why
do_sym_list(type->arguments) can report the bogus definitions.
Test case:
void extf(int MUST_NOT_BE_REPORTED);
typedef void (fptr_t)(int MUST_NOT_BE_REPORTED);
void func1(fptr_t fptr) {}
void func2(typeof(extf) fptr) {}
void func3(void) { typeof(extf) fptr; };
void func4(void (fptr)(int MUST_NOT_BE_REPORTED)) {}
without this patch:
4:6 def func1 void ( ... )
4:12 func1 def fptr void ( ... )
2:23 fptr def MUST_NOT_BE_REPORTED int
5:6 def func2 void ( ... )
5:19 func2 --- extf void ( ... )
5:12 func2 def fptr void ( ... )
1:11 fptr def MUST_NOT_BE_REPORTED int
6:6 def func3 void ( ... )
6:27 func3 --- extf void ( ... )
6:33 func3 def fptr void ( ... )
1:11 fptr def MUST_NOT_BE_REPORTED int
7:6 def func4 void ( ... )
7:12 func4 def fptr void ( ... )
7:24 fptr def MUST_NOT_BE_REPORTED int
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Points to the current function or to the global variable in case of
compound initializer.
Kill the ugly test-dissect.c:storage() and change print_usage() to
report dissect_ctx->ident instead.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
When _Atomic was introduced, it was treated, for most purposes,
like the other qualifiers.
However, it's best to consider _Atomic as an qualifier only for
syntaxic reasons. In particular, an _Atomic type may have different
size and alignment that its corresponding unqualified type.
Also, an _Atomic type is never compatible with its corresponding
unqualified type, and thus, for type checking, this qualifier must
never be ignored.
Fix this by removing MOD_ATOMIC from MOD_QUALIFIER. This,
essentially, has the effect to stop to ignore MOD_ATOMIC when
comparing types.
Fixes: ffe9f9fef003d29b65d29b8da5416aff72baff5a
Repoted-by: Ramsay Jones <ramsay@ramsayjones.plus.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
To report where is the member of struct/union defined.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
This makes dissect.c a bit more readable.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Change deanon() to always initialize base->ident when parent != NULL
but still return false to avoid the pointless ->r_symdef().
Test-case:
struct {
union {
int x;
};
} var = {
{ .x = 0 },
};
before this patch:
1:8 s def :var
5:3 g def var struct :var
5:3 g -w- var struct :var
6:12 s -w- ?.x int
after:
1:8 s def :var
5:3 g def var struct :var
5:3 g -w- var struct :var
6:12 s -w- :var.x int
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Preparation. Change mk_name() to initialize base->ident itself, simplify it,
and rename to deanon().
Also change examine_sym_node() to accept "struct symbol *parent" rather than
"struct ident *root". Currently it is only used as ->ident holder, but this
will be changed.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Change report_member() to not call ->r_member(mem) if !mem->ident.
This can only happen in initializer, the output gives no useful info
but looks like a bug. Test-case:
struct {
union {
int x;
};
} var = {
{}
};
before this patch:
1:8 s def :var
5:3 g def var struct :var
5:3 g -w- var struct :var
6:9 s -w- :var.? union <noident>
after:
1:8 s def :var
5:3 g def var struct :var
5:3 g -w- var struct :var
We also need to change no_member() to ensure we still report the bad
initializers, this will be cleanuped later.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Each time domtree_build gets called, extraneous/duplicated child nodes
get left in the bb->doms ptrlist. This is because the existing children
are not cleared from bb->doms before rebuilding it.
In addition to consuming memory, the extraneous child nodes result
in a malformed dominance tree.
The following 3 line patch fixes this problem by freeing the dominator
tree before rebuilding it.
Signed-off-by: Xan Phung <xan.phung@gmail.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Signed-off-by: John Levon <john.levon@joyent.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
The SPARCV9 compile check needs to look for __sparcv9 on some systems,
and should also define "sparc".
Signed-off-by: Toomas Soome <tsoome@me.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
GCC defines these, so should we.
Signed-off-by: John Levon <john.levon@joyent.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Signed-off-by: John Levon <john.levon@joyent.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
As per:
https://gcc.gnu.org/onlinedocs/gcc-4.6.3/gcc/Symbol_002dRenaming-Pragmas.html
we should set this define.
Signed-off-by: John Levon <john.levon@joyent.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Only on UNIX-like OSes are __unix__ & __unix predefined, so it's needed
to easily test if the OS is UNIX-like or not.
Let's do this cheaply by moving all the define of UNIX-like OSes
after the define for 'generic UNIX': OS_UNIX.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
If nothing more specific matches but __unix__ or __unix is defined,
use OS_UNIX as the native OS.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Sparse knew about OpenBSD & NetBSD but didn't detected them.
Until now, that's it.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
The detection of the native OS was done in a strange order.
Now, do this alphabetically.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
When detecting SunOS, '&&' was used instead of '||'.
Fix that.
Fixes: 6bca188679d235ddbad2e97aa3e4186a4730686e
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
GCC adds predefines for some symbols lying in the user's namespace,
like "linux" or "sparc", but only if the selected dialect is not one
of the standard ones.
Add an helper, predefine_nostd(), for these.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
* move arch specificities in their own files
* better support of arch specificities
|
|
do_show_type() checks sym->type inside the "if (!sym || ...)" block.
While at it, remove the trailing whitespaces.
Fixes: 0fe7ebb9 ("show-parse: do not display base type's redundant specifiers")
Reported-by: Alexey Gladkov <gladkov.alexey@gmail.com>
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Fix some embarrassing typos.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
* improve diagnostic message about wrong redeclaration
|
|
* tidy-up of typeof expansion
|
|
* improve expansion of constant symbols
|
|
* fix testcase with non-constant initializer
|
|
These 2 top-level declarations had a non-constant initializer.
Fix that by moving them into a function.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
arch_target now points to a structure holding all the
arch-specificities. So, arch_mach is not needed anymore.
Remove arch_mach.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
The predefine for INT128 is still done with the generic
predefines but are arch-specific.
So, set a new flag for each arch supporting int128
and use this to determine if the predefine must be
issued or not.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Now that each supported arch has its own target file,
move the predefines for cmodel, which are arch-specific,
to the target files.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Now that each supported arch has its own target file,
move the arch-specific predefines to these files too.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
This is for completeness and only useful for S390 which is not
exactly the most common arch. But since it's now easy to do
this kind of thing ...
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Before initaializing the builtin types some 'finalizations' are
needed. target_ini() already does most of this.
So, move the arch-specific content of handle_arch_finalize()
into the corresponding target files and the generic part to
target_init().
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
So, the 2 tables indexed by arch are next to each other,
both in target.c, making easier to add a new arch.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
lib.c and even more so, target.c, become cluttered by the
arch specific type initialization.
It would be better to move this to arch-specific files,
move the generics target related helpers to target.c
and have sparse_initialize() to just call these helpers.
For doing this:
* introduce a struct to hold the configurations for each arch,
* move the arch-specific type initialization to separate files,
* make target.c generic.
Also change the default types to LP64.
Note: this is the first step to better handle other arch
specificities like the predefines or the handling
of some options.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
The spec names 'ppc64+{be,le}' had the '+' to force them
to be internal names but are also useful as external names
(it helps to make systematic testing of the arch-specific code).
So rename them to 'ppc64{be,le}'.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
The current message is very long (in most cases the position
of the previous declaration is past the 80th column) and,
while saying that the types differ, doesn't show these types.
Change this by splitting the message in 2 parts:
- first, on the current position, the main message
and the type of the current declaration.
- then the type of the previous declaration on its
own position.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
is_bitfield_type() is one of the few type-testing helper
based on get_sym_type(). But get_sym_type() test for SYM_NODE
and SYM_ENUM, which is not needed here.
So, simply test for SYM_BITFIELD.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
No functional changes here, just moving the code for the
conversion of SYM_TYPEOFs in its own function, in preparation
for some further changes.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
SYM_TYPEOFs are expanded at examination time.
However, classify_type() does its own expansion of SYM_TYPEOFs.
Worse, it does this differently (address space & noderef are
not removed)..
So, to enforce the same expansion, also use examine_symbol_type()
to do the expansion in classify_type().
Note: it's not sure that it's currently possible to have
SYM_TYPEOFs to expand in classify_type().
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Two testcases had their command wrongly terminated by ';'.
Fix this by removing this ';'.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
evaluate_string() leaves the strings it creates as unexamined
& unevaluated. More exactly, they are examined and evaluated
(they have correct size & type) but not marked as such.
This doesn't seem to really matter but shows up when auditing
if classify_type() is always used on examined symbols.
So, mark the strings as examined and evaluated since their
size & type are known.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Currently, in expand_dereference(), the dereference of a symbol with
a complex type is considered as costing as high as a non-symbol
because it's not recognised it's a symbol.
However, both cases should have exactly the same cost since they
address calculation amounts to 'symbol + offset'.
So, instead of taking in account a single level of
symbol + offset
let's use a loop for this in order to handle
symbol [+ offset]*
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
When doing loads simplification for a location where
floats & integers are mixed, loads are systematically
replaced with the value of their dominating memop (this
checks if the corresponding write or load overlaps).
However, this must not be done if the involved operations
are doing some form of integer/float type punning.
Fix this by refusing to convert load of an integer by a
previous float value or the opposite.
Note: another way to describe this problem would be to say
that floats need to have their own memory operations:
OP_FSTORE & OP_FLOAD
or that instructions need to have some form of 'machine type'
in addition of the size (like clang's i32/f32, ...).
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Currently, constant_symbol_value() is doing the expansion
of a constant initializer when an explicit one is found
but nothing is done if the initilizer is an implicit one.
Fix this by:
* adding an helper to lookup the corresponding type from
offset;
* using this helper to get the correct kind for the value:
- a 0-valued EXPR_VALUE for integers
- a 0.0-valued EXPR_FVALUE for floats.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Currently, the expansion of constant initializers is done
whenever the offset in the initializer match the one
being expanded.
However, it's not correct to do this expansion of an
integer with the initializer for a float and vice-versa.
Fix this by adding the corresponding tests to the other
tests of the value.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Currently, the expansion of constant initializers is done
whenever the offset in the initializer match the one
we're expanding.
However, it's not correct to do this expansion if their
size doesn't match since in this case the value of one
doesn't represent the value of the other.
Fix this by adding a check for the size.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Symbols which have their address taken (with the 'addressof'
operator: &) are marked as such (with the modifier MOD_ADDRESSABLE).
But degenerated arrays and functions have their address implicitly
taken.
MOD_ADDRESSABLE is used to prevent to replace a symbol dereference
nto the value used to initialize to it. For example, in code like:
static int foo(void)
{
int x[2] = { 1, 2 };
return x[1];
}
the return expression can be replaced by 2. This is not the case
case if the array is first passed in a function call, like here:
extern void def(void *, unsigned int);
static int bar(void)
{
int x[2] = { 1, 2 };
def(x, sizeof(x));
return x[1];
}
Fix this by marking degenerated arrays (and functions) as also
being addressable.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
mark_addressable() is used to track if a symbol has its
address taken but does not take in account the fact that
a symbol can be accessed via one of its subfields.
A failure occurs in case like:
struct { int a; } s = { 3 };
...
def(&s.a);
return s.a;
where 's' is not marked as being addressable and so the
the initializer will be expanded and the return expression
will always be replaced by 3, while def() can redefine it.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
This is just moving the 3 lines of code to mark a symbol
as addressable in a speparate function.
This is a preparatory step for one of the next patches.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Constant expansion of symbols with a complex type is not done
like for simpler ones. Only the first-level EXPR_INITIALIZER
is handled.
Add some testcases for this.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Currently, in expand_dereference(), the dereference of a symbol with
a complex type is considered as costing as high as a non-symbol
because it's not recognised it's a symbol.
Add a testcase for this.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Sparse can't do this yet.
So, add a testcase for it.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Once a symbol has its address taken, a lot of simplifications
must be avoided because the symbol can now be modified via
a pointer.
This is currently done but the symbol addressability
does not take in account the fact that a symbol can be
accessed via one of its subfields.
Add a testcase to illustrate this.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
An array or a function that degenerates into a pointer
has its address implicitly taken since the result is
equivalent to '&array[0]' or '&fun'.
So, the corresponding symbol needs to be marked as
addressable, like when its address is explicitly taken.
Add a testcase to illustrate this.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|