For integer promotion with for example arithmetics or
expr_cond (x ? y : z), integral types need to be promoted
to signed if they fit.
According to latest standards, this also applies to bit-field
types taking into account their specific width.
In tcc, VT_BITFIELD set means width < original type width
Field-widths between 33 and 63 are promoted to signed long long
accordingly.
struct { unsigned long long ullb:35; } s = { 1 };
#define X (s.ullb - 2)
int main (void)
{
long long Y = X;
printf("%d %016llx %016llx\n", X < 0, -X, -Y);
return 0;
}
Results:
GCC 4.7 : 0 0000000000000001 FFFFFFF800000001
MSVC : 1 0000000000000001 0000000000000001
TCC : 1 0000000000000001 0000000000000001
Also, gcc would promote long long bitfields of size < 32
to int as well. Example:
struct { unsigned long long x:20; } t = { 123 };
/* with gcc: */ printf("%d %d\n", t.x, 456);
/* with tcc: */ printf("%lld %d\n", t.x, 456);
See the added testcase. When one used designators like .a.x to initialize
sub-members of members, and didn't then initialize all of them the
required zero-initialization of the other sub-members wasn't done.
The fix also enables tiny code cleanups.
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.
- 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
supports building cross compilers on the fly without need
for configure --enable-cross
$ make cross # all compilers
$ make cross-TARGET # only TARGET-compiler & its libtcc1.a
with TARGET one from
i386 x86_64 i386-win32 x86_64-win32 arm arm64 arm-wince c67
Type 'make help' for more information
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
- lib/Makefile: add (win)crt1_w.o
- crt1.c/_runtmain: return to tcc & only use for UNICODE
(because it might be not 100% reliable with for example
wildcards (tcc *.c -run ...)
- tccrun.c/tccpe.c: load -run startup_code only if called
from tcc_run(). Otherwise main may not be defined. See
libtcc_test.c
- tests2/Makefile: pass extra options in FLAGS to allow
overriding TCC
Also:
- tccpe.c: support weak attribute. (I first tried to solve
the problem above by using it but then didn't)
Also:
- in tests: generate .expect files only if not yet present,
because
1) some files were adjusted manually
2) switching git branche might change timestamps and
cause unwanted update
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.
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
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.
If a condition is always zero/non-zero we can omit the
then or else code. This is complicated a bit by having to
deal with labels that might make such code reachable without
us yet knowing during parsing.
In statement expression we really mustn't emit backward jumps
under nocode_wanted (they will form infinte loops as no expressions
are evaluated). Do-while and explicit loop with gotos weren't
handled.
For
union U { struct {int a,b}; int c; };
union U u = {{ 1, 2, }};
The unnamed first member of union U needs to actually exist in the
structure so initializer parsing isn't confused about the double braces.
That means also the a and b members must be part of _that_, not of
union U directly. Which in turn means we need to do a bit more work
for field lookup.
See the testcase extension for more things that need to work.
Remove dead code and variables. Properly check for unions when
skipping fields in initializers. Make tests2/*.expect depend
on the .c files so they are automatically rebuilt when the latter
change.
E.g. "struct { struct S s; int a;} = { others, 42 };"
if 'others' is also a 'struct S'. Also when the value is a
compound literal. See added testcases.
Previously in order to perform a ll+ll operation tcc
was trying to 'lexpand' PTR in gen_opl which did
not work well. The case:
int printf(const char *, ...);
char t[] = "012345678";
int main(void)
{
char *data = t;
unsigned long long r = 4;
unsigned a = 5;
unsigned long long b = 12;
*(unsigned*)(data + r) += a - b;
printf("data %s\n", data);
return 0;
}
Except
- that libtcc1.a is now installed in subdirs i386/ etc.
- the support for arm and arm64
- some of the "Darwin" fixes
- tests are mosly unchanged
Also
- removed the "legacy links for cross compilers" (was total mess)
- removed "out-of-tree" build support (was broken anyway)
* correct -E output for the case ++ + ++ concatenation
do this only for expanded from macro string
and only when tcc_state->output_type == TCC_OUTPUT_PREPROCESS
From gcc docs: "You may also specify attributes between the enum, struct or union tag and the name of the type rather than after the closing brace."
Adds `82_attribs_position.c` in `tests/tests2`
made like in pcc
(pcc.ludd.ltu.se/ftp/pub/pcc-docs/pcc-utf8-ver3.pdf)
We treat all chars with high bit set as alphabetic.
This allow code like
#include <stdio.h>
int Lefèvre=2;
int main() {
printf("Lefèvre=%d\n",Lefèvre);
return 0;
}
the check on incomplete struct/union/enum types was too early,
disallowing mixed specifiers and qualifiers. Simply rely on
the size (->c) field for that. See testcases.
* Documentation is now in "docs".
* Source code is now in "src".
* Misc. fixes here and there so that everything still works.
I think I got everything in this commit, but I only tested this
on Linux (Make) and Windows (CMake), so I might've messed
something up on other platforms...