summaryrefslogtreecommitdiffstatshomepage
AgeCommit message (Collapse)AuthorFilesLines
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>
2019-12-10add testcase for expansion of default initializersLuc Van Oostenryck2-0/+39
Currently, constant_symbol_value() is doing the expansion of a constant initializer when an explicit one is found but nothing is done for the default/implicit ones. Add a testcase to illustrate this. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-12-10split testcases for type punning & constant initializer expansionLuc Van Oostenryck5-5/+66
Several issues were covered by the same testcase. Fix this by splitting the testcases. Also, rename these testcases to a more descriptive name. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-12-09Merge branch 'premature-examine' into nextLuc Van Oostenryck2-1/+28
* fix premature examination of dereferenced object
2019-12-09fix premature examination of dereferenced objectLuc Van Oostenryck2-1/+28
in the fixes 696b243a5ae0 ("fix: evaluate_dereference() unexamined base type"), the pointer's examination was done prematurely, before the undereferenceable types are filtered out. This allows to examine the base abstract types when the expression was in fact not dereferenceable. Fix that by moving the examination to the top of the SYM_PTR's case since only pointers are concerned. Fixes: 696b243a5ae0 ("fix: evaluate_dereference() unexamined base type") Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-12-09Merge branch 'bitfield-size'Luc Van Oostenryck3-10/+40
* improve diagnostic messages concerning bitfields
2019-12-09Merge branch 'no-std-includes'Luc Van Oostenryck2-3/+2
* testsuite: avoid standard includes in the tests
2019-12-09Merge branch 'cleanups'Luc Van Oostenryck1-1/+1
* remove redundant to degenerate()
2019-12-04Merge branch 'stdc-version'Luc Van Oostenryck2-35/+40
* add support for '-std=c17/c18' This is mainly an excuse for cleaning the associated code and to easily test 'strict' vs. 'gnu'.
2019-12-04cgcc: only define __CYGWIN32__ for -m32 buildsRamsay Jones1-1/+3
'__CYGWIN32__' is wrongly defined on 64-bit Cygwin. Fix this by only defining it when $m32 is set and set $m32 when i386 is selected. Signed-off-by: Ramsay Jones <ramsay@ramsayjones.plus.com> Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-12-01teach sparse about C17Luc Van Oostenryck2-0/+15
No real support is done here (or is needed) but the __STDC_VERSION__ will return the correct value. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-12-01separate definition of __STDC_NO_ATOMICS__ and friends from C11Luc Van Oostenryck1-3/+5
The definition of __STDC_NO_ATOMICS__ and friends will also be needed for C17. Move these definitions outside of the switch statement. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-12-01simplify definition of __STRICT_ANSI__Luc Van Oostenryck1-8/+2
Currently, the definition of __STRICT_ANSI__ is done in the same switch statement used for __STDC_VERSION__. However, this lead to some repetions that can be avoided if moved outside of the switch. Move the definition of __STRICT_ANSI__ out of the switch statement and guard it by testing the absence of STANDARD_GNU. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-12-01reorganize the __STDC_VERSION__/__STRICT_ANSI__ switch statementLuc Van Oostenryck1-8/+5
Move some of the cases so that each STANDARD_GNU* is just under the its corresponding STANDARD_C*. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-30bitfield: display the bitfield name in error messagesLuc Van Oostenryck3-12/+10
Diagnostics related to a bitfield and issued after parsing didn't display the bitfield name because it was not available. Now that that the name is available, use it in error messages since it helps to find the origin of the problem. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-30bitfield: keep the bitfield identLuc Van Oostenryck1-0/+1
While issuing a diagnostic related to a bitfield, it's useful to display the bitfield's name. Unfortunately, this name is not stored in the symbol and thus is only available during parsing. Fix this by adding the ident to the symbol initialization. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-30bitfield: oversized bitfields are errorsLuc Van Oostenryck2-3/+4
Till now, a bitfield with a width bigger than its base type only caused a warning but this should be considered as an error since it's generally impossible to emit correct IR code for it. Fix this by issuing an error instead and marking the width as invalid. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-30bitfield: don't warn twice on invalid widthLuc Van Oostenryck1-3/+2
At parsing time, bitfields with invalid width have their size set to -1 but at examination time this size is interpreted as an unsigned value, causing a second warning. Fix this by avoiding to cast the size to an unsigned variable. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-30bitfield: add testcases for invalid bitfield widthLuc Van Oostenryck1-0/+31
Add some testcases before making related changes. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-28remove redundant degenerate() in compatible_assignment_types()Luc Van Oostenryck1-1/+1
In compatible_assignment_types(), the source expression is first degenerated before calling check_assignment_types(). But this is not needed since check_assignment_types() must anyway do the call to degenerate(). So, remove the redundant call to degenerate(). Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-28testsuite: avoid standard includes in the testsLuc Van Oostenryck2-3/+2
These headers are often complex and full of implementation specificities. They have no place in the testsuite. So, remove these includes and replace them by the prototype of the function being used. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-28cgcc: fix definition of 'linux' macroRamsay Jones1-1/+1
During a call to add_specs('linux'), cgcc adds several macro definitions to the sparse command line. In particular, it provides the incorrect definition: '-Dlinux=linux'. This bug was introduced in commit 807f74466b (<no title>, 2004-08-13), while moving some calls to add_pre_buffer() around in lib.c. This was then moved out of sparse, into cgcc, by commit cf2bde63a6 (<no title>, 2004-10-05), where the definition was copied verbatum. Fix this macro definition to read '-Dlinux=1' instead. Signed-off-by: Ramsay Jones <ramsay@ramsayjones.plus.com> Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-28alt definition for STANDARD_GNU89 & friendsLuc Van Oostenryck1-3/+6
It may be useful to known the base standard and if we're using the gnu extensions but as these are defined it can only be done on a case-by-case basis. Change these defines so that: * the GNU extensions is the least significant bit * the versions can be easily compared with <, >, <= and >= Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-28allow to test the standard version outside of lib.cLuc Van Oostenryck2-7/+12
Since semantics and supported features can differ between standard version we may need the supported version. Allow this by moving the variable 'standard' and the corresponding enum definition to lib.h Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-28simplify initialization of WdeclarationafterstatementLuc Van Oostenryck1-14/+3
In preparation for supporting C17 flags, remove unneeded STANDARD_... cases and remove the impossible default assert(0). Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-28cgcc: add support for riscv64Luc Van Oostenryck1-0/+3
Sparse itself already add support for it, so add support for it in the wrapper too. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-28arch: fix wchar_t & wint_t for openbsdLuc Van Oostenryck1-0/+4
These are only for native build and I don't know if anyone is using sparse on openbsd, but for completeness and ease of testing let's get them right for sparse too. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-28arch: add missing predefines for PPCLuc Van Oostenryck1-0/+3
The macros __PPC, _ARCH_PPC & _ARCH_PPC64 are predefined by GCC for powperpc (well, it seems __PPC isn't anymore but it was, at least on my old toolchain for ppc32). So, do the same here too. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-28arch: add missing predfines: __amd64 & __amd64__Luc Van Oostenryck1-0/+2
These seem to be defined whenever the __x86_64 and __x86_64__ macros are defined. So, do the same here too. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-28cgcc: filter-out -msize-long & -msize-llp64Luc Van Oostenryck1-0/+1
These options are sparse-specific and shouldn't be passed to GCC. Reported-by: Ramsay Jones <ramsay@ramsayjones.plus.com> Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-28spec: replace lllong_ctype by int128_ctypeLuc Van Oostenryck4-15/+15
Sparse knows about __int128_t, __uint128_t & __int128. However, internally, these types are treated as a kind of 128-bit 'long long long' type. It's mainly a question of variable naming, but these types are also displayed by show_typename() as 'long long long' which can't be parsed back, neither by GCC, nor even by sparse itself. So, rename the variables to use 'int128' and let show_typename() display these types as '[signed|unsigned] __int128'. Reported-by: Ramsay Jones <ramsay@ramsayjones.plus.com> Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-28Merge branch 'arch-cleanup' into masterLuc Van Oostenryck5-47/+76
2019-11-28arch: add note for 128-bit long double on mips64Luc Van Oostenryck1-0/+2
On mips64, the 'new' ABIS have 128-bit long doubles while the 'old' and the embedded ABIs use 64-bit. Add a note for this, since currently the -mabi flag is not handled. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-28arch: sparc32 on SunOS/Solaris uses 128-bit long doublesLuc Van Oostenryck1-1/+4
On 32-bit sparc running SunOS or Solaris, long doubles are 128-bit, not 64-bit. Add a special case to handle this. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-28arch: fix wchar_t & wint_t on SunOS/SolarisLuc Van Oostenryck1-1/+6
On 32-bit sparc running SunOS or Solaris, wchar_t and wint_t are long, not uint or int. Add a special case to handle this. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-28arch: use a variable for the OSLuc Van Oostenryck4-11/+41
There are a few OS-specific settings and handling them with #ifdef is 1) ugly, 2) can only work with when specifically built for this OS (either a native or cross-build). So, use a variable to hold the OS and initialize it to the one used to compile sparse. This avoid the ugly #ifdef and allow simpler transition if if the future sparse would take the OS in parameter (maybe as triple). Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-28arch: add predefines for INT128 only on supported archsLuc Van Oostenryck2-2/+13
The predefines for INT128 were added unconditionally for all archs but only the 64-bit ones support them. Fix this by issuing the the predefines only on 64-bit archs. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-28arch: (almost) all platforms simply use int for int32Luc Van Oostenryck1-13/+0
The known execptions are: * ARM with the bare-metal eabi * MIPS64 with the n32 ABI But these two are not really supported yet. So, for now, int32 & uint32 can siply be set to int & uint. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-28arch: char32_t should be the same as uint32_t, not uintLuc Van Oostenryck1-1/+1
When the predefine for char32_t was added, it was made to correspond 'unsigned int' with the commit message saying some archs use 'unsigned long'. In fact, it appears that char32_t is always uint32_t (on the archs & OSes I'm using to look at this). So, simply predefine __CHAR32_TYPE__ like uint32_t is. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-27Merge branch 'arm-hf' into masterLuc Van Oostenryck9-215/+328