aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/validation/eval
AgeCommit message (Collapse)AuthorFilesLines
2021-04-19remove early simplification of casts during evaluationLuc Van Oostenryck2-2/+0
The current code will simplify away some casts at evaluation time but doesn't take in account some special cases: * (bool)~<int> is not equivalent to ~(bool)<int> (anything not all 0 or 1) * (float)~<int> is not equivalent to ~(float)<int> which doesn't make sense. * (int)(float)<int> is not a no-op if the (float) overflows This kind of simplification is better done on the IR where the different kind of casts correspond to distinct instructions. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2021-04-18add testcases for simplification of casts.Luc Van Oostenryck2-0/+30
and remove one that didn't made much sense. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2021-02-24fix eval of the assignment of a non-restricted value to a restricted variableLuc Van Oostenryck1-0/+22
Assignment to restricted variables are severely ... restricted. Nevertheless, one value is always fine because it has always the same bit representation: 0. So, 0 is accepted unconditionally but this creates a problem because the type of this 0 needs to be adjusted. Otherwise 0 (int) is assigned as-is even on restricted variable with a different bit-length. Fix this by casting the value to the target type before accepting it. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-11-18unqual: statement expressions should drop qualifiersLuc Van Oostenryck1-1/+0
Statement expressions should be subjected to lvalue-conversion and thus should drop qualifiers. Fix this by calling unqualify_type() after array-to-pointer conversion. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-11-18unqual: comma expressions should drop qualifiersLuc Van Oostenryck1-1/+0
Comma expressions should be subjected to lvalue-conversion and thus should drop qualifiers. Fix this by calling unqualify_type() after array-to-pointer conversion. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-11-18unqual: add testcasesLuc Van Oostenryck4-0/+75
Add some testcases related to qualifier dropping / lvalue conversion. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-11-18casts should drop qualifiersLuc Van Oostenryck1-0/+14
Casts should drop qualifiers but Sparse doesn't do this yet. The fix seems pretty simple: after having evaluated the type of the cast, if this type is a SYM_NODE and contains qualifiers, make a copy of the type with the qualifiers removed and use this copy as the type. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-08-17union-cast: teach sparse about union castsLuc Van Oostenryck2-2/+0
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-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-07-13fix evaluation error with assignment of qualified arraysLuc Van Oostenryck2-2/+0
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-10add testcase for missing warning for assignment to constLuc Van Oostenryck1-0/+29
The problem is seems to be related with evaluate_dereference() where all mods are dropped when the type is a node. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-10add another testcase with const array/pointerLuc Van Oostenryck1-0/+50
Those are cases that sparse should warn about but doesn't. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-09add a testcase for assignment to const <type> (*)[]Luc Van Oostenryck1-0/+7
You can assign a '<type>[]' to a 'const <type> *'. Likewise, you can assign a '<type>[][N]' to a 'const <type> (*)[N]' but sparse doesn't like this. Analyzed-by: Ard Biesheuvel <ardb@kernel.org> Reported-by: Herbert Xu <herbert@gondor.apana.org.au> Link: https://lore.kernel.org/linux-crypto/20200709120937.GA13332@gondor.apana.org.au/ Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2020-07-04avoid multiple warnings when inlining undeclared callsLuc Van Oostenryck1-0/+19
When inlining multiple times a function which contains an undeclared function call, multiple error messages are issued. More annoyingly, only the first one is meaningful, the other ones doesn't even show the incriminated identifier: error: undefined identifier '...' error: not a function <noident> Part of the problem is that the first message is displayed with expression_error() which also sets the expression to &bad_ctype. This change the way how the expression is handled when re-evaluated. Fix this by avoiding the evaluation of function calls that already evaluate to bad_ctype: it's known that an error message have already been issued for them and that nothing good can done with them. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-12-17Merge branch 'expand-init' (early part) into nextLuc Van Oostenryck2-0/+40
* improve expansion of constant symbols
2019-12-10degenerated arrays & functions are addressable tooLuc Van Oostenryck1-1/+0
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 Oostenryck1-1/+0
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-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-09fix premature examination of dereferenced objectLuc Van Oostenryck1-0/+27
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-11-10typeof: examine it at show-timeLuc Van Oostenryck1-1/+0
Unless an explicit call to examine_pointer_target() or get_base_type() is made, the base type of pointers are *not* examined via the usual recursive examine_symbol_type(). That means that it is possible to call show_typename() on a non-fully examined type which is wrong (for example, because SYM_TYPEOFs may not be converted). So, call examine_pointer_target() on pointers when trying to display them. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-10typeof: add a test for unexamined typeofLuc Van Oostenryck1-0/+11
The base type of pointers are not examined when the pointer is. It needs to be done later when looked at. This may be a problem when show_typename() is used on a pointer which has not yet been 'deep-examined' and, for example, has a SYM_TYPEOF as its base type. Add a test case showing the problem. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-09-28asm: arrays & functions in non-memory operand degenerate into pointersLuc Van Oostenryck1-1/+0
Non-memory asm operands are very much like function's arguments. As such, any array (or function designator) used as an asm operand need to degenerate into the corresponding pointer. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-09-27asm: missing evaluation of asm statementsLuc Van Oostenryck1-1/+0
The operands of extended ASM need to have their type evaluated, exactly like any other expression. So, add the missing evaluation of ASM operands. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-09-27asm: add test evaluation, expansion & linearization of ASM operandsLuc Van Oostenryck2-0/+85
ASM statements are quite complex. Add some tests to catch some potential errors. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>