aboutsummaryrefslogtreecommitdiffstatshomepage
AgeCommit message (Collapse)AuthorFilesLines
2020-08-01sindex.1: Use ' for a plain quote charmaint-v0.6.2Uwe Kleine-König1-2/+2
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 &#92;(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>
2020-08-01fix build on Hurd which doesn't define PATH_MAXLuc Van Oostenryck2-4/+4
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>
2020-08-01generic: fix missing inlining of generic expressionLuc Van Oostenryck2-0/+18
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>
2020-06-23gensel: remove unneeded test/uninitialized warningLuc Van Oostenryck1-3/+1
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>
2020-06-21Sparse v0.6.2v0.6.2Luc Van Oostenryck1-1/+1
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-06-21doc: update release notesLuc Van Oostenryck1-3/+9
Update the release notes with the changes since v0.6.2-rc1. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-06-21doc: add some info to the main pageLuc Van Oostenryck1-10/+30
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>
2020-06-20doc: switch to the sphinx_rtd themeLuc Van Oostenryck1-1/+8
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>
2020-06-20Merge branch 'fix-gensel'Luc Van Oostenryck3-3/+50
2020-06-20gensel: validate the type of the associationsLuc Van Oostenryck2-0/+24
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>
2020-06-20gensel: controlling expression must be pointer-convertedLuc Van Oostenryck2-2/+3
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>
2020-06-19gensel: controlling expression must be lvalue convertedLuc Van Oostenryck1-1/+4
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>
2020-06-19gensel: use temporary variable in generic selectionLuc Van Oostenryck1-2/+4
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>
2020-06-19gensel: add testcases from DR481Luc Van Oostenryck1-0/+17
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>
2020-06-18Sparse v0.6.2-rc2v0.6.2-rc2Luc Van Oostenryck1-1/+1
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-06-18Merge branch 'genmacro'Luc Van Oostenryck5-61/+151
* support for builtin macros with arguments * support for __has_feature() & __has_extension()
2020-06-18pre-process: make __has_{attribute,builtin}() true builtin macrosLuc Van Oostenryck3-56/+32
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>
2020-06-18pre-process: add support for __has_feature() & __has_extension()Luc Van Oostenryck3-1/+58
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>
2020-06-18ir-validate: remove orphan commentsgarritfra1-7/+0
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>
2020-06-18Merge branch 'misc'Luc Van Oostenryck4-16/+16
2020-06-18pre-process: add support for builtin macrosLuc Van Oostenryck2-0/+36
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>
2020-06-18pre-process: rename 'expander' into 'expand_simple'Luc Van Oostenryck2-5/+5
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>
2020-06-18pre-process: add testcases for __has_feature() & __has_extension()Luc Van Oostenryck1-0/+21
The support for these builtin macros is incoming. So, add some testcases for them. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-06-16testsuite: be less paranoid with timeoutLuc Van Oostenryck1-1/+1
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>
2020-06-16build: let the C++ compiler be configurableLuc Van Oostenryck1-1/+2
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>
2020-06-16Merge branch 'sindex-build'Luc Van Oostenryck1-0/+7
2020-06-16doc: reformulate an item in the TODOLuc Van Oostenryck1-2/+2
One of the item wasn't even grammatical. Reformulate it. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-06-16doc: fix markup in types.rst (s/```/``/)Luc Van Oostenryck1-9/+9
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>
2020-06-16doc: fix some typosLuc Van Oostenryck1-2/+2
Fix some silly typos. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-06-16doc: update TODOLuc Van Oostenryck1-1/+0
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>
2020-06-16doc: copy the old relnotes hereLuc Van Oostenryck15-0/+2731
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>
2020-06-16doc: add intro stolen from the wikiLuc Van Oostenryck1-0/+37
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>
2020-06-15doc: minimal version for Sphinx is 1.7Luc Van Oostenryck1-1/+1
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>
2020-06-16doc: fix code-block formatting in v0.6.2 relnotesLuc Van Oostenryck1-1/+1
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>
2020-06-14attribute: parse but ignore enum attributesLuc Van Oostenryck1-0/+4
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>
2020-06-14doc: reindent the sublists in the relnotesLuc Van Oostenryck1-69/+67
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>
2020-06-14doc: correct some spellingRamsay Jones2-11/+11
Signed-off-by: Ramsay Jones <ramsay@ramsayjones.plus.com> Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-06-14sindex: use -stdc=gnu99Luc Van Oostenryck1-0/+1
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>
2020-06-14sindex: minimal version for sqlite3 is 3.24Luc Van Oostenryck1-0/+6
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>
2020-06-13Sparse v0.6.2-rc1v0.6.2-rc1Luc Van Oostenryck1-1/+1
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-06-13doc: show the ToC in the sidebarLuc Van Oostenryck1-6/+1
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>
2020-06-13doc: add release notes for incoming v0.6.2Luc Van Oostenryck3-0/+115
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>
2020-06-12doc: add link to the doc on kernel.org in the man pageLuc Van Oostenryck1-0/+4
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>
2020-06-12doc: move meta-doc to its own sectionLuc Van Oostenryck1-1/+7
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>
2020-06-12doc: add some doc for the type systemLuc Van Oostenryck2-0/+166
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>
2020-06-12ctype: keep modifiers & base_type closeLuc Van Oostenryck1-1/+1
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>
2020-06-12Merge branch 'builtins'Luc Van Oostenryck12-245/+320
* add support for arch-specific builtins
2020-06-12testsuite: plain chars are never compatible with [un]signed charsLuc Van Oostenryck1-0/+19
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>
2020-06-12arch: add specificities for AlphaLuc Van Oostenryck6-9/+37
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>
2020-06-12arch: add specificities for BlackfinLuc Van Oostenryck6-5/+31
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>
2020-06-12arch: add specificities for Nios2Luc Van Oostenryck6-5/+36
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>
2020-06-12builtin: add support for arch-specific builtinsLuc Van Oostenryck2-0/+8
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>
2020-06-12builtin: unify the 2 tables of builtinsLuc Van Oostenryck2-95/+50
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>
2020-06-12builtin: use a table for the builtinsLuc Van Oostenryck4-200/+227
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>
2020-06-12builtin: can be initialized laterLuc Van Oostenryck2-1/+1
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>
2020-06-09nios2: add declaration for __builtin_{rd,wr}ctl()Luc Van Oostenryck1-0/+5
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>
2020-06-09generic: fix crash when nothing matchLuc Van Oostenryck2-2/+29
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>
2020-06-06pre-process: remove unneeded declaration of show_token_sequence()Luc Van Oostenryck1-2/+0
Remove this declaration which follows the definition. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-06-06pre-process: fix a compiler array subscript type warningRamsay Jones1-1/+1
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>
2020-06-03univ-init: set default to -Wno-universal-initializerLuc Van Oostenryck2-5/+7
'{ 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>
2020-06-03univ-init: scalar initializer needs some additional checksLuc Van Oostenryck5-7/+49
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>
2020-05-30evaluate: mark evaluate_generic_selection() as staticRamsay Jones1-1/+1
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>
2020-05-28add support for _GenericLuc Van Oostenryck8-0/+336
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>
2020-05-27testsuite: add testcase for duplicated local definitionsLuc Van Oostenryck1-0/+28
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>
2020-05-27add an option to suppress warning 'no newline at EOF'Luc Van Oostenryck4-1/+11
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>
2020-05-21Merge branch 'univ'Luc Van Oostenryck7-0/+50
* conditionally accept { 0 } without warnings
2020-05-21Merge branch 'bad-goto'Luc Van Oostenryck31-63/+617
* 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.
2020-05-21univ-init: conditionally accept { 0 } without warningsLuc Van Oostenryck6-0/+43
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>
2020-05-21Merge branch 'fun-attr'Luc Van Oostenryck7-55/+55
* improve handling of function attributes * separate modifiers into type/declaration * add support for attributes 'unused' & 'gnu_inline' * simplify parsing of inline/__tls/__visible
2020-05-21Merge branch 'doc-update'Luc Van Oostenryck3-28/+28
* doc: do not use obsolete sphinx's AutodocReporter
2020-05-21bad-label: respect attribute((unused))Luc Van Oostenryck4-1/+19
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>
2020-05-21bad-label: mark labels as used when neededLuc Van Oostenryck3-6/+8
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>
2020-05-21bad-label: check for unused labelsLuc Van Oostenryck2-1/+8
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>
2020-05-21bad-goto: check declaration of label expressionsLuc Van Oostenryck3-2/+1
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>
2020-05-21bad-goto: extract check_label_declaration()Luc Van Oostenryck1-6/+16
Extract this helper from evaluate_goto_statement(). Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-05-21bad-goto: label expression inside a statement expression is UBLuc Van Oostenryck1-0/+1
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>
2020-05-21bad-goto: jumping inside a statement expression is an errorLuc Van Oostenryck8-10/+27
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>
2020-05-21scope: give a scope for labels & gotosLuc Van Oostenryck3-1/+12
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>
2020-05-21scope: add is_in_scope()Luc Van Oostenryck2-0/+11
Add an helper to check if a scope is included into another one. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-05-21scope: let labels have their own scopeLuc Van Oostenryck3-2/+21
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>
2020-05-21scope: s/{start,end}_symbol_scope/{start,end}_block_scope/Luc Van Oostenryck3-10/+10
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>
2020-05-21scope: __label__ is specialLuc Van Oostenryck1-2/+1
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>
2020-05-21scope: __func__ is specialLuc Van Oostenryck1-3/+2
__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>
2020-05-21scope: extract bind_symbol_with_scope() from bind_symbol()Luc Van Oostenryck2-4/+10
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>
2020-05-21scope: move scope opening/ending inside compound_statement()Luc Van Oostenryck2-9/+6
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>
2020-05-21scope: no memset() needed after __alloc_scope()Luc Van Oostenryck1-2/+0
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>
2020-05-21bad-goto: catch labels with reserved namesLuc Van Oostenryck2-1/+2
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>
2020-05-21bad-goto: do not linearize function with undeclared labelsLuc Van Oostenryck1-0/+1
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>
2020-05-21bad-goto: simplify testing of undeclared labelsLuc Van Oostenryck1-1/+2
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>
2020-05-21bad-goto: reorg test in evaluate_goto_statement()Luc Van Oostenryck1-3/+7
No functional changes here, only changing the code structure to prepare more incoming changes. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-05-21bad-goto: do not linearize if the IR will be invalidLuc Van Oostenryck2-1/+2
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>
2020-05-21bad-goto: reorganize testcases and add some moreLuc Van Oostenryck18-13/+332
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>
2020-05-21bad-goto: add testcases for linearization of invalid labelsLuc Van Oostenryck1-0/+19
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>
2020-05-21bad-goto: add testcase for 'jump inside discarded expression statement'Luc Van Oostenryck2-0/+57
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>
2020-05-21misc: always use the node for current_fnLuc Van Oostenryck2-3/+3
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>
2020-05-21misc: s/fntype/rettype/Luc Van Oostenryck1-5/+6
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>
2020-05-21misc: fix testcase typeof-safeLuc Van Oostenryck1-7/+20
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>
2020-05-19testsuite: add a few testcases for nested functionsLuc Van Oostenryck1-0/+43
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>
2020-05-19attribute: 'externally_visible' is just another 'declaration' modifierLuc Van Oostenryck4-18/+3
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>
2020-05-19attribute: 'inline' is just another 'declaration' modifierLuc Van Oostenryck2-4/+4
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>
2020-05-19attribute: '__tls' is just another 'declaration' modifierLuc Van Oostenryck2-5/+5
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>
2020-05-18univ-init: add helper match_token_zero()Luc Van Oostenryck1-0/+7
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-05-17attribute: teach sparse about attribute((gnu_inline))Luc Van Oostenryck3-4/+7
But for the moment do nothing special with it. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-05-17attribute: separate modifiers into type/declarationLuc Van Oostenryck2-6/+11
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>
2020-05-17attribute: add support for unusedLuc Van Oostenryck3-3/+6
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>
2020-05-17attribute: allow some attribute to be present multiple timesLuc Van Oostenryck2-1/+3
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>
2020-05-17attribute: add helper apply_mod() and use itLuc Van Oostenryck1-7/+9
to avoid duplicated code checking for ... duplicated modifiers! Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-05-17attribute: sort the table of modifier namesLuc Van Oostenryck3-17/+17
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>
2020-05-15misc: fix typo: s/OS_UNIX/OS_NATIVE/Luc Van Oostenryck1-1/+1
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-05-15doc: remove done item from the TODOLuc Van Oostenryck1-6/+0
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-05-15doc: fix the warnings when building the docLuc Van Oostenryck2-17/+23
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>
2020-05-15doc: do not use obsolete sphinx.ext.autodoc.AutodocReporterLuc Van Oostenryck1-5/+5
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>
2020-05-14show-parse: null pointer dereference in do_show_type()Davidson Francis1-1/+1
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>
2020-05-14build: fix LLVM version detectionQuentin Monnet1-1/+2
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>
2020-04-13Merge branch 'fix-atomic-type'Luc Van Oostenryck3-25/+41
* fix type compatibility of _Atomic types
2020-04-11do not use expr->left for conditionalsLuc Van Oostenryck1-1/+1
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>
2020-03-24add support for GCC's __auto_typeLuc Van Oostenryck5-0/+159
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>
2020-03-20Merge branch 'unreach'Luc Van Oostenryck9-9/+135
* generate OP_UNREACH from __builtin_unreachable() * add OP_UNREACH after calls to __noreturn functions
2020-03-20teach sparse to linearize __builtin_unreachable()Luc Van Oostenryck4-3/+7
__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>
2020-03-20add support for linearization of builtinsLuc Van Oostenryck3-1/+40
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>
2020-03-20add an implicit __builtin_unreachable() for __noreturnLuc Van Oostenryck2-1/+10
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>
2020-03-20add instruction OP_UNREACHLuc Van Oostenryck3-0/+7
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-03-20add testcases for OP_UNREACHLuc Van Oostenryck4-7/+74
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-03-18sindex: Add option to search by locationAlexey Gladkov2-2/+80
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>
2020-03-16cpp: fix redefinition of a macro during its own expansionLuc Van Oostenryck2-1/+22
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>
2020-03-15cpp: remove extra newlines during macro expansionLuc Van Oostenryck4-9/+17
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>
2020-03-15cpp: silently allow conditional directives within a macroLuc Van Oostenryck3-4/+55
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>
2020-03-15make "directive in macro's argument list" a warningOleg Nesterov2-5/+5
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>
2020-03-15teach sparse about -pedantic/-WpedanticLuc Van Oostenryck2-0/+15
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-03-11Add semantic index utilityAlexey Gladkov4-1/+1249
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>
2020-03-02dissect: enforce toplevel() if SYM_STRUCT was not definedOleg Nesterov1-0/+3
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>
2020-02-20dissect: fix sym_is_local(SYM_STRUCT/UNION/ENUM)Oleg Nesterov2-3/+4
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>
2020-02-20struct_union_enum_specifier: always initialize sym->scopeOleg Nesterov3-0/+7
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>
2020-02-13dissect: kill no_member()Oleg Nesterov1-15/+14
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>
2020-02-13dissect: don't set ->ident = '?' in no_member()Oleg Nesterov2-6/+7
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>
2020-02-13dissect: use show_ident() to print dctx->identOleg Nesterov1-6/+3
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>
2020-02-13dissect: move __sparse() callsite from test-dissect.c to dissect.cOleg Nesterov3-12/+6
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>
2020-02-13dissect: introduce sym_is_local() for reporterOleg Nesterov3-5/+20
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>
2020-02-10dissect: enforce sym->kind='f' when it looks like a function callOleg Nesterov2-2/+4
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>
2020-02-10dissect: set sym->kind for reporterOleg Nesterov2-9/+44
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>
2020-02-09do the tree inlining during expansion phaseLuc Van Oostenryck4-22/+19
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>
2020-02-09inline: add some testsLuc Van Oostenryck4-0/+108
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-02-07dissect: kill return_typeOleg Nesterov1-5/+4
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>
2020-02-07dissect: change do_symbol(SYM_FN) to check base_type->stmt != NULLOleg Nesterov1-3/+14
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>
2020-02-07dissect: introduce dissect_ctxOleg Nesterov3-15/+25
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>
2020-02-06fix type compatibility of _AtomicLuc Van Oostenryck3-25/+41
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>
2020-02-06dissect: introduce reporter->r_memdef()Oleg Nesterov3-1/+18
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>
2020-02-06dissect: disallow NULL pointers in struct reporterOleg Nesterov1-17/+7
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>
2020-02-06dissect: change deanon() to handle the !node caseOleg Nesterov1-1/+3
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>
2020-02-06dissect: turn mk_name() into deanon()Oleg Nesterov1-10/+14
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>
2020-02-06dissect: don't report anonymous members in initializersOleg Nesterov2-6/+5
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>
2020-01-29domtree: domtree_build() creates extraneous bb->doms entriesXan Phung1-0/+4
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>
2020-01-23predefine "i386" if neededJohn Levon1-0/+1
Signed-off-by: John Levon <john.levon@joyent.com> Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-01-22correct sparcv9 definesToomas Soome2-1/+2
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>
2020-01-22pre-define __unix__ and friendsJohn Levon1-0/+6
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>
2020-01-22add necessary defined for sunos-derived systemsJohn Levon1-0/+7
Signed-off-by: John Levon <john.levon@joyent.com> Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-01-22define __PRAGMA_REDEFINE_EXTNAMEJohn Levon1-0/+2
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>
2020-01-22allow to easily test if the OS is UNIX-likeLuc Van Oostenryck1-2/+2
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>
2020-01-22detect OS_UNIX as native OSLuc Van Oostenryck1-0/+3
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>
2020-01-22detect native OS on OpenBSD & NetBSDLuc Van Oostenryck1-0/+4
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>
2020-01-22detect native OS in alphabetical orderLuc Van Oostenryck1-6/+6
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>
2020-01-22fix typo when detecting SunOSLuc Van Oostenryck1-1/+1
When detecting SunOS, '&&' was used instead of '||'. Fix that. Fixes: 6bca188679d235ddbad2e97aa3e4186a4730686e Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-01-22add predefine_nostd()Luc Van Oostenryck2-0/+9
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>
2020-01-21Merge branch 'arch-spec'Luc Van Oostenryck18-373/+673
* move arch specificities in their own files * better support of arch specificities
2020-01-16show_parse: avoid null pointer dereference in do_show_type()Oleg Nesterov1-3/+3
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>
2019-12-30ptrlist: fix typosLuc Van Oostenryck1-3/+3
Fix some embarrassing typos. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-12-17Merge branch 'msg-wrong-redecl' into nextLuc Van Oostenryck5-18/+65
* improve diagnostic message about wrong redeclaration
2019-12-17Merge branch 'eval-typeof' into nextLuc Van Oostenryck2-24/+27
* tidy-up of typeof expansion
2019-12-17Merge branch 'expand-init' (early part) into nextLuc Van Oostenryck18-22/+355
* improve expansion of constant symbols
2019-12-17Merge branch 'top-level-init' into nextLuc Van Oostenryck1-2/+8
* fix testcase with non-constant initializer
2019-12-17fix testcase with non-constant initializerLuc Van Oostenryck1-2/+8
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>
2019-12-16arch: arch_mach is not needed anymoreLuc Van Oostenryck3-4/+0
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>
2019-12-16arch: use arch_target for INT128's predefineLuc Van Oostenryck9-9/+9
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>
2019-12-16arch: move cmodel predefines to the target files.Luc Van Oostenryck4-50/+21
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>
2019-12-16arch: move target-specific predefines to the target files.Luc Van Oostenryck11-85/+169
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>
2019-12-16arch: use an arch-specific default for -msize-longLuc Van Oostenryck3-1/+3
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>
2019-12-16arch: move handle_arch_finalize() into target_init()Luc Van Oostenryck5-34/+32
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>
2019-12-16arch: move parsing of --arch=<ARCH> to target.cLuc Van Oostenryck3-46/+58
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>
2019-12-16arch: move arch-specificities to their own filesLuc Van Oostenryck16-167/+401
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>
2019-12-16cgcc: rename 'ppc64+{be,le}' to 'ppc64{be,le}'Luc Van Oostenryck1-5/+5
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>
2019-12-16cgcc: add support for riscv32Luc Van Oostenryck1-0/+3
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-12-15improve diagnostic message about wrong redeclarationLuc Van Oostenryck5-18/+65
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>
2019-12-15typeof: avoid using is_bitfield_type()Luc Van Oostenryck1-2/+2
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>
2019-12-15typeof: extract examine_typeof() from examine_symbol_type()Luc Van Oostenryck1-20/+21
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>
2019-12-15typeof: do not let classify_type() do its own SYM_TYPEOF expansionLuc Van Oostenryck1-4/+2
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>
2019-12-15testcase: remove trailing ';' in commandsLuc Van Oostenryck2-2/+2
Two testcases had their command wrongly terminated by ';'. Fix this by removing this ';'. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-12-15mark strings as examined & evaluatedLuc Van Oostenryck1-0/+4
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>
2019-12-10fix cost of dereference of symbols with complex typeLuc Van Oostenryck2-6/+5
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>
2019-12-10fix simplify_loads() when doing type punningLuc Van Oostenryck3-2/+11
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>
2019-12-10fix expansion of initializer (default)Luc Van Oostenryck2-3/+63
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>
2019-12-10fix expansion of initializer (mismatching type)Luc Van Oostenryck3-2/+4
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>
2019-12-10fix expansion of initializer (mismatching size)Luc Van Oostenryck2-5/+4
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>
2019-12-10degenerated arrays & functions are addressable tooLuc Van Oostenryck3-1/+16
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>
2019-12-10fix addressability marking in evaluate_addressof()Luc Van Oostenryck2-1/+2
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>
2019-12-10extract mark_addressable() from evaluate_addressof().Luc Van Oostenryck1-4/+9
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>
2019-12-10add test for constant expansion of complex initializerLuc Van Oostenryck3-0/+53
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>
2019-12-10add test for dereference cost of symbol with complex typeLuc Van Oostenryck1-0/+21
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>
2019-12-10add test for union castLuc Van Oostenryck1-0/+27
Sparse can't do this yet. So, add a testcase for it. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-12-10add testcase for addressability of 'complex' symbolsLuc Van Oostenryck1-0/+24
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>
2019-12-10add testcase for addressability of degenerated symbolLuc Van Oostenryck1-0/+18
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>