| Age | Commit message (Collapse) | Author | Files | Lines |
|
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>
|
|
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>
|
|
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
Signed-off-by: John Levon <john.levon@joyent.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
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>
|
|
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>
|
|
Signed-off-by: John Levon <john.levon@joyent.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
When detecting SunOS, '&&' was used instead of '||'.
Fix that.
Fixes: 6bca188679d235ddbad2e97aa3e4186a4730686e
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
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>
|
|
* move arch specificities in their own files
* better support of arch specificities
|
|
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>
|
|
Fix some embarrassing typos.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
* improve diagnostic message about wrong redeclaration
|
|
* tidy-up of typeof expansion
|
|
* improve expansion of constant symbols
|
|
* fix testcase with non-constant initializer
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
Two testcases had their command wrongly terminated by ';'.
Fix this by removing this ';'.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
Sparse can't do this yet.
So, add a testcase for it.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
* fix premature examination of dereferenced object
|
|
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>
|
|
* improve diagnostic messages concerning bitfields
|
|
* testsuite: avoid standard includes in the tests
|
|
* remove redundant to degenerate()
|
|
* add support for '-std=c17/c18'
This is mainly an excuse for cleaning the associated
code and to easily test 'strict' vs. 'gnu'.
|
|
'__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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
Add some testcases before making related changes.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
|
|
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>
|
|
Teach Sparse about these options.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
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>
|
|
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
|
|
|
|
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
Cygwin uses 'unsigned short' for its wchar_t.
So, use -fshort-wchar for it.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
__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>
|
|
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>
|
|
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>
|
|
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>
|
|
* clarify lazy evaluation & conversion of SYM_TYPEOF
|
|
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>
|
|
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>
|
|
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>
|
|
* more cgcc simplifications
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
* add new option, --arch=ARCH, allowing to specify the target arch.
|
|
|
|
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>
|
|
SYM_TYPEDEF is not used anymore since the SYM -> MOD conversion.
So, remove it.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
SYM_MEMBER has never been set.
Remove since it's unused.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
KW_STATEMENT has never been used.
Remove it.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
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>
|
|
Support '__<attribute-name>__' for all attributes.
|
|
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.
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
On s390x, the flag -m31 is needed to enable this mode.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
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>
|
|
This define was missing for MIPS, add it.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
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>
|
|
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>
|
|
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
* asm: warn on invalid empty constraints
* make 'directive in argument list' clearer
* expand more builtins like __builtin_ffs()
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
ASM statements are quite complex.
Add some tests to catch some potential errors.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
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>
|
|
This will help to detect earlier syntax errors concerning
string constants.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
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>
|
|
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>
|
|
Compound literals are currently not expanded.
Add a test for this.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|