See testcase. If an enum has only positive values, fits N bits,
and is placed in a N-bit bit-field that bit-fields must be treated
as unsigned, not signed.
This invalid function definition:
int f()[] {}
was tried to be handled but there was no testcase if it actually worked.
This fixes it and adds a TCC only testcase.
introduce common_section (SHN_COMMON), factorize some handling
in decl_initializer_alloc, add section_add and use it to factorize
some code that allocates stuff in sections (at the same time also fixing
harmless bugs re section alignment), use init_putv to emit float consts
into .data from gv() (fixing an XXX).
factor code a bit for transforming tokens into SValues. This revealed
a bug in TOK_GET (see testcase), which happened to be harmless before.
So fix that as well.
The canonical way to describe a local variable that actually holds
the address of an lvalue is VT_LLOCAL. Remove the last user of VT_REF,
and handling of it, thereby freeing a flag for SValue.r.
VT_LLOCAL is a flag on .r, not on type.t. Fixing this requires
minor surgery for compound literals which accidentally happened
to be subsumed by the bogus test.
the second argument can be an arbitrary expression (including
side-effects), not just a constant. This removes the last user
of expr_lor_const and hence also that function (and expr_land_const).
Also the argument to __builtin_constant_p can be only a non-comma
expression (like all functions arguments).
Our code generation assumes that it can load/store with the
bit-fields base type, so bit_pos/bit_size must be in range for this.
We could change the fields type or adjust offset/bit_pos; we do the
latter.
Checked the lcc testsuite for bitfield stuff (in cq.c and fields.c),
fixed one more error in initializing unnamed members (which have
to be skipped), removed the TODO.
- configure/Makefiles: minor adjustments
- build-tcc.bat: add -static to gcc options
(avoids libgcc_s*.dll dependency with some mingw versions)
- tccpe.c/tcctools.c: eliminate MAX_PATH
(not available for cross compilers)
- tccasm.c: use uint64_t/strtoull in unary()
(unsigned long sometimes is only uint32_t, as always on windows)
- tccgen.c: Revert (f077d16c) "tccgen: gen_cast: cast FLOAT to DOUBLE"
Was a rather experimental, tentative commit, not really necessary
and somewhat ugly too.
- cleanup recent osx support:
- Makefile/libtcc.c: cleanup copy&paste code
- tccpp.c: restore deleted function
Also, retain storage qualifiers in type_decl, in particular
also for function pointers. This allows to get rid of this
very early hack in decl()
type.t |= (btype.t & VT_STATIC); /* Retain "static". */
which was to fix the case of
int main() { static int (*foo)(); ...
Also:
- missing __declspec(dllimport) is an error now
- except if the symbol is "_imp__symbol"
- demonstrate export/import of data in the dll example (while
'extern' isn't strictly required with dllimport anymore)
- new function 'patch_storage()' replaces 'weaken_symbol()'
and 'apply_visibility()'
- new function 'update_storage()' applies storage attributes
to Elf symbols.
- put_extern_sym/2 accepts new pseudo section SECTION_COMMON
- add -Wl,-export-all-symbols as alias for -rdynamic
- add -Wl,-subsystem=windows for mingw compatibility
- redefinition of 'sym' error for initialized global data
Forgot about it. It allows to compile several
sources (and other .o's) to one single .o file;
tcc -r -o all.o f1.c f2.c f3.S o4.o ...
Also:
- option -fold-struct-init-code removed, no effect anymore
- (tcc_)set_environment() moved to tcc.c
- win32/lib/(win)crt1 minor fix & add dependency
- debug line output for asm (tcc -c -g xxx.S) enabled
- configure/Makefiles: x86-64 -> x86_64 changes
- README: cleanup
- tccgen.c/tcc.h: allow function declaration after use:
int f() { return g(); }
int g() { return 1; }
may be a warning but not an error
see also 76cb1144ef
- tccgen.c: redundant code related to inline functions removed
(functions used anywhere have sym->c set automatically)
- tccgen.c: make 32bit llop non-equal test portable
(probably not on C67)
- dynarray_add: change prototype to possibly avoid aliasing
problems or at least warnings
- lib/alloca*.S: ".section .note.GNU-stack,"",%progbits" removed
(has no effect)
- tccpe: set SizeOfCode field (for correct upx decompression)
- libtcc.c: fixed alternative -run invocation
tcc "-run -lxxx ..." file.c
(meant to load the library after file).
Also supported now:
tcc files ... options ... -run @ arguments ...
Some code in gen_opl was depending on a gvtst label
which in nocode_wanted mode is not set.
This was causing vstack leaks and crashes with for example
long long ll;
if (0)
return ll - 10 < 0;
Also:
- on windows i386 and x86-64, structures of size <= 8 are
NOT returned in registers if size is not one of 1,2,4,8.
- cleanup: put all tv-push/pop/swap/rot into one place
Some more subtle issues with code suppression:
- outputting asms but not their operand setup is broken
- but global asms must always be output
- statement expressions are transparent to code suppression
- vtop can't be transformed from VT_CMP/VT_JMP when nocode_wanted
Also remove .exe files from tests2 if they don't fail.
Restore ebx from *ebp because alloca might change esp.
Also disable USE_EBX for upcoming release.
Actually the benefit is less than one would expect, it
appears that tcc can't do much with more than 3 registers
except with extensive use of long longs where the disassembly
looks much prettier (and shorter also).
Also: tccgen/expr_cond() : fix wrong gv/save_regs order
Also ...
tcctest.c:
- exclude stuff that gcc doesn't compile on windows.
libtcc.c/tccpp.c:
- use unsigned for memory sizes to avoid printf format warnings
- use "file:line: message" to make IDE error parsers happy.
tccgen.c: fix typo
tccgen.c: remove any 'nocode_wanted' checks, except in
- greloca(), disables output elf symbols and relocs
- get_reg(), will return just the first suitable reg)
- save_regs(), will do nothing
Some minor adjustments were made where nocode_wanted is set.
xxx-gen.c: disable code output directly where it happens
in functions:
- g(), output disabled
- gjmp(), will do nothing
- gtst(), dto.
when an alignment is explicitely given on the member itself,
or on its types attributes then respect it always. Was only
allowed to increase before, but GCC is allowing it.
The linux kernel has some structures that are page aligned,
i.e. 4096. Instead of enlarging the bit fields to specify this,
use the fact that alignment is always power of two, and store only
the log2 minus 1 of it. The 5 bits are enough to specify an alignment
of 1 << 30.
Another corner case:
struct foo6_1
{
char x;
short p:8;
short :0;
short :0;
short p2:8;
char y;
};
In MS layout the second anon :0 bit-field does _not_ adjust size or
alignment of the struct again. The first one does, though.
Bit-fields are layed out differently in visual C, this implements
a compatible mode. Checked against Visual C/C++ 2016.
Unfortunately the GCC implementation of MS layout (behind
-mms-bitfields) actually is different, and hence not compatible
with MS in all cases :-/
Such struct decl:
struct S { char a; int i;} __attribute__((packed));
should be accepted and cause S to be five bytes long (i.e.
the packed attribute should matter). So we can't layout
the members during parsing already. Split off the offset
and alignment calculation for this.
See testcases. We now support 64bit case constants. At the same time
also 64bit enum constants on L64 platforms (otherwise the Sym struct
isn't large enough for now). The testcase also checks for various
cases where sign/zero extension was confused.
In certain very specific situations (involving switches
with asms inside dead statement expressions) we could generate
invalid code (clobbering the buffer so much that we generated
invalid instructions). Don't emit the decision table if the
switch itself is dead.
When intializing members where the initializer needs relocations
and the member is initialized multiple times we can't allow
that to lead to multiple relocations to the same place. The last
one must win.
Similar to GCC a local asm register variable enforces the use of a
specified register in asm operands (and doesn't otherwise
matter). Works only if the variable is directly mentioned as
operand. For that we now generally store a backpointer from
an SValue to a Sym when the SValue was the result of unary()
parsing a symbol identifier.