aboutsummaryrefslogtreecommitdiffstatshomepage
AgeCommit message (Collapse)AuthorFilesLines
2020-10-20sub: canonicalize (0 - x) into -xLuc Van Oostenryck2-1/+4
Not really a simplification in itself but it make some other simplification a little easier (already because there is one argument less to be matched). Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-20sub: reorganize handling of OP_{ADD,SUB}s with constant rightsideLuc Van Oostenryck1-9/+11
This is a preparatory step for more interesting changes later. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-20reassoc: simplify (x # C) # K --> x # eval(C # K)Luc Van Oostenryck2-1/+5
Do this simplification once for all associative binops. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-20constants must be truncated to the operation's sizeLuc Van Oostenryck2-2/+1
At expansion phase, when simplified, all constants are truncated to the size of the operations that generate them. This should be done during simplification too because: *) if some constants are sometimes truncated and sometimes sign-extended, CSE will miss some opportunities. *) it's not possible to sign-extend them because it's not always known if the constant is used in a signed context or not. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-20add a flag to identify commutative & associative opsLuc Van Oostenryck3-48/+76
The way how the functions doing the simplification of commutative or associative binops are called is simple but complicates the simplification of a specific binop. Fix this by adding a flag to the opcode table to identify the commutative and the associative binops and using this flag to call or not the functions doing the corresponding simplification. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-20unop: add helper replace_with_unop()Luc Van Oostenryck1-0/+14
Some simplifications reduce to transforming a binop into an unop. Add an helper for making this change easier and more readable. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-20unop: add helper eval_unop()Luc Van Oostenryck1-0/+12
Currently, eval_op() only do the evaluation of binops but unops need sometimes to be evaluated too. So, teach eval_op() about OP_NEG & OP_NOT and add a new helper, eval_unop() for making it easier to use with unops. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-20extract eval_op() from eval_insn()Luc Van Oostenryck1-5/+9
eval_insn() can be handy when there is an existing instruction to evaluate but it can happen that there isn't one, only pseudos. Allow to reuse the evaluation code by using a new API: eval_op() extracted from eval_insn() and taking all its input as arguments (opcode, size, src1 & src2). Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-20let switch_pseudo() return REPEAT_CSELuc Van Oostenryck1-1/+2
It make some uses easier and more compact. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-20add testcases about OP_ADD & OP_SUB simplificationsLuc Van Oostenryck15-0/+171
Add some testcases about basic simplifications of additions and subtractions. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-19Merge branch 'builtin-atomic' into nextLuc Van Oostenryck6-32/+136
* fix and complete the evaluation of atomic builtins
2020-10-19builtin: add support for remaining atomic builtinsLuc Van Oostenryck1-0/+5
Nothing special for these ones, just plain functions with fixed types and arity. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-19builtin: add support for __atomic_clear()Luc Van Oostenryck2-0/+16
The first argument is supposed to be a pointer to a bool, but of course, a volatile qualified pointer should be accepted too. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-19builtin: add builtin type: [volatile] pointer to boolLuc Van Oostenryck2-0/+4
This builtin type is needed for __atomic_clear()'s prototype. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-19builtin: add support for others generic atomic builtinsLuc Van Oostenryck1-0/+10
Reuse the generic method for all these builtins. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-19builtin: add support for __atomic_add_fetch(), ...Luc Van Oostenryck1-0/+12
Reuse the generic method for all these builtins. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-19builtin: add predefines for __ATOMIC_RELAXED & friendsLuc Van Oostenryck1-0/+7
The __atomic_*() builtins take an int argument to specify the desired memory ordering. The different admissible values are predefined by the compiler, so do that too for Sparse. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-19builtin: __sync_synchronize() too is variadicLuc Van Oostenryck1-1/+1
This builtin was marked as taking no argument but is in fact variadic (like all the __sync_* builtins). Fix this by marking it as being variadic. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-19builtin: fix evaluation of __sync_lock_releaseLuc Van Oostenryck1-1/+1
It must use the generic method too. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-19builtin: evaluate __sync_*_fetch*()Luc Van Oostenryck2-13/+37
Reuse the generic method for all these builtins. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-19builtin: make eval_sync_compare_and_swap() more genericLuc Van Oostenryck1-17/+32
Most __sync_* or __atomic_* builtin functions have one or more arguments having its real type determined by the first argument: either the same type (a pointer to an integral type) or the type of the object it points to. Currently, only __sync_{bool,val}_compare_and_swap() are handled but lots of very similar variants would be needed for the others. So, make it a generic function, able to handle all these builtins. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-19Merge branch 'warn-address-builtin' into nextLuc Van Oostenryck2-10/+19
2020-10-18Sparse v0.6.3v0.6.3Luc Van Oostenryck2-3/+4
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-16fix null pointer deref on return expression with invalid typeLuc Van Oostenryck2-1/+10
If the evaluation of the return expression failed a following test can dereference the pointer holding the expression's type ... which is null. Bad. Fix this by adding the missing null pointer test. Fixes: 3bc32d46494c404df7905fceaca9156830ff97f1 Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-16warn when taking the address of a built-in functionLuc Van Oostenryck2-10/+19
Built-in functions are meant to be expanded by the compiler. As such, they don't have an address. So, issue an error when trying take the address of a built-in function. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-16testsuite: fix location of error messagesLuc Van Oostenryck1-3/+3
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-14update TODO listLuc Van Oostenryck1-8/+21
A few things are now done, remove them from the list, and add a few things that should be done. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-14flex-array: fix typo in warning messageLuc Van Oostenryck2-3/+3
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-14builtin: add builtin type for volatile void *Luc Van Oostenryck2-0/+4
This is the type of most __sync_* or __atomic_* builtins. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-14builtin: add generic .args methodLuc Van Oostenryck1-0/+7
The arity of builtin functions can be retrieved from their prototype. So, create a generic .args method, doing the evaluation of all arguments present in the prototype. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-12Sparse v0.6.3-rc1v0.6.3-rc1Luc Van Oostenryck2-1/+2
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-12doc: add release notes for incoming v0.6.3Luc Van Oostenryck1-4/+54
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-11Merge branch 'more-builtin' (early part)Luc Van Oostenryck1-0/+8
* builtin: teach sparse about __builtin_ia32_pause()
2020-10-09builtin: teach sparse about __builtin_ia32_pause()Luc Van Oostenryck1-0/+8
This builtin is used by Open vSwitch, so teach Sparse about it. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-09flex-array: fix location for nesting of flexible membersLuc Van Oostenryck2-3/+3
The warning about the nesting of flexible array members is given with the location of the outer struct or union but that is not very interesting. What is needed is the location of the member causing this nesting. So, fix the warning message to use the member's location. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-09Merge branch 'misc'Luc Van Oostenryck5-9/+5
2020-10-09Merge branch 'usual-conv'Luc Van Oostenryck3-32/+47
2020-10-09flex-array: allow arrays of unions with flexible members.Ilya Maximets7-1/+44
There is a common pattern on how to allocate memory for a flexible-size structure, e.g. union { struct flex f; /* Structure that contains a flexible array. */ char buf[MAX_SIZE]; /* Memory buffer for structure 'flex' and its flexible array. */ }; There is another example of such thing in CMSG manpage with the alignment purposes: union { /* Ancillary data buffer, wrapped in a union in order to ensure it is suitably aligned */ char buf[CMSG_SPACE(sizeof(myfds))]; struct cmsghdr align; } u; Such unions could form an array in case user wants multiple instances of them. For example, if you want receive up to 32 network packets via recvmmsg(), you will need 32 unions like 'u'. Open vSwitch does exactly that and fails the check. So, add a new option, -W[no-]flex-array-union, to enable or disable any warning concerning flexible arrays and unions. This option needs at least one of -Wflex-array-{array,nested,union} to be enabled in order to have any effect. Signed-off-by: Ilya Maximets <i.maximets@ovn.org> Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-08fix usual conversion of integersLuc Van Oostenryck2-31/+45
The current implementation of the usual conversion doesn't handle correctly the case of 'long' + 'unsigned int' on a 32-bit arch. The resulting type is 'unsigned int' instead of 'unsigned long'. Fix this by following closely the C99's wording. This now gives the expected result for C89 & C99 on 32 & 64-bit archs (as tested with the GCC testsuite). Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-08fix evaluation of pointer to bool conversionsLuc Van Oostenryck2-1/+2
The pointer to bool conversion used an indirect intermediate conversion to an int because the pointer was compared to 0 and not to a null pointer. The final result is the same but the intermediate conversion generated an unneeded OP_PTRTOU instruction which made some tests to fail. Fix this by directly comparing to a null pointer of the same type as the type to convert. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-08build: rule for validation needs to be FORCEdLuc Van Oostenryck1-1/+1
The Makefile contains a rule for launching a test from the testsuite but we want these tests to run even if when their dependencies are up-to-date. So, add 'FORCE' in the dependency list. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-08add helpers is_struct_type() & is_union_type()Ilya Maximets1-0/+14
Signed-off-by: Ilya Maximets <i.maximets@ovn.org> Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-06unop: fix access to defining instruction in simplify_unop()Luc Van Oostenryck1-4/+2
Only pseudos of type PSEUDO_REG have a defining instruction. However, in commit 5425db10d4d3 ("simplify '~(~x)' and '-(-x)' to 'x'"), this defining instruction of the 'src' of the outer unop was accessed without checking the type. Fixes: 5425db10d4d35895ba3ca390478c624233ec027d Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-06remove definition of removed OP_{AND,OR}_BOOLLuc Van Oostenryck1-2/+0
These instructions have been removed years ago, in 2016 but the corresponding opcode defines have been forgotten. So remove them now. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-06Merge branch 'flex-array-base'Luc Van Oostenryck11-18/+177
2020-10-06flex-array: remove unneeded testLuc Van Oostenryck1-22/+0
This test was for a failed experience. Remove it. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-04add builtin types for size_t*, intmax_t* & ptrdiff_t*Luc Van Oostenryck2-0/+9
This is needed for printf format checking of "%zn", "%jn" & "%tn". Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-04add builtin types for signed char* and short *Luc Van Oostenryck2-0/+4
This is needed for printf format checking of "%hhn" & "%hn". Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-04add builtin type for wide stringsLuc Van Oostenryck2-0/+9
This is needed for printf format checking of "%Ls". Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-01testsuite: fix erroneous commentLuc Van Oostenryck1-1/+1
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-01fix Hurd PATH_MAX ...Luc Van Oostenryck1-1/+1
The fix quickly added for Hurd not defining PATH_MAX is not correct: the local define must be guaranteed to be done only after <limits.h> is included, which is not. Since this problem only exists with Hurd, simply conditionalize the local define by __gnu_hurd__. Horrible but well ... Hurd. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-01flex-array: warn on flexible array in nested aggregate typesLuc Van Oostenryck5-1/+14
A structure or a union containing another aggregate type containing, possibly recursively, a flexible array is quite error prone and make not much sense. So, add an option -Wflexible-array-nested to warn on such usage. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-01flex-array: warn an arrays containing a flexible arrayLuc Van Oostenryck5-1/+12
An array of some aggregate type containing, possibly recursively, a flexible array is pretty non-sensical. So, add an option -Wflexible-array-array to warn on such usage. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-01flex-array: warn when using sizeof() on a flexible arrayLuc Van Oostenryck5-1/+13
Using sizeof() on a structure containing a flexible array will ignore the 'flexible' part. This is maybe what is expected but maybe not, so add an option -Wflexible-array-sizeof to warn on such usage. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-01flex-array: add helper has_flexible_array()Luc Van Oostenryck1-0/+7
This will make later checks easier & clearer. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-01flex-array: identify structures with a flexible array memberLuc Van Oostenryck2-0/+7
Structures containing a flexible array must not be nested. So, as a preparatory step, detect structures or union containing a flexible array, possibly recursively and mark the corresponding type with a dedicated flag. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-01flex-array: warn if flexible array is not lastLuc Van Oostenryck2-1/+2
Flexible array members must be the last in a structure. Warn if it is not the case. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-01flex-array: warn on flexible arrays in unionsLuc Van Oostenryck1-0/+3
Flexible array members are not allowed in unions. So, warn if one is present. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-01flex-array: detect structures with a flexible array memberLuc Van Oostenryck1-0/+2
This is a preparatory step for doing the checks and warnings. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-01flex-array: flexible array members have zero size and alignment is OKLuc Van Oostenryck2-2/+0
When doing the layout of structures, flexible arrays used to not align the resulting structure size. However, the standard specify that while for most purposes flexible arrays can be handled as if not present, they still may add some trailing padding (cfr. C11's 6.7.2.1p18). So, there is no reason to reset the alignment. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-01flex-array: do not lay out invalid struct membersLuc Van Oostenryck1-2/+4
Do not bother trying to lay out invalid struct members, ignore them as it will avoid to special case them later. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-01flex-array: factor out common part of lay_out_{struct,union}()Luc Van Oostenryck1-16/+8
This is a preparatory step for later patches. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-10-01flex-array: add testcasesLuc Van Oostenryck6-0/+133
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-09-16teach sparse about -funsigned-bitfieldsLuc Van Oostenryck10-22/+60
Currently, Sparse treats 'plain' bitfields as unsigned. However, this is this is inconsistent with how non-bitfield integers are handled and with how GCC & clang handle bitfields. So, teach sparse about '-funsigned-bitfields' and by default treat these bitfields are signed, like done by GCC & clang and like done for non-bitfield integers. Also, avoid plain bitfields in IR related testcases. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-09-07Merge branch 'linear-fma' into nextLuc Van Oostenryck5-2/+57
* add support for a new instruction: OP_FMA * teach sparse to linearize __builtin_fma()
2020-09-07builtin: teach sparse to linearize __builtin_fma()Luc Van Oostenryck2-0/+39
The support for the linearization of builtins was already added for __builtin_unreachable() but this builtin has no arguments and no return value. So, to complete the experience of builtin linearization, add the linearization of __builtin_fma(). Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-09-07builtin: add declaration for __builtin_fma{,f,l}()Luc Van Oostenryck1-0/+3
The motivation for this is to experiment with adding infrastructure for the linearization of builtins. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-09-07builtin: allow linearization to failLuc Van Oostenryck1-2/+5
Allow the linearization of builtins to fail and continue with the normal linearization of OP_CALLs. The motivation for this is for the linearization of target specific builtins. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-09-07add support for a new instruction: OP_FMADDLuc Van Oostenryck3-0/+10
This will be the instruction for fused multiply-add but the motivation for it is some experimentation with the linearization of builtins. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-09-07Merge branch 'replace-with-val' into nextLuc Van Oostenryck1-14/+15
* add & use replace_with_value()
2020-09-06testsuite: easier testing via script & makefileLuc Van Oostenryck1-2/+2
With this change, using the testsuite via the Makefile is not limited anymore to a single file. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-09-05replace_with_{pseudo,value}() can be tail-callsLuc Van Oostenryck1-8/+4
This avoids the need to have a separate 'return REPEAT_CSE' and thus make the code slightly more compact and fast to read. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-09-05use replace_with_value()Luc Van Oostenryck1-8/+8
Replace existing 'replace_with_pseudo(insn, value_pseudo($N))' by 'replace_with_value($N)'. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-09-05add helper replace_with_value()Luc Van Oostenryck1-0/+5
During simplification, it's relatively common to have to replace an instruction with pseudo corresponding to a known value. The pseudo can be created with value_pseudo() and the replacement can be made via replace_with_pseudo() but the combination of the two is a bit long. So, create an helper doing both sat once: replace_with_value(). Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-08-18Merge branch 'union-cast' into masterLuc Van Oostenryck7-20/+129
* teach sparse about union casts
2020-08-18Merge branch 'pointer-arith' into masterLuc Van Oostenryck3-2/+175
* fix evaluate_ptr_add() when sizeof(offset) != sizeof(pointer)
2020-08-18Merge branch 'past-deep'Luc Van Oostenryck4-2/+12
* conditionalize warning "advancing past deep designator"
2020-08-18Merge branch 'cleanup' into masterLuc Van Oostenryck1-2/+0
* cleanup: remove unneeded predeclaration of evaluate_cast()
2020-08-18remove unneeded predeclaration of evaluate_cast()Luc Van Oostenryck1-2/+0
evaluate_cast() is predeclared in the middle of the file but is not used before it's defined. So, remove this unneeded predeclaration. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-08-17fix evaluate_ptr_add() when sizeof(offset) != sizeof(pointer)Luc Van Oostenryck3-2/+175
For a binary op, both sides need to be converted to the resulting type of the usual conversion. For a compound-assignment (which is equivalent to a binary op followed by an assignment), the LHS can't be so converted since its type needs to be preserved for the assignment, so only the RHS is converted at evaluation and the type of the RHS is used at linearization to convert the LHS. However, in the case of pointer arithmetics, a number of shortcuts are taken and as a result additions with mixed sizes can be produced producing invalid IR. So, fix this by converting the RHS to the same size as pointers, as done for 'normal' binops. Note: On 32-bit kernel, this patch also removes a few warnings about non size-preserving casts. It's fine as these warnings were designed for when an address would be stored in an integer, not for storing an offset like it's the case here. Reported-by: Valentin Schneider <valentin.schneider@arm.com> Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-08-17union-cast: teach sparse about union castsLuc Van Oostenryck7-3/+60
A cast to union type is a GCC extension similar to a compound literal just for union, using the syntax of a cast. However, sparse doesn't know about them and treats them like other casts to non-scalars. So, teach sparse about them, convert them to the corresponding compound literal and add a warning flag to enable/disable the associated warning: -W[no-]union-cast. Note: a difference between union casts and compound literals is that the union casts yield rvalues while compound literals are lvalues but this distinction is not yet done in this series. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-08-17fix typo in warningLuc Van Oostenryck1-1/+1
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-08-15union-cast: extract evaluate_compound_literal()Luc Van Oostenryck1-19/+22
extract evaluate_compound_literal() from evaluate_cast, in preparation for supporting union casts. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-08-15union-cast: add some testcasesLuc Van Oostenryck2-0/+49
Casts to union type are a GCC extension and are similar to compound literals. However, sparse doesn't know about them and treats them like other casts to non-scalars. Add some testcases for this and its upcoming warning flag. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-08-12Merge branch 'doc-next'Luc Van Oostenryck7-21/+51
* doc: more compact sidebar * doc: use shorter titles * doc: reorganize the table of content
2020-08-12Merge branch 'fix-scalar'Luc Van Oostenryck2-0/+15
* fouled types are scalars too (fix is_{scalar,integral}_type()
2020-08-11fix is_scalar_type(): fouled types are scalars tooLuc Van Oostenryck2-0/+15
is_scalar_type() accept SYM_RESTRICT but not SYM_FOULED but both are for integer types (and only for them). So, let it accept SYM_FOULED too. Same for is_integral_type(). Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-08-11Merge branch 'force-to-0' into masterLuc Van Oostenryck1-1/+5
* force to 0 expressions which are erroneously non-constant
2020-08-11bug-assign-op0.c: fix test on 32-bit buildsRamsay Jones1-5/+5
This test was failing on 32-bit because it made the assumption that 'long' is always 64-bit. Fix this by using 'long long' when 64-bit is needed. Fixes 36a75754ba161b4ce905390cf5b0ba9b83b34cd2 Signed-off-by: Ramsay Jones <ramsay@ramsayjones.plus.com> Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-08-10doc: add links to some external docLuc Van Oostenryck1-0/+5
One is a LWN article which covers sparse very well, the other is a pdf giving a short overview of sparse. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-08-10doc: use shorter titlesLuc Van Oostenryck4-9/+9
Mainly it's removing 'sparse' from the title. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-08-10doc: reorganize the table of contentLuc Van Oostenryck1-8/+8
Reorganize the table of of content with user documentation first then all documentation useful for development on sparse itself. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-08-10doc: move down info about tarballs, after git repositoriesLuc Van Oostenryck1-3/+2
Better to have the information about the GIT repositories first because I'm not sure if anyone still use the tarballs. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-08-10doc: decrease vertical spacingLuc Van Oostenryck1-0/+13
The vertical spacing in the generated HTML is a bit excessive to my taste. So decrease it somehow, especially the top of lists. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-08-10doc: make the sidebar more compactLuc Van Oostenryck1-0/+4
There is generous spacing in the sidebar, too generous. So, reduce it to something more compact, which will also allow more entries without scrolling. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-08-10doc: use a smaller logo in the sidebarLuc Van Oostenryck2-1/+10
The logo takes quite a bit height in the sidebar and so pushes the table of content too much at the bottom. Fix this by reducing the logo to 50%. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-08-09Merge branches 'attr-asm' and 'storage-mod'Luc Van Oostenryck3-222/+143
* separate parsing of asm-names from attributes * simplify parsing of storage modifiers
2020-08-09Merge branch 'doc-annot'Luc Van Oostenryck6-66/+113
* improve presentation of the doc, mainly the sidebar
2020-08-09parse: simplify set_storage_class()Luc Van Oostenryck1-5/+2
The second test is now made as the else part of the first test, saving a 'return' that is otherwise not needed. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-08-09parse: improve error messages concerning storage specifiersLuc Van Oostenryck1-5/+4
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-08-09parse: let asm_modifier() use the keyword modifierLuc Van Oostenryck2-14/+4
Now that 'MOD_INLINE' & 'MOD_VOLATILE' are associated with their corresponding keyword, a single asm_modifier() method can cover both cases. So, replace asm_modifier_inline() & asm_modifier_volatile() by a single, generic version: asm_modifier(). Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-08-09parse: associate modifiers with their keywordLuc Van Oostenryck2-110/+48
A significant number of declarators need to set or simply use the modifier associated with the corresponding keyword but this is open-coded for each of them. As result, almost all keywords corresponding to a declaration need their own specific method. Make this more generic by adding the associated modifier to the ctype associated to keywords and passing the result of the keyword lookup to the declarator methods. This way, these methods can be made generic by getting the modifier from the ctype, like it was already done for attributes. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-08-09parse: rework handling of storage_classLuc Van Oostenryck2-50/+25
The handling of the storage class modifiers is done differently than the other modifiers: * they don't use MOD_... but their own enums * consequently they can't use modifier_string() and have their own string table to display them. * the attribute 'force' is considered as a kind of storage class. Fine, but it means that 'register' or '__tls' can't be used with 'force' (which is probably very fine but seems more as a side-effect than something really desired). The real justification for these difference seems to be that storage class modifiers *must* be treated differently than the other modifiers because they don't apply at the same level. For example, in a declaration like: static const int a[N]; 'static' applies to the array/the whole object, while 'const' only applies to the (type of the) elements of the array. Storage class specifiers must thus be parsed, stored aside and only be applied after the whole declarator have been parsed. But other modifiers are also in the same situation (for example, '__noreturn' or '__pure' for functions). So, use the generic keyword/attribute handling of modifiers for storage class specifiers but for simplicity, store them separately in decl_state to easily do duplication tests on them. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-08-09Merge branch 'empty-char' into nextLuc Van Oostenryck4-6/+28
* delay 'empty character constant' warning to phase 5
2020-08-09force to 0 expressions which are erroneously non-constantLuc Van Oostenryck1-1/+5
When an expression that needs to be constant but is, in fact, not constant, sparse throws an error and leaves it as-is. But some code makes the assumption that the expression is constant and uses its value, with some random result. One situation where this happens is in code like: switch (x) { case <some non-const expression>: ... In this case, the linearization of the switch/case statement will unconditionally use the value of the case expression but the expression has no value. One way to avoid this would be to add defensive checks each time a value is retrieved but this is a lot of work and time for no benefits. So, change this by forcing the expression to be a constant value of 0 just after the error message has been issued. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-08-09Merge branch 'check-void' into tipLuc Van Oostenryck1-1/+1
* fix checking if type is void
2020-08-09fix checking if type is voidLuc Van Oostenryck1-1/+1
Sparse warns if a void function returns a non-void expression. But the check directly compares the returned type with void_ctype, without taking in account the presence of a SYM_NODE. In consequence, sparse issues a few false warnings. Fix this by using is_void_type() to test the returned type. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-08-08Merge branch 'wstring-init' into nextLuc Van Oostenryck5-10/+89
* teach sparse about wide string initializers
2020-08-08warning: conditionalize "advancing past deep designator"Luc Van Oostenryck4-2/+12
The warning "advancing past deep designator" is issued when a multi-level (deep) designator is followed by a non-designated one. But it's far from clear what is the value of this warning, what could be the confusion about this situation and what is special about these 'deep' designators? There are hundreds such occurrences in the kernel (394 in the configs I use for testing) and GCC, clang and sparse have no problems to handle them correctly. This means that there is also 0 chances that they will be 'corrected'. So, add conditionalize this warning with a '-Wpast-deep-designator' and make it false by default. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-08-08Merge branch 'sync-cas' into nextLuc Van Oostenryck4-6/+93
* fix evaluation of __sync_{bool,val}_compare_and_swap()
2020-08-08Merge branch 'bad-shift-equal' into nextLuc Van Oostenryck12-87/+462
* fix type evaluation of shifts-assigns * don't warn for UB shifts in dead code
2020-08-08Merge branch 'prev-stream' into nextLuc Van Oostenryck3-1/+17
* fix diagnostic source path from command line * fix diagnostic source path for invalid streams
2020-08-08wstring: call is_string_type() only when neededLuc Van Oostenryck1-3/+2
Just a tiny code reorganization to call is_string_type() only where & when needed. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-08-08wstring: extend is_string_type() to also detect wide stringsLuc Van Oostenryck2-2/+4
When evaluating initializers, it must be known if it is for a string or not. But sparse doesn't known about wide strings. Fix this by modifying is_string_type() to use is_wchar_type() in addition of is_byte_type(). Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-08-08wstring: add helper is_wchar_type()Luc Van Oostenryck1-0/+7
Like is_byte_type() but for wide chars. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-08-08wstring: add support for examination of string initializationLuc Van Oostenryck1-0/+25
The examination of a string initializer doesn't know about wide strings. The only thing needed is if the base type is some kind of char but for wide chars, this type is the same as 'int' and an array of ints can't be treated the same as an array of chars. So, do the detection for wide string initializers as: 1) check that the LHS base type is wchar_ctype 2) check that the RHS is a kind of string expression (possibly between braces or parenthesis, recursively). Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-08-08wstring: add support for checking size in string initializerLuc Van Oostenryck3-2/+47
A warning is given for string initializers if the LHS array is not large enough to contains the string. But this check doesn't knowns about wide strings. Fix this by selecting the correct char type and use this type for the size calculations. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-08-08wstring: add support for evaluation of wide stringLuc Van Oostenryck1-4/+5
Evaluation doesn't know about wide strings. Fix this by: 1) selecting the right base type (char_ctype vs wchar_ctype) 2) adapting the type, size & alignment of the underlying array to this base type. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-08-07add builtin support for __sync_{bool,val}_compare_and_swap()Luc Van Oostenryck2-3/+58
In the kernel, the architecture s390 uses these builtins to implement __atomic_cmpxchg() and friends. These builtins are polymorphic, so they need some special evaluation. These builtins are known to sparse but with a return type of 'int' and the argument's types being ignored. A problem occurs when used on a pointer type: the expected type doesn't match 'int' and it can give warnings like: warning: non size-preserving integer to pointer cast So, improve the support for these builtins by: *) checking the number of arguments *) extract the type from the 1st argument *) set the returned type to this type if needed *) finally, do the typechecking by calling evaluate_arguments() Reported-by: kernel test robot <lkp@intel.com> Link: https://lore.kernel.org/lkml/202008072005.Myrby1lg%25lkp@intel.com/ Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-08-07export evaluate_arguments()Luc Van Oostenryck2-4/+10
evaluate_arguments() is local to evaluate.c but the same functionality is needed for builtins. So, in order to not duplicate this code: *) change slightly its interface to accept the expected types as a list *) make this function extern. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-08-07add testcases for __sync_{bool,val}_compare_and_swap()Luc Van Oostenryck1-0/+26
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-08-06bad-shift: wait dead code elimination to warn about bad shiftsLuc Van Oostenryck8-83/+78
Sparse complains when a shift amount is too big for the size of its operand or if it's negative. However, it does this even for expressions that are never evaluated. It's especially annoying in the kernel for type generic macros, for example the ones in arch/*/include/asm/cmpxchg.h So, remove all warnings done at expansion time and avoid any simplifications of such expressions. Same, at linearization and optimization time but in this case mark the instructions as 'tainted' to inhibit any further simplifications. Finally, at the end of the optimization phase, warn for the tainted instructions. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-08-06shift-assign: restrict shift count to unsigned intLuc Van Oostenryck2-1/+5
After the RHS of shift-assigns had been integer-promoted, both gcc & clang seems to restrict it to an unsigned int. This only make a difference when the shift count is negative and would it make it UB. Better to have the same generated code, so make the same here. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-08-06shift-assign: fix linearization of shift-assignLuc Van Oostenryck4-11/+13
The result of a shift-assigns has the same type as the left operand but the shift itself must be done on the promoted type. The usual conversions are not done for shifts. The problem is that this promoted type is not stored explicitly in the data structure. This is specific to shift-assigns because for other operations, for example add-assign, the usual conversions must be done and the resulting type can be found on the RHS. Since at linearization, the LHS and the RHS must have the same type, the solution is to cast the RHS to LHS's promoted type during evaluation. This solve a bunch of problems with shift-assigns, like doing logical shift when an arithmetic shift was needed. Fixes: efdefb100d086aaabf20d475c3d1a65cbceeb534 Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-08-06shift-assign: add more testcases for bogus linearizationLuc Van Oostenryck2-0/+374
The usual conversions must not be applied to shifts. This causes problems for shift-assigns. So, add testcases for all combinations of size and signedness. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-08-05sindex: rename it to 'semind'Alexey Gladkov4-195/+195
The name 'sindex' is already used by another package (biosquid). So it was decided to rename it to 'semind'. Signed-off-by: Alexey Gladkov <gladkov.alexey@gmail.com> Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-08-01sindex.1: Use ' for a plain quote charUwe 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-07-31Merge branch 'array-decl'Luc Van Oostenryck5-38/+57
2020-07-31Merge branch 'attr-parsing'Luc Van Oostenryck1-19/+3
2020-07-31Merge branch 'doc-misc'Luc Van Oostenryck3-5/+5
2020-07-31Merge branch 'undef-option'Luc Van Oostenryck1-0/+6
2020-07-30sindex: allow indexing outside the project treeAlexey Gladkov1-4/+17
One possible way to compile the linux kernel is by using the O=<DIR> parameter to place all generated files outside the source tree. Prior to this patch, sindex filters processed sources to exclude system files. The base directory of the project was the current directory. When compiled outside of the source tree, this may not be the case. This patch adds a parameter and an environment variable to specify the source tree. You can use it like this: $ make O=$PWD-build C=2 CHECK="sindex -B $PWD add --" This parameter is also needed for searching if you want to display the source code line because sindex does not store lines in the database but reads them from source files. Signed-off-by: Alexey Gladkov <gladkov.alexey@gmail.com> Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-30dissect: support _Generic() a bit moreOleg Nesterov1-1/+11
Change do_expression(EXPR_GENERIC) to inspect expr->control/map/def. The is the minimal "better than nothing" change, technically incorrect but still useful for the indexing. Example: void func(void) { _Generic(a, int: b, void: c, default: d, ) = e; } output: 1:6 def f func void ( ... ) 3:18 func --- v a bad type 4:33 func -w- v b bad type 5:33 func -w- v c bad type 6:33 func -w- v d bad type 7:13 func -r- v e bad type Signed-off-by: Oleg Nesterov <oleg@redhat.com> Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-30fix diagnostic source path from command lineLuc Van Oostenryck2-0/+13
Now, diagnostic messages are prepended with the source path. But if the problem comes from a file included directly from the command line like: sparse -include some-buggy-file.c the prepended message will be: (null): note: in included file ... because there isn't a source path yet. So, initialize the source path to "command-line". Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-29fix stream_prev() for invalid (negative) streamLuc Van Oostenryck1-1/+4
Now that the parent stream is stored as a position, the validity of a stream can't anymore be tested by checking if its number is non-negative because inside a struct position stream number are stored as an unsigned (and changing it to signed would halve the maximum number of stream). So, add a check against input_stream_nr before returning the previous stream. Fixes: 4c6cbe557c48205f9b3d2aae4c166cd66446b240 Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-29dissect: use struct symbol::visited/inspected instead of ::examined/evaluatedLuc Van Oostenryck2-6/+7
The dissect client uses struct symbol's fields 'examined' & 'evaluated' to avoid reprocessing the same symbols. But these fields are used internally by sparse for type examination & evaluation and despite dissect not doing these operations explicitly, they can be done implicitly (for example to handle static assertions or when the value of a constant expression is needed) inside __sparse(). If this happens, dissect.c:examine_sym_node() will be a no-op because node->examined will already be set and node->kind would be 0. Same can happen with node->evaluated. So, add a new field to struct symbol: 'inspected' and use it, as well as the existing 'visited', instead of 'evaluated' & 'examined'. This way, dissect will control its recursion via flags reserved for backends and thus never set by sparse internals. Note: when used on the kernel, this patch avoids a lot of warnings: "warning: r_member bad sym type=7 kind=0" "warning: r_member bad mem->kind = 0" and creates substantially more normal output. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com> Acked-by: Oleg Nesterov <oleg@redhat.com>
2020-07-29dissect: add support for _GenericAlexey Gladkov1-0/+1
Just suppress the warning about unknown type. Before: $ ./test-dissect validation/generic-functions.c FILE: validation/generic-functions.c 13:1 def f testf void ( ... ) 13:1 testf def . v a float validation/generic-functions.c:13:1: warning: bad expr->type: 31 13:1 testf -r- . v a float 14:1 def f testd void ( ... ) 14:1 testd def . v a double validation/generic-functions.c:14:1: warning: bad expr->type: 31 14:1 testd -r- . v a double 15:1 def f testl void ( ... ) 15:1 testl def . v a long double validation/generic-functions.c:15:1: warning: bad expr->type: 31 15:1 testl -r- . v a long double After: $ ./test-dissect validation/generic-functions.c FILE: validation/generic-functions.c 13:1 def f testf void ( ... ) 13:1 testf def . v a float 13:1 testf -r- . v a float 14:1 def f testd void ( ... ) 14:1 testd def . v a double 14:1 testd -r- . v a double 15:1 def f testl void ( ... ) 15:1 testl def . v a long double 15:1 testl -r- . v a long double Signed-off-by: Alexey Gladkov <gladkov.alexey@gmail.com> Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-27xtensa: fix configuration of endiannessLuc Van Oostenryck1-5/+0
Since gcc 3.4.0 there is no option to specify the endianness for the Xtensa architecture, so the kernel relies on autodetecting the endianness and then defining the macros __XTENSA_E{B,L}__. But this means that sparse's 'arch_big_endian' can't be used for the predefine. So, do not predefine these macros anymore, they will transparently be set directly from the command line. Reported-by: Peter Zijlstra <peterz@infradead.org> Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-27remove unsed field for EXPR_GENERICLuc Van Oostenryck1-1/+0
The field 'result' have been committed by inadvertence in the initial commit. Remove it now. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-25keyword type is a bitmask and must be tested soLuc Van Oostenryck1-1/+1
The keyword's type is a bitmask because depending on the context the same keyword can be of different type (for example 'const' as qualifier and the attribute 'const' , a variant of 'pure'). Thus, it's an error to test this type for equality, instead it's a specific (set of) bit(s) that must be tested. So, change a test ' x == KW_...' into 'x & KW_...'. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-25attribute: simplify parsing of attributesLuc Van Oostenryck1-19/+3
In the loop doing the parsing of attributes, it's first checked if EOF is reached, then if the token is ';' but these tests are not needed since they're subsumed by the third one: checking if the token is an identifier. So, remove the tests for EOF and ';', and change the for-loop into a while-loop checking for TOKEN_IDENT. As a bonus, remove the local variable holding the identifier since it's there only for historical reasons. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-25testing for sym->op is unneeded for lookup_keyword()Luc Van Oostenryck1-1/+1
All symbols returned by lookup_keyword() are of type SYM_KEYWORD, because either: 1) it's in NS_KEYWORD (and all symbol in NS_KEYWORD are SYM_KEYWORD) 2) it's in NS_TYPEDEF and all *keywords* in NS_TYPEDEF are reserved and so can't be user defined and so must be SYM_KEYWORD. Thus, they all have a symbol_op associated to them and it's unneeded to test it. So, remove the unneeded test. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-25testing for SYM_KEYWORD is unneeded for lookup_keyword()Luc Van Oostenryck1-4/+2
All symbols returned by lookup_keyword() are of type SYM_KEYWORD, because either: 1) it's in NS_KEYWORD (and all symbol in NS_KEYWORD are SYM_KEYWORD) 2) it's in NS_TYPEDEF and all *keywords* in NS_TYPEDEF are reserved and so can't be user defined and so must be SYM_KEYWORD. It's thus unneeded to test it. So, remove the unneeded test. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-25attribute: no need to lookup '__attribute__' in NS_KEYWORDLuc Van Oostenryck1-1/+1
Since '__attribute__' is in NS_TYPEDEF, it's not useful to look it up also in NS_KEYWORD. So, remove NS_KEYWORD from the mask while looking up '__attribute__'. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-25attribute: factorize matching of '__attribute__'Luc Van Oostenryck1-19/+16
Matching the keyword '__attribute__' (or '__attribute') needs several tests and this matching is needed to handle attributes or to skip them. So, create an helper, match_attribute(), and use it in the loops to handle and to skip attributes. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-25attribute: directly use attribute_specifier() to handle attributesLuc Van Oostenryck1-1/+1
handle_attributes() used to also handle asm names and so used the declarator method associated to the taken. But now, asm names are handled in a separated function. So, directly use attribute_specifier() to handle the attributes instead of using it via the declarator method. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-25attribute: remove argument 'keywords' from handle_attributes()Luc Van Oostenryck1-13/+12
Now that the asm names are handled in handle_asm(), the 'keywords' argument of handle_attributes() is no more needed since it always must be 'KW_ATTRIBUTE'. So, remove this argument. Note: this is preparation work to later make the distinction between function/variable/type/label/... attributes. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-25attribute: fold parse_asm_declarator() into handle_asm_name()Luc Van Oostenryck1-12/+8
An asm name is not really a declarator, it must only be placed *after* a declarator and is directly handled by handle_asm_name(). It's thus not needed and possibly confusing to treat it like a generic declarator. So, fold parse_asm_declarator() into handle_asm_name() and remove it. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-25attribute: split handle_asm_name() from handle_attributes()Luc Van Oostenryck1-3/+18
handle_attributes() handles attributes but also the asm names. These asm names must occur before the attributes and only once while the attributes may occur multiple time. Also, these asm names are not allowed everywhere attributes, only in declarations. It's maybe handy to process both in the same function but it's also slightly confusing. So, move the handling of the asm names in a separate function. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-25use lookup_keyword() for qualifiersLuc Van Oostenryck1-1/+1
When handling qualifiers, the corresponding symbol is looked-up with lookup_symbol() then it's checked if the symbol's type is SYM_KEYWORD. But, only if the identifier is a keyword (struct ident::keyword) can the symbol be a SYM_KEYWORD. Thus, non-keyword can be filtered-out early by using lookup_keyword(). So change the call to lookup_symbol() by a call to lookup_keyword(). Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-25option: accept 'sparse -U ...'Luc Van Oostenryck1-0/+6
The '-D' flag was fixed to accept whitespace before the argument but the '-U' flag wasn't. So, fix this now. Fixes: 7f1011b311e9329f53d73f88de495ea64071eb77 Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-25doc: do not display bugzilla's URL, it's too longLuc Van Oostenryck1-2/+2
The full URL for bugzilla is quite long and was rendered as split into 2 lines which is quite ugly. So, do not show the URL but simply the hyperlink's name: "Linux kernel’s bugzilla for sparse". Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-25doc: use https URLsLuc Van Oostenryck1-2/+2
Use 'https' instead of 'http' for pages needing some level of trust. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-25manpage: replace homepage to sparse.docs.kernel.orgLuc Van Oostenryck2-2/+2
The online documentation was updated for the new homepage but the manpages were forgotten. So, update them now. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-25show-mod: no extra space when showing modifiers + identLuc Van Oostenryck1-1/+1
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-25show-mod: no ending space when showing a single modifierLuc Van Oostenryck1-1/+1
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-25show-mod: add helper to show the modifiers but without ending spaceLuc Van Oostenryck2-1/+18
modifier_string() returns either "" or a string with one or several modifiers separated by a space. In this last case the string has also a trailing space. This trailing space is sometimes desired (for example when composed with identifier name: "%s%s") but is also sometimes not desired (for example when only the modifiers must be displayed). So, create a variant of modifier_string() which doesn't add the ending space: modifier_name(). Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-25generic: 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-07-23allow [*] in array declaratorsLuc Van Oostenryck2-2/+6
Since C99, a '*' is allowed in an abstract array declarator to specify that the array is a VLA with a yet-to-be-determined size. So, accept this construction (but still ignore it for now). Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-23remove now unused match_idents()Luc Van Oostenryck1-18/+0
match_idents() is now unused and identifier matching should preferably be done via the keyword table. So, remove this function. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-23simplify & fix parsing of array declaratorsLuc Van Oostenryck3-20/+11
Any type qualifier is valid inside an abstract-array-declarator but currently only 'restrict' is accepted. Also the parsing of this is somehow more complex than needed and done by comparing the identifiers instead of being driven by the keyword table. So, simplify & fix the parsing of these declarators by: 1) using the keyword type KW_QUALIFIER to identify all type qualifier at once. 2) add a new keyword type just for 'static' 3) folding the helper abstract_array_static_declarator() into the main function: abstract_array_declarator(). Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-23add testcases for C99 array declaratorsLuc Van Oostenryck2-0/+31
C99 introduced some funky new array declarators, those with 'restrict' or 'static' inside the brackets. Add some testcases for them. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-23do not accept comma expressions in array declaratorLuc Van Oostenryck2-2/+1
Comma expressions are not allowed for the size in an array declarator. So, change the parsing of these expressions to only accept assignment-expressions. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-23add testcase for comma in array declaratorLuc Van Oostenryck1-0/+12
Comma expressions are not allowed for the size in an array declarator. Add a testcase for this. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-22doc: shorter title for "submitting-patches.md"Luc Van Oostenryck1-2/+2
The documentation for submitting patches has ": the sparse version" is in its title. This is quite useless and makes it longer than needed. So, remove this part from the title. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-08-03doc: remove link "edit on github"Luc Van Oostenryck1-0/+11
since the development isn't done on github, the link "edit on github" is useless and confusing. So remove this link (but leave the one "View page source" as it's sometimes quite handy). Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-08-03doc: add index to the sidebarLuc Van Oostenryck1-0/+8
It's very useful to be able to access the index from the sidebar but no change in the configuration seems to allow this. Trying to abuse the toctree give the same result. So, add it directly via the template system. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-08-03doc: simplify the toctreeLuc Van Oostenryck1-21/+7
Combine the 'user' documentation with the one for developers and add captions for each sections in order to have this structuration visible in the sidebar. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-08-03doc: replace nocast-vs-bitwise document with its lore linkLuc Van Oostenryck2-44/+0
The nocast-vs-bitwise document was copied here to be sure to remain accessible but isn't really useful here now because: 1) the original document have also been archived to lore.kernel.org 2) nocast & bitwise have now been documented 3) 2) contains a link to 1) So, remove this redundant document. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-08-03doc: document the sparse's extensionsLuc Van Oostenryck2-0/+86
First try at documenting sparse's extensions to C's type system. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-22add position to struct streamLuc Van Oostenryck5-12/+16
Now that struct stream contains the parent's stream, it might as well contains the position so that all information about the parent is available. So, add a struct position to struct stream, initialize it with the information from the '#include' token (if there is one) and use this positions's ::stream as previous/parent stream. Suggested-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-22delay 'empty character constant' warning to phase 5Luc Van Oostenryck4-6/+28
A subset of C syntax regarding character constants is: char-constant: ' c-char-sequence ' c-char-sequence: char c-char-sequence char In short, when tokenized, a character constant must have at least one character between the quotes. Consequently, sparse will issue an error on empty character constants (unlike GCC). However, sparse issues the error during tokenization (phase 3), before preprocessing directives are handled (phase 4). This means that code like: #if 0 ... '' #endif will throw an error although the corresponding code is discarded. Fix this by 1) silently accept empty char constants during tokenization 2) issue the diagnostic only when escape sequences are handled. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-19prepend diagnostics with source's path and include chainLuc Van Oostenryck6-17/+103
When a diagnostic is issued for a problem in an included file, the message show the include's path but it's often needed to (quickly) know the chain of include files involved. So, if the path associated with the diagnostic is different than the path oft he source file and different from the path of the previous message, prepend the message with a note showing the source file's path. And, if any intermediate include file is concerned, display the include chain (possibly truncated or not displayed at all if too long). Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-18Merge branch 'error-inval-num'Luc Van Oostenryck5-2/+20
* teach sparse about -fmax-errors * syntax errors in numbers are not fatal
2020-07-18Merge branch 'empty-expr'Luc Van Oostenryck5-2/+32
* warn on empty assignments & initializations
2020-07-18Merge branch 'arch'Luc Van Oostenryck27-65/+726
* some small adjustments to the builtin types and predefined macros.
2020-07-16predefine: let predefine_width() take the usual interfaceLuc Van Oostenryck1-3/+3
All the helpers for type-related predefines directly take in argument the pointer to the type. All but predefine_width(). This must be an historical relic. So, let predefine_width() also take the pointer to the type as argument. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-15syntax errors in numbers are not fatalLuc Van Oostenryck1-1/+4
When parsing expressions, if an invalid number is reached, a fatal error is issued. But this is not the kind of error for which continuing the processing doesn't make sense, since the token was already categorized as a number during the tokenization. So, change the fatal error into a normal one (and set the value to 0). Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-14Merge branch 'keyword-tbl'Luc Van Oostenryck1-154/+132
2020-07-14Merge branch 'assert-opt-msg'Luc Van Oostenryck2-8/+21
2020-07-14Merge branch 'bad-shift-assign'Luc Van Oostenryck1-0/+115
2020-07-14warn on empty initializationsLuc Van Oostenryck2-2/+4
Currently sparse accepts an empty initialization like: int a = ; Make this an error. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-14warn on empty assignmentsLuc Van Oostenryck3-2/+6
Currently sparse accepts an empty assignment like: a = ; Make this an error. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-14add testcase for incorrect empty expressionsLuc Van Oostenryck2-0/+24
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-14x86-x32: fix it by defining a separate target for itLuc Van Oostenryck3-3/+41
On x86-64, the x32 ABI was processed as a kind of special case of the usual 32-bit variant. But this doesn't work very well. Fix it and help avoiding possible future problems by defining a separate target for it. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-14arch: allow target specific [u]intptr_t & ptrdiff_tLuc Van Oostenryck8-6/+23
These types are aliased to size_t & ssize_t but this is not correct for all architectures. So, add a variable for them so that target files can adjust them. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-14predefine: teach sparse about __SIG_ATOMIC_TYPE__Luc Van Oostenryck3-0/+3
This type is predefined by GCC so add it to sparse too. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-14arch: add predefines __INT_FAST${N}_TYPE__Luc Van Oostenryck17-1/+146
We just added __INT_LEAST${N}_TYPE__, so add these ones too as they looks slightly more useful. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-14arch: add predefines __INT_LEAST${N}_TYPE__Luc Van Oostenryck4-0/+27
These are used by some system headers (neon on arm64). Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-13ppc: add predefines __LONGDOUBLE128 & __LONG_DOUBLE_128__Luc Van Oostenryck1-0/+4
On powerpc, if long double is 128-bit width, then '__LONGDOUBLE128' & '__LONG_DOUBLE_128__' should be defined. So do this in the target specific file. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-13alpha: has 64-bit long double & int128Luc Van Oostenryck1-0/+3
Support for alpha was added in order to move the specific builtins away from the common list without changing the defaults. Improve the support for this arch by fixing a few specificities: * support of 128-bit integers * long doubles are 64-bit. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-13sparc: add 'sparcv8' predefines for sparc32Luc Van Oostenryck1-3/+16
By default, the architecture version is 'v8' for sparc32 and 'v9' for sparc64. The predefines were added for sparc64 but not for sparc32. Fix this by adding a generic 'sparcv%d' together with a variable to hold the architecture version and initialize this one accordingly. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-13Merge branches 'march', 'endianness', 'os' and 'arch-mini' into archLuc Van Oostenryck20-49/+460
2020-07-13fix evaluation error with assignment of qualified arraysLuc Van Oostenryck3-4/+2
This is a fix for a problem reported today to the mailing list. In check_assignment_types(), the first 'level' is checked by the function itself but the next level is checked by the type_difference(). This later function take as arguments, beside the types to be checked, the modifiers that can be assumed for each of the types (this works as a kind of reverse mask). But these modifiers are taken from target_qualifiers() which, purposely ignore the modifiers for arrays introduced in commit 984b7b66457c ("[PATCH] deal correctly with qualifiers on arrays") with the comment: "Pointers to any array are considered as pointers to unqualified type as far as implicit conversions are concerned" But by dropping these modifiers, type_difference() reports incorrect results for pointers to qualified arrays. So, do not use target_qualifiers() but take the modifiers directly from the ctypes. Admittingly, I'm far from sure that this is the right fix but it solve several wrong cases. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-13openrisc: add minimal supportLuc Van Oostenryck5-0/+31
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-13sh: add minimal supportLuc Van Oostenryck5-0/+33
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-13nds32: add minimal supportLuc Van Oostenryck5-0/+33
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-13xtensa: add minimal supportLuc Van Oostenryck5-0/+36
This is one of the architecture needing a specific predefine set in order to correctly process byteorder.h. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-13h8300: add minimal supportLuc Van Oostenryck5-0/+32
This is now the only architecture needing '-msize-long'. Prepare the obsolescence of this option by adding the target file for this architecture. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>