- remove any error messages that were just for debugging the
templates really
- don't use c99 in tcc (array designators etc.)
- remove memory model type (cannot be an own type really)
and move memory model defines from built-in to stdatomics.h
- apply normal casts to non-pointer atomic_function arguments
- tidy the library support
- add some tests for errors/warnings
Also:
- Makefile: move GIT_HASH stuff from CFLAGS to DEFINES and into
main section (away from what is included by tests for example)
- tccelf.c/tccgen.c: avoid some warnings with newer GCC
Some complex types can still be small and simple enough to fit into
register. Other compilers allow some operations on these types, and it
seems to be quite a reasonable choice. From now on, we should be able
to compile the following artificial example:
struct combo {
uint16_t lo;
uint16_t hi;
};
struct combo load(const _Atomic(struct combo) *atom)
{
return atomic_load(atom);
}
void store(_Atomic(struct combo) *atom, struct combo value)
{
atomic_store(atom, value);
}
struct combo xchg(_Atomic(struct combo) *atom, struct combo value)
{
return atomic_exchange(atom, value);
}
bool cmpxchg(_Atomic(struct combo) *atom,
struct combo *cmp, struct combo xchg)
{
return atomic_compare_exchange_strong(atom, cmp, xchg);
}
This might be useful for some corner cases, though it is quite likely
that many programmers will prefer operating on a single 32-bit value
instead of using the structure consisting of 16-bit pair.
Things will work as long as the overall structure size happens to be
the same as for any integer type we support in atomics.
libtcc.c: add -Wwrite-strings to -Wall
tccgen.c: ro float-consts, string-consts, ro arrays if base type is
tccpe.c: merge IAT with rodata
tccrun.c: mprotect rodata accordingly. free section data after copy
x86_64.c: do not use got for static data.
tcc -bench: show data.rw/ro
Probably STB_LOCAL should never get to put_got_entry(), and currently
it doesn't seem to happen (See "Hack Alarm" there)
Other files: use more ro-data in tinycc
when used with string initialization the size of nested struct flex
array member was tested too late for < 0.
GCC accepts but discards such initializers (the flex array member will
become zero sized). TCC supports flex arrays members only in
top-level structs and gives an error in this case.
When defining an array with non-explicit size, one would get
"incompatible types for redefinition of 'array' if the array was already
declared with a different size.
For example:
extern int array[2];
int array[] = {1};
would fail to compile with tcc. Instead the above is now equivalent to:
int array[] = {1, 0};
this change fixes building of invalid types. The inner scope
struct P is return type of the forward decl foobar. The outer scope
foobar() call implicitely declares that function again, with int
return type; overall this leads to access within the sym free list,
effectively building up a type directly referring to itself, leading
to endless recursion later. The testcase is:
void n(void)
{
{
struct P {
int __val;
};
struct P foobar(); // 1
}
foobar(); // 2
}
I've not included it in tests2 for now, because tcc accepts this.
Ideally we would like to reject it (as 'int foobar();' is incompatible
with the earlier decl). clang also accepts it, but only because it's
not handling (1) above as an implicit decl of foobar (it warns, and
with -pedantic also warns about the type incompatiblity). GCC rejects
this.
Implementing that in tcc requires some surgery, as we need to differ
between these cases:
{ struct P foo(int); // 1
foo(); // no implicit decl, call to foo from 1
}
and
{ { struct P foo(int); // 2 }
foo(); // implicit decl, _incompatible_ with 2
}
normally the sym slot is meaningful only with VT_SYM. But we also
use it when mentioning a decl for inline asms with register vars,
conditional on being a VT_LOCAL entry. So when generating VT_LOCAL we
need to reset .sym as it might contain stale entries from the cmp_op
fields.
with fuzzed source code we might run into this with idx out of bounds.
We're going to error out on this later, but let's not access
out-of-bounds elements.
see testcase, reduced example of a situation reported by
Kyryl Melekhin in https://github.com/kyx0r/neatvi/ .
Problem is that setting up the VLA sp-save in a scope that isn't
entered at runtime leaves traces of it in outer scopes that then
try to restore the stack pointer from uninitialized slots.