Commit Graph

447 Commits

Author SHA1 Message Date
Michael Matz
04418c7add Fix function types
various cases of function type uses were broken by recent
attribute refactoring, this fixes and adds testcases for them.
2017-07-14 17:42:48 +02:00
Michael Matz
2acb04f7f2 tccasm: Fix local statics referenced from asms
The assembler uses the ->sym_scope member to walk up the symbols
until finding a non-automatic symbol.  Since reordering the
members of Sym the sym_scope member contains a scope even for local
statics.  Formerly the use of asm_label for statics was implicitely
clearing sym_scope, now we have to do that explicitely.

Add a testcase for that, and one I encountered when moving the
clearing of sym_scope too deep into the call chain (into put_extern_sym).
2017-07-10 22:29:28 +02:00
Michael Matz
9bea88d616 Fix statement exprs returning a local label
Like returned local variables also labels local to a statement expression
can be returned, and so their symbols must not be immediately freed
(though they need to be removed from the symbol table).
2017-07-10 22:25:11 +02:00
Michael Matz
2240422da9 enums: Accept GNU extension
See testcase.  Happens e.g. in the linux kernel.
2017-07-10 22:20:34 +02:00
grischka
a9e502cc3b refactor bitfields
Use 2 level strategy to access packed bitfields cleanly:

1) Allow to override the original declaration type with
   an auxilary "access type".  This solves cases such as

    struct {
        ...
        unsigned f1:1;
    };

    by using VT_BYTE to access f1.

2) Allow byte-wise split accesses using two new functions
   load/store_packed_bf. This solves any cases, also ones
   such as

    struct __attribute((packed)) _s {
        unsigned x : 12;
        unsigned char y : 7;
        unsigned z : 28;
        unsigned a: 3;
        unsigned b: 3;
        unsigned c: 3;
    };

    where for field 'z':
    - VT_INT access from offset 2 would be unaligned
    - VT_LLONG from offset 0 would go past the total
      struct size (7)

    and for field 'a' because it is in two bytes and
    aligned access with VT_SHORT/INT is not possible.

Also, static bitfield initializers are stored byte-wise always.
Also, cleanup the struct_layout function a bit.
2017-07-09 12:38:59 +02:00
grischka
f87afa72e0 refactor enums
Eliminate VT_ENUM as a basic type.  Instead use the integral
types VT_InT/VT_LLONG with an additional flag to indicate
that it is an enum.
2017-07-09 12:38:25 +02:00
grischka
9ba76ac834 refactor sym & attributes
tcc.h:
* cleanup struct 'Sym'
* include some 'Attributes' into 'Sym'
* in turn get rid of VT_IM/EXPORT, VT_WEAK
* re-number VT_XXX flags
* replace some 'long' function args by 'int'

tccgen.c:
* refactor parse_btype()
2017-07-09 12:34:11 +02:00
grischka
9f79b62ec4 unsorted adjustments
- configure
  * use aarch64 instead of arm64

- Makefile
  * rename the custom include file to "config-extra.mak"
  * Also avoid "rm -r /*" if $(tccdir) is empty

- pp/Makefile
  * fix .expect generation with gcc

- tcc.h
  * cleanup #defines for _MSC_VER

- tccgen.c:
  * fix const-propagation for &,|
  * fix anonymous named struct (ms-extension) and enable
    -fms-extension by default

- i386-gen.c
  * clear VT_DEFSIGN

- x86_64-gen.c/win64:
  * fix passing structs in registers
  * fix alloca (need to keep "func_scratch" below each alloca area on stack)
    (This allows to compile a working gnu-make on win64)

- tccpp.c
  * alternative approach to 37999a4fbf
    This is to avoid some slowdown with ## token pasting.
  * get_tok_str() : return <eof> for TOK_EOF
  * -funsigned-char: apply to "string" literals as well

- tccpe/tools.c: -impdef: support both 32 and 64 bit dlls anyway
2017-07-09 12:07:40 +02:00
Matthias Gatto
157bad52cd add C11's _Generic
Simple implementation, I'm not even sure to respect C standart here,
but it should work with most use case.

This add an case in unary(), and generate TokString depending of _Generic
controlling exression, use begin_macro to "push"
the generated TokString, then call unary() again before exiting the switch
so the just add token are reevaluate again.
2017-07-05 10:57:50 +02:00
Michael Matz
9ed8b54f6c Revert "String literals are always const"
This reverts commit d4fe9aba3f.
I was confused by the fact that string literals aren't writable.
Nevertheless the type isn't const.  As extension in GCC it's const
with -Wwrite-string, which is exactly what we had before.

GCC also wonders in a comment if it's really a good idea to change
expression types based on warning flags (IMHO it's not), but let's
be compatible.  So restore the state from before.
2017-07-04 16:37:49 +02:00
Michael Matz
580ad5f24c Extend skip_or_save_block
Make it stop also before outer level closing parens.  This way
we can now also skip/save the expression inside "foobar(42 + 41)".
2017-07-03 19:15:16 +02:00
Michael Matz
27ca303874 Improve skip_or_save_block
Stop at level 0 only for matching outer '}' (which is added).
Otherwise stop only at stop tokens (which aren't added).
2017-07-03 18:13:15 +02:00
Michael Matz
d4fe9aba3f String literals are always const
Don't make the standard mandated types of string literals
depends on warning options.  Instead make them always const,
but limit the emission of the warning by that option.
2017-07-03 18:02:57 +02:00
Michael Matz
31e5ad789a Limit access end-of-struct warning a bit
Only warn if the struct has a non-zero size.  You can't create objects
of zero-sized structs, but they can be used inside sizeof (e.g.
"sizeof (struct {int :0;})".  The warning would always trigger for these,
but as no objects can be created no accesses can ever happen.
2017-05-27 22:44:53 +02:00
grischka
28435ec58c configure: --config-musl/-uClibc switch & misc cleanups
- configure:
  - add --config-uClibc,-musl switch and suggest to use
    it if uClibc/musl is detected
  - make warning options magic clang compatible
  - simplify (use $confvars instead of individual options)
- Revert "Remove some unused-parameter lint"
  7443db0d5f
  rather use -Wno-unused-parameter (or just not -Wextra)
- #ifdef functions that are unused on some targets
- tccgen.c: use PTR_SIZE==8 instead of (X86_64 || ARM64)
- tccpe.c: fix some warnings
- integrate dummy arm-asm better
2017-05-13 08:59:06 +02:00
grischka
1ed20a01c9 bitfields: promote to signed int
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);
2017-05-09 18:36:24 +02:00
grischka
d242706f3b bitfields: one more hack and a "-Wgcc-compat" switch
bit_pos + bit_size > type_size * 8

must NEVER happen because the code generator can read/write
only the basic integral types.

Warn if tcc has to break GCC compatibility for that reason
and if -Wgcc-compat is given.

Example:
    struct __attribute__((packed)) _s
    {
        unsigned int x  : 12;
        unsigned char y :  7;
        unsigned int z  : 28;
    };

Expected (GCC) layout (sizeof struct = 6)
.xxxxxxxx.xxxxyyyy.yyyzzzzz.zzzzzzzz.zzzzzzzz.zzzzzzz0.

But we cannot read/write 'char y'from 2 bytes in memory.
So we have to adjust:
.xxxxxxxx.xxxx0000.yyyyyyyz.zzzzzzzz.zzzzzzzz.zzzzzzzz.zzz00000

Now 'int z' cannot be accessed from 5 bytes.  So we arrive
at this (sizeof struct = 7):
.xxxxxxxx.xxxx0000.yyyyyyy0.zzzzzzzz.zzzzzzzz.zzzzzzzz.zzzz0000

Otherwise the bitfield load/store generator needs to be
changed to allow byte-wise accesses.

Also we may touch memory past the struct in some cases
currently.  The patch adds a warning for that too.

   0:	55                   	push   %ebp
   1:	89 e5                	mov    %esp,%ebp
   3:	81 ec 04 00 00 00    	sub    $0x4,%esp
   9:	90                   	nop

    struct __attribute__((packed)) { unsigned x : 5; } b = {0} ;

   a:	8b 45 ff             	mov    -0x1(%ebp),%eax
   d:	83 e0 e0             	and    $0xffffffe0,%eax
  10:	89 45 ff             	mov    %eax,-0x1(%ebp)

This touches -0x1 ... +0x3(%ebp), hence 3 bytes beyond
stack space.  Since the data is not changed, nothing
else happens here.
2017-05-09 18:10:02 +02:00
Michael Matz
377e8e5e68 bitfields: fix long bitfields
now the testcase works on i386-linux as well.
2017-05-08 19:58:31 +02:00
Larry Doolittle
19d8b8a173 Spelling fixes in C comments only 2017-05-07 21:38:09 -07:00
grischka
44abffe33a more minor fixes
* tccgen: re-allow long double constants for x87 cross
  sizeof (long double) may be 12 or 16 depending on host platform
  (i386/x86_64 on unix/windows).
  Except that it's 8 if the host is on windows and not gcc
  was used to compile tcc.

* win64: fix builtin_va_start after VT_REF removal
  See also a8b83ce43a

* tcctest.c: remove outdated limitation for ll-bitfield test
  It always worked, there is no reason why it should not work
  in future.

* libtcc1.c: exclude long double conversion on ARM

* Makefile: remove CFLAGS from link recipes

* lib/Makefile: use target DEFINES as passed from main Makefile

* lib/armflush.c lib/va_list.c: factor out from libtcc1.c

* arm-gen.c: disable "depreciated" warnings for now
2017-05-07 12:41:29 +02:00
Michael Matz
94ac9f2b49 Accept extern initialized file-scope variables
'extern int i = 42;' at file scope (but not in function scope!) is
allowed and is a proper definition, even though questionable style;
some compilers warn about this.
2017-05-07 08:10:06 +02:00
Michael Matz
ff998900b1 struct-init: Fix zero initialization with multi-level designators
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.
2017-05-06 05:28:13 +02:00
Michael Matz
0757234560 Fix unsigned enum bit-fields
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.
2017-05-05 23:16:43 +02:00
Michael Matz
a7a3627ab2 Fix segfault with invalid function def
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.
2017-05-05 22:01:02 +02:00
Michael Matz
149678e888 Tidy decl_designator
Removing the need for the notfirst local variable, and tidy loop structure
and error messaging a bit.
2017-05-02 03:14:05 +02:00
Michael Matz
9839b60177 Remove label_or_decl
The only use of this function can be rewritten in terms of
is_label (if one other use of that one are a bit amended).
2017-05-02 03:14:05 +02:00
Michael Matz
c7dbc900c8 Cleanups (float consts, sections, symbols)
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).
2017-05-02 03:13:55 +02:00
Michael Matz
25522e4799 Merge func_decl_list into decl0
Removes some code duplication and also implements one feature:
checking for duplicate decls for old style parameters.
2017-05-02 03:07:37 +02:00
Michael Matz
7aef0522b0 Tidy decl_designator
The fixme therein is long solved.
2017-05-02 03:07:37 +02:00
Michael Matz
8ca98e23c4 Tidy unary() a bit
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.
2017-05-02 03:07:37 +02:00
Michael Matz
21b12ea10d Factor some code
Three places that skip (and store) tokens in some fashion can
be factored a bit.
2017-05-02 03:07:37 +02:00
Michael Matz
328b06a3fc Extend type_to_str
to also print storage-class specifiers.
2017-05-02 03:07:36 +02:00
Michael Matz
182367e232 Reorganize type parsing
Various corner cases for declarator parsing were incorrect.  This
reorganizes and fixes it, and somewhat simplifies it as well.
2017-05-02 03:07:36 +02:00
Michael Matz
5891fbc0c8 Tidy typename parsing a bit 2017-05-02 03:07:36 +02:00
Michael Matz
51314932e3 Tidy arg parsing for builtins
Saves some lines of code.
2017-05-02 03:07:36 +02:00
Michael Matz
a8b83ce43a Remove VT_REF
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.
2017-05-02 03:07:36 +02:00
Michael Matz
8b9697ca6b Fix bogus check for VT_LLOCAL types
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.
2017-05-02 03:07:36 +02:00
Michael Matz
3c39cb5cd8 fix __builtin_expect
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).
2017-05-02 03:07:36 +02:00
Michael Matz
8d9dd3c008 Fix more bitfield corner cases
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.
2017-05-01 06:18:48 +02:00
Michael Matz
4ce73354fc Fix last change
Skipping anonymous bit-fields is correct, but not other
anonymous ones like unions or structs.
2017-05-01 06:04:19 +02:00
Michael Matz
f775d68725 Remove a bit-field TODO
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.
2017-04-29 22:09:10 +02:00
Michael Matz
28084420fe Fix char bitfields corner case
See testcase.
2017-04-29 21:25:31 +02:00
grischka
7acf9aa862 final adjustments for release
- 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
2017-04-25 21:01:54 +02:00
grischka
536ed76d5a tccgen/win32: let __declspec(dllimport) imply extern
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
2017-04-04 08:34:52 +02:00
grischka
5f33d313c8 tcc: re-enable correct option -r support
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
2017-02-20 18:58:08 +01:00
grischka
a4a20360e9 fixes & cleanups
- 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 ...
2017-02-13 18:23:43 +01:00
grischka
ec6a997f80 tccgen: yet another nocode_wanted fix
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;
2017-02-12 13:21:20 +01:00
grischka
68666eee2a tccgen: factor out gfunc_return
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
2017-02-08 19:45:31 +01:00
grischka
f077d16c20 tccgen: gen_cast: cast FLOAT to DOUBLE
... to avoid precision loss when casting to int,
also when saving FLOATs to stack
2017-02-05 14:30:20 +01:00
Michael Matz
42e2a67f23 Fix some code suppression fallout
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.
2016-12-20 04:58:34 +01:00
grischka
559ee1e940 i386-gen: fix USE_EBX
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
2016-12-19 00:33:01 +01:00
grischka
a1c12b9fb9 tests: add memory leak test
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
2016-12-18 22:05:42 +01:00
grischka
f7fc4f02cf tccgen: nocode_wanted++/--
uses 'nocode_wanted' as a level couter instead of
'saved_nocode_wanted' everywhere.
2016-12-18 18:58:33 +01:00
grischka
e5efd18435 tccgen: fix expr_cond for alt. nocode_wanted
making shure that both the active and the passive branches
do exacly the same thing.
2016-12-18 18:55:55 +01:00
grischka
f843cadb6b tccgen: nocode_wanted alternatively
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.
2016-12-18 18:53:21 +01:00
Michael Matz
b5b12b89a0 arm64: Fix a case of dead code suppression
82_nocode_wanted.c:kb_wait_2_1 was miscompiled on arm64.
2016-12-15 17:49:56 +01:00
Michael Matz
f5ae4daa5f struct-layout: Allow lowering of member alignment
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.
2016-12-15 17:49:56 +01:00
Michael Matz
8859dc9e6d Support large alignment requests
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.
2016-12-15 17:49:56 +01:00
Michael Matz
d815a0f658 struct-layout: cleanup code a bit 2016-12-15 17:49:56 +01:00
Michael Matz
23b257a8d2 bitfields: Fix MS layout some more
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.
2016-12-15 17:49:56 +01:00
Michael Matz
ed680da951 bitfields: fix PCC layout
Fixes some corner cases in PCC layout.  Testcases coming
up.
2016-12-15 17:49:56 +01:00
Michael Matz
bd69bce20f bitfields: Implement MS compatible layout
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 :-/
2016-12-15 17:49:56 +01:00
Michael Matz
78c7096162 Fix struct layout some more
Anonymous sub-sub-members weren't handled correctly.  Bit-fields
neither: this implements PCC layout for now.  It temporarily disables
MS-compatible bit-field layout.
2016-12-15 17:49:56 +01:00
Michael Matz
ddecb0e685 Split off record layouting
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.
2016-12-15 17:49:56 +01:00
Michael Matz
22f5fccc2c Fix 64bit enums and switch cases
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.
2016-12-15 17:49:56 +01:00
Michael Matz
d042e71e9f Fix miscompile with dead switches
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.
2016-12-15 17:49:55 +01:00
Michael Matz
235711f3d3 64bit: Fix addends > 32 bits
If a symbolic reference is offsetted by a constant > 32bit
the backends can't deal with that, so don't construct such
values.
2016-12-15 17:49:55 +01:00
Michael Matz
ddd461dcc8 Fix initializing members multiple times
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.
2016-12-15 17:49:53 +01:00
Michael Matz
f081acbfba Support local register variables
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.
2016-12-15 17:47:13 +01:00
Michael Matz
3bc9c325c5 Fix const folding of 64bit pointer constants
See testcase.
2016-12-15 17:47:12 +01:00
Michael Matz
7ab35c6265 struct-init: Copy relocs for compound literals
When copying the content of compound literals we must
include relocations as well.
2016-12-15 17:47:12 +01:00
Michael Matz
ad8e14b740 opt: Don't emit inline functions from dead code
Inside dead code don't regard inline functions as being
referenced.
2016-12-15 17:47:12 +01:00
Michael Matz
fb933ae0eb opt: constprop also 'cond && 0'
We didn't handle constants in logical expressions when they weren't
the first operand.  Some reordering in the loop structure is enough
to handle them.
2016-12-15 17:47:12 +01:00
Michael Matz
ca435dc2e3 opt: Make break and goto not fallthrough
As we can optimize dead code a bit already it's fitting
to disable code emission after break and goto.
2016-12-15 17:47:12 +01:00
Michael Matz
31c7ea0165 opt: Start optimizing dead code a bit
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.
2016-12-15 17:47:12 +01:00
Michael Matz
b303a00ce0 Revert "Reject jumping inside stmtexprs"
Not fully thought out.  You can't jump inside stmt exprs,
but you can jump out of them.  So there's a difference
between undefined but declared labels at the end of stmt
exprs and those defined inside.  Additionally it should
also be checked if a label defined inside a stmt expr
was tentatively created as declared from outside.

I'm not prepared doing that right now, so simply revert.

This reverts commit 9160e4cab9147d77840cc44a285031fdb4640cf9.
2016-12-15 17:47:11 +01:00
Michael Matz
d4d3144e75 Factor out const condition detection
Creating condition_3way for this.
2016-12-15 17:47:11 +01:00
Michael Matz
892c3d996f Reject jumping inside stmtexprs
One can't jump into statement expressions from outside
them, like the following:

  int i = ({ label: foo(); 42; });
  goto label;

We reject this by making the labels simply not available
outside (GCC has a nicer error message about jumping into
a statement expression).
2016-12-15 17:47:11 +01:00
Michael Matz
1602998751 Fix more nocode_wanted jump problems
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.
2016-12-15 17:47:11 +01:00
Michael Matz
f2a071e808 Fix aliases on 64 bit
Use correct width ELF structure.
2016-12-15 17:47:11 +01:00
Michael Matz
9656560f14 Fix sizeof(char[a])
The sizes of VLAs need to be evaluated even inside sizeof,
i.e. when nocode_wanted is set.
2016-12-15 17:47:11 +01:00
Michael Matz
49bb5a7e06 Fix __builtin_constant_p(1000/x)
was incorrectly treated as constant because the vpop removed
all traces of non-constness.
2016-12-15 17:47:11 +01:00
Michael Matz
372f4b6a4e Fix enum bitfields passed to stdarg functions
VT_ENUM types use the .ref member and can be VT_BITFIELD,
so we need to copy it as well.  Simply do it always.
2016-12-15 17:47:11 +01:00
Michael Matz
d720865fb6 Addresses of non-weak symbols are non-zero
Use this fact in some foldings of comparisons.  See testcase.
2016-12-15 17:47:10 +01:00
Michael Matz
be6d8ffc10 Fix access-after-free with statement expressions
The return value of statement expressions might refer to local
symbols, so those can't be popped.  The old error message always
was just a band-aid, and since disabling it for pointer types it
wasn't effective anyway.  It also never considered that also the
vtop->sym member might have referred to such symbols (see the
testcase with the local static, that used to segfault).

For fixing this (can be seen better with valgrind and SYM_DEBUG)
simply leave local symbols of stmt exprs on the stack.
2016-12-15 17:47:10 +01:00
Michael Matz
34fc6435ee enums and ints are compatible
But like GCC do warn about changes in signedness.  The latter
leads to some changes in gen_assign_cast to not also warn about
  unsigned* = int*
(where GCC warns, but only with extra warnings).
2016-12-15 17:47:10 +01:00
Michael Matz
b1a906b970 enums and ints are compatible 2016-12-15 17:47:10 +01:00
Michael Matz
4e46c22d5c struct-init: Support range inits for local vars
Implement missing support for range init for local variables.
2016-12-15 17:47:09 +01:00
Michael Matz
b7ca74577b struct-init: Allow member initialization from qualified lvalues
See testcase.
2016-12-15 17:47:09 +01:00
Michael Matz
9e86ebee94 struct-init: Correctly parse unnamed member initializers
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.
2016-12-15 17:47:09 +01:00
Michael Matz
21da73c383 struct-init: Cleanup some more
Some parameters aren't actually necessary.  Also join the
two parsing loops for the initializer list of arrays and structs.
2016-12-15 17:47:09 +01:00
Michael Matz
7bf323843e struct-init: Cleanup
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.
2016-12-15 17:47:09 +01:00
Michael Matz
ed7d54651d struct-init: Implement initializing subaggregates
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.
2016-12-15 17:47:09 +01:00
Michael Matz
968bccdd2a struct-init: Reimplement
Start reimplementing the whole initializer handling to be
conforming to ISO C.  This patch just reimplements current
functionality to prepare for further changes, all tests pass.
2016-12-15 17:47:09 +01:00
Michael Matz
5d0c16a884 Support attribute between double pointer stars
"int * __attribute__((something)) *" is supported by GCC.
2016-12-15 17:47:09 +01:00
Michael Matz
662338f116 Fix function to pointer conversion
This snippet is valid:
  void foo(void);
  ... foo + 42 ...
the function designator is converted to pointer to function
implicitely.  gen_op didn't do that and bailed out.
2016-12-15 17:47:08 +01:00
Michael Matz
e034853b38 Fix parsing array typedefs of unknown size
This must compile:
 typedef int arrtype1[];
 arrtype1 sinit19 = {1};
 arrtype1 sinit20 = {2,3};
and generate two arrays of one resp. two elements.  Before the fix
the determined size of the first array was encoded in the type
directly, so sinit20 couldn't be parsed anymore (because arrtype1
was thought to be only one element long).
2016-12-15 17:47:08 +01:00
Michael Matz
8a1a2a6033 Implement __builtin_choose_expr
Follows GCC implementation.
2016-12-15 17:47:08 +01:00
Michael Matz
2b618c1ab4 Fix parsing attributes for struct decls
Given this code:

  struct __attribute__((...)) Name {...};

TCC was eating "Name", hence generating an anonymous struct.
It also didn't apply any packed attributes to the parsed
members.  Both fixed.  The testcase also contains a case
that isn't yet handled by TCC (under a BROKEN #define).
2016-12-15 17:47:08 +01:00
Michael Matz
bbce31552e inline asm: accept concatenated strings in constraints
This really should be handled implicitly in the preprocessor,
but for now this is enough.
2016-12-15 17:47:08 +01:00