aboutsummaryrefslogtreecommitdiffstatshomepage
AgeCommit message (Collapse)AuthorFilesLines
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
2019-11-27cgcc: use -mfloat-abi=hard for armhfLuc Van Oostenryck1-1/+1
Now that sparse understands -mfloat-abi and set the related predefines (__ARM_PCS_VFP, __ARM_PCS & __SOFTFP) it's not cgcc can make good use of it. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-27fp-abi: teach sparse about -m{hard,soft}-floatLuc Van Oostenryck2-1/+2
Teach Sparse about these options. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-27fp-abi: teach sparse about -mfloat-abi on ARMLuc Van Oostenryck7-4/+39
Teach sparse about the -mfloat-abi option and set the related predefines for ARM accordingly. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-27fp-abi: add tests for ARM's -mfloat-abi=... & -msoft-floatLuc Van Oostenryck5-0/+45
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-26Merge branch 'arch-cygwin' into masterLuc Van Oostenryck9-23/+66
2019-11-26Merge branch 'parse-spec' into masterLuc Van Oostenryck7-126/+124
2019-11-26Merge branch 'static-forward' into masterLuc Van Oostenryck2-9/+33
2019-11-25spec: get rid of all specifier MOD_XXXLuc Van Oostenryck7-95/+68
Modifiers like MOD_CHAR, MOD_LONG, ... are used to keep track of the size/rank of integers and floats. But this is problematic: * they use 5 of the precious modifiers bits * they're not really modifiers but the base of the primitive types * a 'long double' has MOD_LONGLONG set Change this by using instead the explicit notion of 'rank'. The advanatges are: * using only 3 bits (in struct symbol) * free 5 modifier bits * follow closely the definition & rules of the standard * things like integer promotion are slightly simpler. Note: this is somewhat experimental as I'm not yet convinced that everything is correct (but the testsuite is OK and gives the same result for a defconfig + allyesconfig build of the kernel). Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-25spec: make ctype_declare[] more readableLuc Van Oostenryck1-51/+71
The table ctype_declare[] is used to initialize the builtin types. It contains quite a bit information and is thus quite large and is difficult to read. Fix this by using some macros to abstract the specificities of the different kind of types, making the table narrower and much more readable. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-21allow 'static' forward declarationLuc Van Oostenryck2-9/+33
A function or an object can be forward-declared as 'static' and then defining with the keyword 'static' omitted. This is perfectly legal and relatively common. However, Sparse complains that the definition is not declared and asks to the dev if should not be static. This is weird because the function or object *is* declared and *is* static (or at least should be following the standard or GCC's rules). Fix this by letting a new declaration or definition 'inherit' the 'static-ness' of the previous declarations. This is a bit more complicated than simply copying MOD_STATIC and must be done when binding the new symbol because static or extern objects have different scopes. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-21let function definition inherit prototype attributesLuc Van Oostenryck3-5/+10
It's common to declare a function with the attribute 'pure' or 'noreturn' and to omit the attribute in the function definition. It makes somehow sense since the information conveyed by these attributes are destined to the function users not the function itself. So, when checking declaration/definition, let the current symbol inherit any function attributes present in previous declarations. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-20propagate function modifiers only to functionsLuc Van Oostenryck4-26/+28
Function attributes need to be parsed differently than the usual specifiers: For example, in code like: #define __noreturn __attribute__((noreturn)) __noreturn void foo(int a); the __noreturn attribute should apply to the function type while a specifier like 'const' would apply to its return type. The situation is quite similar to how storage specifiers must not be handled by alloc_indirect_symbol(). However, the solution used for storage specifiers (apply the modifier bits only after the declarator is reached: cfr.commit 233d4e17c ("function attributes apply to the function declaration")) can't be used here (because the storage modifiers can be applied to the outermost declarator and function attributes may be applied more deeply if function pointers are present). Fix this by: 1) reverting the previous storage-specifier-like solution 2) collect function specifiers MODs in a new separate field in the declaration context (f_modifiers) 3) apply these modifiers when the declarator for the function type is reached (note: it must not be applied to the SYM_FN itself since this correspond to the function's return type; it must be applied to the parent node which can be a SYM_NODE or a SYM_PTR). 4) also apply these modifiers to the declared symbol, if this symbol is a function declaration, to take into account attributes which are placed at the end of the declaration and not in front. Reported-by: Ramsay Jones <ramsay@ramsayjones.plus.com> Fixes: 233d4e17c544e1de252aed8f409630599104dbc7 Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-19fix assignment check with function attributeLuc Van Oostenryck2-2/+8
It's OK to assign a non-qualified type to the corresponding const- or -volatile-qualified type (same for 'restrict'). For modifiers like __pure or __noreturn, it's the opposite: it's OK to assign the qualified version to the corresponding non-qualified type. Allow this by using type_difference() with the appropriate mask when checking assignments. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-19fix assignment: pointer to __pure/__noreturn function to void *Luc Van Oostenryck1-1/+1
It's fine for a pointer to a __pure or a __noreturn function to be assigned to a void pointer (since this pointer can't be used to make an indirect function call without another cast). Ensure this by ignoring the corresponding modifiers when checking such assignments. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-19add tests for function attributesLuc Van Oostenryck9-10/+134
Function attributes need to be parsed differently than the usual specifiers. For example, in code like: #define __noreturn __attribute__((noreturn)) __noreturn void foo(int a); the __noreturn attribute should apply to the function type, while a specifier like 'const' would apply to its return type. It's even more clear when function pointers are involved: __noreturn void (*fptr)(void); here too, the attribute should be applied to the function type, not the its return type, nor to the declared pointer type. Add some testcases to cover some of the situations concerning the parsing of these function pointers. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-15option: simpler handling of key-value for suboptionsLuc Van Oostenryck1-20/+40
Currently handling a set of suboptions is done by a series of if (strcmp()) but it's neater to have this in a table. Add an helper to doing this easily and convert the handling of '-mcmodel' options. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-15option: use handle_switches() for -m flagsLuc Van Oostenryck1-17/+17
The function handle_switch_m(), parsing the -m flags, consists in a series of strcmp(), each setting a specific value in one of the internal flag variable. This can now be simplified by using a table to specify these variables & values in a compact form. So, convert the current code to use, if possible, a table & handle_switches(). Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-15option: allow handle_switches() to set non-boolean valuesLuc Van Oostenryck1-0/+4
The function handle_switches() was designated to set or clear simple boolean flags but some options, internally, are non-boolean. So, extend the function so that it can be used to set non-boolean values. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-15cgcc: let cygwin use -fshort-wcharLuc Van Oostenryck1-0/+1
Cygwin uses 'unsigned short' for its wchar_t. So, use -fshort-wchar for it. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-15arch: teach sparse about -fshort-wcharLuc Van Oostenryck4-0/+11
This is useful in cgcc for supporting Cygwin which doesn't use a 32-bit type for wchar_t. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-15arch: keep cygwin specifics with i386/x86-64 specificsLuc Van Oostenryck1-4/+3
No functional changes but it will help to reorganize this code into arch-specific sections. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-15option: move all option parsing helpers before their potential usesLuc Van Oostenryck1-180/+188
The helpers for option parsing are spread all over the functions doing the effective parsing. This doesn't help to reuse these helpers because new potential uses sometimes arise before the helpers itself. Fix this by moving all these helpers above any function which may use them. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-15function attributes apply to the function declarationLuc Van Oostenryck3-1/+37
Function attributes relate to the function declaration they appear in. Sparse ignore most these attributes but a few ones have a semantic value: 'pure', 'noreturn' & 'externally_visible'. Due to how Sparse parse attributes and how these attributes are stored for functions, the attributes 'pure' & 'noreturn' are applied not to the function itself but its return type if the function returns a pointer. Fix this by extracting these attributes from the declaration context and ensure they're applied to the declarator. Reported-by: John Levon <john.levon@joyent.com> Reported-by: Alex Kogan <alex.kogan@oracle.com> Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-14arch: keep BSD & Darwin specifics with i386/x86-64 specificsLuc Van Oostenryck1-7/+7
Without more testing, the specific types for wint_t & int64_t on FreeBSD & Darwin are only valid for i386/x86-64. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-14arch: remove impossible cases with 64-bit arch not being lp64Luc Van Oostenryck2-18/+9
The code at the start of init_target() already take care of making the arch variants match their bitness. It's thus not possible, when setting the type of [u]int32, to have mips64, ppc64, riscv64 or sparc64 with arch_m64 different than ARCH_LP64. So, remove the unneeded checks. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-14arch: do not needlessly set bitness on 32-bit archsLuc Van Oostenryck1-1/+0
The code at the start of init_target() already take care of making the arch variants match their bitness. There is no need to redo that while setting the type of [u]int32. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-14arch: simplify i386/x86-64 specificsLuc Van Oostenryck1-4/+4
The current test for setting wchar on i386 uses a conditional break and a fallthrough on the x86-64 case. This is not needed and can be simplified by reversing the order of the i386 & x86-64 cases. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-14arch: fix the signedness of plain charsLuc Van Oostenryck6-8/+40
Some architectures, like ARM or PPC, use 'unsigned' for plain chars while others, like the Intel's, use signed ones. Sparse understands -funsigned-char but by default uses the native signedness. Fix this by setting the proper signedness of plain chars for the archs that Sparse know about. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-12Add -Wexternal-function-has-definitionJohn Levon5-3/+13
Some older codebases hit this warning all the time, so it's useful to be able to disable it. Signed-off-by: John Levon <john.levon@joyent.com> Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-12lib.c: fix spelling of _BIG_ENDIANRamsay Jones1-1/+1
Commit 3c3881cf1c ("cgcc: let sparse define _BIG_ENDIAN", 2019-11-08) moved the definition of the _BIG_ENDIAN macro from cgcc to sparse (for the powerpc platforms). Unfortunately, the macro was inadvertently spelt incorrectly (as _BIG_DEBIAN). Correct the spelling. Fixes: 3c3881cf1c68f1b4ec4e5a68fa0aa92e88eb275c Signed-off-by: Ramsay Jones <ramsay@ramsayjones.plus.com> Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-11spec: s/size/rank/Luc Van Oostenryck1-6/+6
In declaration_specifiers() the variable 'size' is used to make the distinction between char/short/int/long/long long/... but this correspond more closely to the notion of 'rank' since some of these types can have the same bit-size. Rename the variable 'size' to 'rank'. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-11spec: KW_LONG is not neededLuc Van Oostenryck2-3/+3
To determine the rank of shorts & floats, the keyword type KW_LONG is used but there is no need for a specific keyword since testing for 'Set_Long' has the same effect. So, remove this keyword and test for 'Set_Long' instead as this somehow clarify the processing of specifiers. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-11spec: KW_SHORT is not neededLuc Van Oostenryck2-4/+4
To determine the rank of shorts & floats, the keyword type KW_SHORT is used but there is no need for a specific keyword since testing for 'Set_Short' or 'Set_Float' has the same effect. So, remove this keyword and test the Set_... flags instead as this somehow clarify the processing of specifiers. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-11spec: improve parsing of __int128Luc Van Oostenryck1-4/+4
__int128 is processed as-if 'long' is applied to a 'long long'-like type. But this is not necessary or desirable: better to be more direct and process it as a kind of 'long long long' type. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-11spec: add '.class = CInt'Luc Van Oostenryck1-0/+3
Add it for the specifier that implies an integer type. Since Cint is (and must be) zero, it changes nothing but it helps a little for as documentation. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-11spec: types[] is indexed by the specifier classLuc Van Oostenryck1-2/+4
The array types[] is initialized without using 'designators' but the entries are in fact indexed by the 'class'. Make this clear by using the 'class' constant (CInt, CUInt, CSInt & CReal) as designator in the table initializer. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-11spec: process chars like other integer typesLuc Van Oostenryck1-9/+9
When parsing specifiers, Sparse process chars independently of other integers. But this is not necessary (as long as the proper see/test/set flags are correct). Change this by processing chars the same as other integers but 'below' shorts. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-10Merge branch 'eval-typeof' into nextLuc Van Oostenryck6-4/+46
* clarify lazy evaluation & conversion of SYM_TYPEOF
2019-11-10typeof: examine it at show-timeLuc Van Oostenryck2-1/+1
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-11-10typeof: fix up comment in examine_pointer_type()Luc Van Oostenryck1-4/+5
The comment was added in commit c72032ad3 ("Add comment on what ...") and explain why the size is set before recursing into the object pointed to. But since commit 017034ed4 ("Fix up type examination.") the object is no more examined. Adjust the comment to remove posible confusion. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-09Merge branch 'cgcc-cleanup' into nextLuc Van Oostenryck2-3/+4
* more cgcc simplifications
2019-11-09cgcc: let sparse define _BIG_ENDIANLuc Van Oostenryck2-2/+3
In addition of __BIG_ENDIAN__, gcc defines _BIG_ENDIAN on powerpc (32 & 64-bit). cgcc does that too but this may also beeneeded when using sparse itself. So, move this define the the sparse code. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-08cgcc: remove _STRING_ARCH_unalignedLuc Van Oostenryck1-2/+2
As far as I can see, the macro '_STRING_ARCH_unaligned' may be defined by glibc, not gcc. So, there is no reason for cgcc to define it. Worse, cgcc defines it to '1' while on some platorms (at least the few ppc64 I've access to) the installed glibc defines it to '0'. So, do not let cgcc define this macro. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-06arch: fix setting the endiannessLuc Van Oostenryck1-3/+1
The new --arch flag set arch_big_endian for big endian archs but didn't clear it for little endian ones. Fix it by simply copying the endianness from the arch table. Fixes: 2c06f143fa63394dbdfa07f3f9d00b24b7c902c5 Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-05show-type: add a test program to test do_show_type() & friendsLuc Van Oostenryck3-0/+30
Add another small client doing nothing but display the type of the toplevel symbols. This will help to test further changes in do_show_type(). Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-05Merge branch 'option-arch'Luc Van Oostenryck9-65/+232
* add new option, --arch=ARCH, allowing to specify the target arch.
2019-11-03Merge branch 'rem-unused'Luc Van Oostenryck5-16/+4
2019-11-03remove unneeded MOD_TYPELuc Van Oostenryck4-7/+3
MOD_TYPE is used for the sparse extension which allow to directly compare types with each others. Expressions for direct type are EXPR_TYPE with the type in expr->symbol and the expression itself having it's type (expr->ctype) set to &type_ctype. This is one of the few base/builtin types and is the only one which can have MOD_TYPE. However, a specific modifier is not needed, the address of the symbol can simple be used (like it is done for 'bad_ctype' or 'incomplete_ctype'). Also, there is only a single place where MOD_TYPE is tested: is_type_ctype(), itself used a single time. So: * rewrite the unique test using is_type_ctype() by directly comparing with &type_ctype instead; * remove the now unused is_type_ctype(); * remove MOD_TYPE from type_ctype's definition; * remove MOD_TYPE's definition; and spare one precious bit for other modifiers. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-03remove unused SYM_TYPEDEFLuc Van Oostenryck4-4/+0
SYM_TYPEDEF is not used anymore since the SYM -> MOD conversion. So, remove it. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-03remove unused SYM_MEMBERLuc Van Oostenryck4-4/+0
SYM_MEMBER has never been set. Remove since it's unused. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-03remove unused KW_STATEMENTLuc Van Oostenryck1-1/+1
KW_STATEMENT has never been used. Remove it. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-03fix pointer casts in evaluate_compare()Xi Wang1-4/+4
The results of cast_to() seem unused. Assign them to expr->left and expr->right. Signed-off-by: Xi Wang <xi.wang@gmail.com> Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-11-01Merge branch 'double-underscore'Luc Van Oostenryck1-1/+7
Support '__<attribute-name>__' for all attributes.
2019-11-01Merge branch 'cmodel'Luc Van Oostenryck2-0/+125
Add support for -mcmodel & -f{pic,PIC,pie,PIE}. This is motivated by the kernel using the predefine macros __riscv_cmodel_medlow & __riscv_cmodel_medany.
2019-10-30.gitignore: alphasort the patternsLuc Van Oostenryck1-12/+12
The patterns have most probably been added in a queue-like way but it makes harder to see what's in and what's not. So, alphasort them. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-10-30Add '__' prefix and suffix to all __attribute__ #definesJoe Perches1-1/+7
To avoid macro name collisions and improve portability the kernel want to use a double underscore prefix and suffix on all attributes. However, for some of them (mainly sparse's extensions), Sparse know only about the plain name. Teach Sparse about the double underscore for all attributes. Link: https://lore.kernel.org/r/7a15bc8ad7437dc3a044a4f9cd283500bd0b5f36.camel@perches.com Link: https://lore.kernel.org/r/19fd23e98bab65a1ee624445193bd2ed86108881.camel@perches.com Originally-by: Joe Perches <joe@perches.com> Reported-by: Miguel Ojeda <miguel.ojeda.sandonis@gmail.com> Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-10-30cgcc: removed unneeded predefines for integersLuc Van Oostenryck1-48/+4
Now that the arch is passed to sparse via '--arch=ARCH', all predefines for integers and pointers are defined in sparse itself. So, integer_types() & define_size_t() are now unneeded. Remove these functions and -D__SIZEOF_POINTER__. Note: sparc64 had also an entry for 128-bit integers (with name 'LONG_LONG_LONG' and suffix 'LLL'); GCC only predefines the SIZEOF macros which sparse also does (but for all archs). So, it's fine to remove these also. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-10-30cgcc: specify the arch via --archLuc Van Oostenryck1-4/+11
Now that it's possible to specify the architecture via the --arch=ARCH option, let cgcc make use of it. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-10-30arch: add an option to specify the desired arch: --arch=<arch>Luc Van Oostenryck6-0/+182
Sparse is universal in the sense that the same executable can be used for all architectures. For this, most arch-specific setting can be set with an option and the default values are taken from the host machine. This is working nicely for native targets. However, for cross- compilation, while seeming to work relatively well (thanks to the kernel build system using -m32/-m64 for all archs, for example) things can never work 100% correctly. For example, in the case an X86-64 host machine is used for an ARM target, the kernel build system will call sparse with -m32, Sparse will 'autodetect' the target arch as i386 (x86-64 + -m32) and will then predefine the macro __i386__. Most of the time this is not a problem (at least for the kernel) unless, of course, if the code contains something like: #ifdef __i386__ ... #elif __arm__ ... So, add an option --arch=<arch> to specify the target architecture. The native arch is still used if no such flag is given. Reported-by: Ben Dooks <ben.dooks@codethink.co.uk> Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-10-30arch: change the arch when changing -m32/64Luc Van Oostenryck1-0/+21
If the flag -m32 or -m64 is given in argument, we must insure that the corresponding architecture is changed as well. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-10-30arch: add support for s390 (ILP32)Luc Van Oostenryck3-1/+7
On s390x, the flag -m31 is needed to enable this mode. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-10-30arch: reorder MACH_XXX definesLuc Van Oostenryck1-12/+6
Some architectures have a 32- and a 64-bit variant which can be exchanged via the -m32/-m64 flags. Make clear the correspondance between these variant when defining the MACH_XXX. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-10-30arch: add predefine for __mips__Luc Van Oostenryck1-0/+1
This define was missing for MIPS, add it. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-10-28options: add support for -mcmodelLuc Van Oostenryck2-0/+99
Do the parsing of all models used in the kernel and output the predefines for arm64 & riscv. Reported-by: Paul Walmsley <paul.walmsley@sifive.com> Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-10-28options: add support for -fpic, -fPIC, -fpie & -fPIELuc Van Oostenryck2-0/+26
Do the parsing and output the corresponding predefines. Follow the same rules as GCC: pic/pie -> 1, PIC/PIE -> 2 and pie/PIE implies pic/PIC. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-10-14Sparse v0.6.1v0.6.1Luc Van Oostenryck1-1/+1
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-10-13doc: fix typo in binops' descriptionLuc Van Oostenryck1-2/+2
Both operands of integer & floating-point binops are described as being '.src1' but, of course, the second one should be '.scr2'. Fix the typo. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-10-09"graph" segfaults on top-level asmLuc Van Oostenryck2-1/+2
The "graph" binary segfaults on this input: asm(""); with gdb saying (edited for clarity): Program received signal SIGSEGV, Segmentation fault. in graph_ep (ep=0x7ffff7f62010) at graph.c:52 (gdb) p ep->entry $1 = (struct instruction *) 0x0 Sadly, the commit that introduced this crash: 15fa4d60e ("topasm: top-level asm is special") was (part of a bigger series) meant to fix crashes because of such toplevel asm statements. Toplevel ASM statements are quite abnormal: * they are toplevel but anonymous symbols * they should be limited to basic ASM syntax but are not * they are given the type SYM_FN but are not functions * there is nothing to evaluate or expand about it. These cause quite a few problems including crashes, even before the above commit. So, before handling them more correctly and instead of adding a bunch of special cases here and there, temporarily take the more radical approach of stopping to add them to the list of toplevel symbols. Fixes: 15fa4d60ebba3025495bb34f0718764336d3dfe0 Reported-by: Vegard Nossum <vegard.nossum@gmail.com> Analyzed-by: Vegard Nossum <vegard.nossum@gmail.com> Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-10-09llvm: fix sparsec breakage on recent cygwin versionLuc Van Oostenryck1-0/+1
On recent version of cygwin, sparsec fails because, apparently, lcc is using the wrong triple. This is because: 1) sparse-llvm doesn't use an explicit triple for cygwin; 2) by default, llc use triple of the host machine at build-time as the the default for the target machine. Why/how it was working with previous versions is unknown. Fix this by using, on cygwin, the triple given by llvm-config. Reported-by: Ramsay Jones <ramsay@ramsayjones.plus.com> Investigated-by: Ramsay Jones <ramsay@ramsayjones.plus.com> Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-10-07Sparse v0.6.1-rc2 is now out.Luc Van Oostenryck1-1/+1
The source code can be found at its usual repository: git://git.kernel.org/pub/scm/devel/sparse/sparse.git v0.6.1-rc2 The tarballs are found at: https://www.kernel.org/pub/software/devel/sparse/dist/ Many thanks to people who have contributed to this release: Ben Dooks, Dan Carpenter, Jann Horn, Randy Dunlap, Thomas Weißschuh, Ramsay Jones, Linus Torvalds, Oliver Hartkopp and Ilya Maximets, Most changes since the previous release (v0.6.1-rc1) belong in 2 categories: 1) small fixes and iprovements 2) do the evaluation & expansion of ASM operands The complete list of patches are: Ben Dooks (1): .gitignore: add temporary *~ files Dan Carpenter (1): fix sign extension in casting enums Jann Horn (1): evaluate: externally_visible functions don't need a declaration Luc Van Oostenryck (32): expand: add explanation to 'conservative' add test for evaluation of invalid assignments also accept casts of AS pointers to uintptr_t man: explain role of uintptr_t & unsigned long in casts from AS pointers fix allowing casts of AS pointers to uintptr_t cgcc: fix wrong processing of -MD & -MMD constexpr: relax constexprness of constant conditionals more consistent type info in error messages shorter message for non-scalar in conditionals expand: add test for expansion of compound literals expand: add missing expansion of compound literals dissect: fix processing of ASM statements string: add helper string_expression() string: use string_expression() in parse_static_assert() asm: add test evaluation, expansion & linearization of ASM operands asm: check earlier that body & constraints are strings asm: use a specific struct for asm operands asm: keep using struct asm_operand during linearization asm: parse constraints asm: use parse_asm_constraint() to verify constraints asm: missing evaluation of asm statements asm: linearization of output memory operands is different asm: fix liveness memory operand asm: fix missing expansion of asm statements asm: arrays & functions in non-memory operand degenerate into pointers do not linearize invalid expression add test for enum sign extension remove useless optimization in cast_enum_list() asm: warn on invalid empty constraints make 'directive in argument list' clearer expand more builtins like __builtin_ffs() cleanup: make arch_msize_long static Randy Dunlap (1): problem building sparse 0.6.0 (sparse-llvm) Thomas Weißschuh (1): expand: 'conservative' must not bypass valid simplifications Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-10-03cleanup: make arch_msize_long staticLuc Van Oostenryck2-2/+1
This variable is used to set 'size_t_ctype' with the option '-msize-long'. Code that cares should directly use size_t_ctype, not 'arch_msize_long'. To be sure that some random code doesn't use 'arch_msize_long', make it local to "lib.c". Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-10-03Merge branches 'asm-warn-invalid', 'directive-arg' and 'expand-ffs'Luc Van Oostenryck3-5/+61
* asm: warn on invalid empty constraints * make 'directive in argument list' clearer * expand more builtins like __builtin_ffs()
2019-10-03expand more builtins like __builtin_ffs()Luc Van Oostenryck1-0/+56
GCC expands at compile time builtins like __builtin_ffs() when their argument is constant. A driver in the kernel uses such a builtin in a case statement, causing sparse to report: error: Expected constant expression in case statement So, let sparse also expand such builtins, somehow like it was done for bswap16/32/64 but now for ffs/ffsl/ffsll, clz, ctz, clrsb, popcount & parity. Reported-by: Randy Dunlap <rdunlap@infradead.org> Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com> Tested-by: Randy Dunlap <rdunlap@infradead.org>
2019-10-01make 'directive in argument list' clearerLuc Van Oostenryck2-5/+5
The warning 'directive in argument list' is about macros' arguments, not functions' ones. Make this clearer in the warning message. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-09-30asm: warn on invalid empty constraintsLuc Van Oostenryck1-0/+3
Empty ASM constraints are invalid. So, catch them at parsing time and issue a warning. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-09-30Merge branch 'fix-expand-asm' into tipLuc Van Oostenryck29-147/+455
Currently, ASM operands aren't expanded or even evaluated. This causes Sparse to emit warnings about 'unknown expression' during the linearization of these operands if they contains, for example, calls to __builtin_compatible_types_p(). Note: the correct handling of ASM operands needs to make the distinction between 'memory' operands and 'normal' operands. For this, it is needed to look at the constraints and these are architecture specific. The patches in this series only consider the constraints m, v, o & Q as being for memory operands and, happily, these seems to cover most usage for the most common architectures. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-09-30Merge branch 'relax-constexpr' into tipLuc Van Oostenryck3-17/+25
2019-09-30Merge branch 'fix-bad-linear' into tipLuc Van Oostenryck3-2/+42
Expressions without a valid type should never be linearized since they have no (valid) type and haven't been expanded. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-09-30Merge branch 'fix-enum-sign-extend' into tipLuc Van Oostenryck2-3/+13
In a declaration like: enum { a = 0x80000000, b = -1, } the underlying type should be long and b's value should be 0xffffffffffffffff (on a 64-bit machine) but is 0xffffffff. The fix is in cast_enum_list() to change the the type of the enumeration after casting its value and not before since the original type is needed for the cast. Fixes: 604a148a73af ("enum: fix cast_enum_list()") Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-09-30fix sign extension in casting enumsDan Carpenter2-2/+1
The function cast_value() needs the exact type of the old expression but when called via cast_enum_list() this type is incorrect because: - the same struct is used for the new and the old expression - the type of the new expression is adjusted before cast_value() is called. Fix this by adjusting the type of the new expression only after cast_value() has been called. Fixes: 604a148a73af ("enum: fix cast_enum_list()") Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-09-30remove useless optimization in cast_enum_list()Luc Van Oostenryck1-2/+0
The function cast_enum_list() is used to give the same type to all elements of an enum declaration. The base case for doing this is to call cast_value() on the element, but this call is not done is the size of the element already match the size of the common type. This special case is an optimization but not an interesting one since cast_value() is not a costly function. OTOH, it somehow complicates the flow inside cast_enum_list(). So, remove the optimisation by letting cast_value() to handle all cases. Suggested-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-09-30add test for enum sign extensionLuc Van Oostenryck1-0/+13
In a declaration like: enum { a = 0x80000000, b = -1, } the underlying type should be long and b's value should be 0xffffffffffffffff (on a 64-bit machine) but is 0xffffffff. Reported-by: Dan Carpenter <dan.carpenter@oracle.com> Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-09-30do not linearize invalid expressionLuc Van Oostenryck2-3/+6
Code like: int *r; r = ({ __builtin_types_compatible_p(long, long); }); triggers the following diagnostics: warning: incorrect type in assignment (different base types) expected int *r got long warning: unknown expression (4 0) warning: unknown expression (4 0) The first warning is expected but the other two are bogus. The origin of the problem could be considered as being how type incompabilities are handled in assignment: If an incompatibility is found by compatible_assignment_types() - a warning is issued (not an error), - the source expression is casted to the destination type, - the returned value indicates a problem was detected. In the other uses of this function the returned value is simply ignored and normal processing continue. This seems logical since only a warning is issued and so (thanks to the cast) the resulting expression is at least type-coherent. However, in evaluate_assignment() the returned value is not ignored and the calling function directly returns. This leaves the resulting expression without a valid type, as if an error occured, unable to be correctly processed further. However, the real problem is that an expression without a valid type should never be linearized. So, in linearize_expression(), refuse to linearize an expression without a valid type. Note: if one is interested in doing a maximum of processing, including expansion and linearization, check_assignment_types() should be modified to distinguish between recoverable and non-recoverable type error (those for which the forced cast make sense and those for which it doesn't) and compatible_assignment_types() modified accordingly (maybe issuing a warning in the first case and an error otherwise). Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-09-28asm: arrays & functions in non-memory operand degenerate into pointersLuc Van Oostenryck2-1/+3
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: fix missing expansion of asm statementsLuc Van Oostenryck2-2/+17
The operands of extended ASM need to be expanded, exactly like any other expression. For example, without this expansion expressions with __builtin_compatible_types_p() can't be linearized and will issue a 'warning unknown expression". So, add the missing expansion of ASM operands. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-09-27asm: fix liveness memory operandLuc Van Oostenryck3-1/+6
Since memory operands are only some kind of reference, the pseudo in an output operand is not defined by the statement, the reference is only used. Fix the liveness processing accordingly. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-09-27asm: linearization of output memory operands is differentLuc Van Oostenryck2-5/+9
ASM memory operands are considered by GCC as some kind of implicit reference. Their linearization should thus not create any storage statement: the storage is done by the ASM code itself. Adjust the linearization of such operands accordingly. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-09-27asm: missing evaluation of asm statementsLuc Van Oostenryck2-1/+18
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: use parse_asm_constraint() to verify constraintsLuc Van Oostenryck1-20/+15
In extended ASM statements, output constraints need to be prefixed with "=" or "+" and input constraints must not. This is checked in verify_{output,input}_constraint() where the constraint string is analyzed to look after these two chars. However, the needed information is now already available thanks to parse_asm_constraint(). So, use the result of the parsing of the constraint strings to avoid to analyze again these strings during their verification. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-09-27asm: parse constraintsLuc Van Oostenryck2-2/+80
The details of the ASM constraint strings are needed for their validation but also for the proper evaluation of the operands. So, parse these strings and store the significant properties in struct asm_operand where they can be used for the next steps. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-09-27asm: keep using struct asm_operand during linearizationLuc Van Oostenryck1-15/+10
In linearize_asm_statement(), the functions asm_add_{input,output}() are given the ASM operand 'name', 'constraint' & 'expression' as argument. However, it's much simpler to simply give the whole struct asm_operad. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-09-27asm: use a specific struct for asm operandsLuc Van Oostenryck12-47/+40
Before commit 756731e9 ("use a specific struct for asm operands") ASM operands where stored as a list of n times 3 expressions. After this commit, the triplets where stored inside a single expression of type EXPR_ASM_OPERAND. However, while this improved the parsing and use of ASM operands it needlessly reuse 'struct expression' for something that is not an expression at all. Fix this by really using a specific struct for ASM operands. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-09-27asm: check earlier that body & constraints are stringsLuc Van Oostenryck3-17/+10
The syntax of extended ASM statements requires that the bodies & constraints are given via a literal string. However, at parsing time more general expressions are accepted and it's checked only at evaluation time if these are effectively string literals. This has at least two drawbacks: *) evaluate_asm_statement() is slightly more complicated than needed, mixing these checks with the real evaluation code *) in case of error, the diagnostic is issued later than other syntaxic warnings. Fix this by checking at parse-time that ASM bodies & constraints are string literals and not some arbitrary expressions. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-09-27asm: add test evaluation, expansion & linearization of ASM operandsLuc Van Oostenryck5-0/+174
ASM statements are quite complex. Add some tests to catch some potential errors. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-09-26string: use string_expression() in parse_static_assert()Luc Van Oostenryck2-10/+5
The error handling during the parsing of _Static_assert()'s message string is relatively complex. Simplify this by using the new helper string_expression(). Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-09-26string: add helper string_expression()Luc Van Oostenryck2-0/+12
This will help to detect earlier syntax errors concerning string constants. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-09-26dissect: fix processing of ASM statementsLuc Van Oostenryck1-5/+1
Before commit 756731e9 ("use a specific struct for asm operands"), ASM operands ('name', 'constraint, 'expression') were stored as a sequence of 3 expressions. After, they had their own expression type: EXPR_ASM_OPERAND. However, dissect.c:do_asm_xputs() was not adapated for this change. Fix this in do_asm_xputs() by processing the 'expression' of every entries (instead of only processing every third entries). CC: Oleg Nesterov <oleg@redhat.com> Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-09-26expand: add missing expansion of compound literalsLuc Van Oostenryck4-2/+9
Compound literals, like all other expressions, need to be be expanded before linearization, but this is currently not done. As consequence, some builtins are unexpectedly still present, same for EXPR_TYPEs, ... with error messages like: warning: unknown expression at linearization. Fix this by adding the missing expansion of compound literals. Note: as explained in the code itself, it's not totally clear how compound literals can be identified after evaluation. The code here consider all anonymous symbols with an initializer as being a compound literal. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2019-09-26expand: add test for expansion of compound literalsLuc Van Oostenryck1-0/+27
Compound literals are currently not expanded. Add a test for this. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>