aboutsummaryrefslogtreecommitdiff
path: root/tccgen.c
Commit message (Collapse)AuthorAgeFilesLines
* bitfields: promote to signed intgrischka2017-05-091-9/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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);
* bitfields: one more hack and a "-Wgcc-compat" switchgrischka2017-05-091-6/+19
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* bitfields: fix long bitfieldsMichael Matz2017-05-081-3/+3
| | | | now the testcase works on i386-linux as well.
* Spelling fixes in C comments onlyLarry Doolittle2017-05-071-6/+6
|
* more minor fixesgrischka2017-05-071-4/+11
| | | | | | | | | | | | | | | | | | | | | | | | | * 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 a8b83ce43a95fa519dacfe7690a3a0098af7909c * 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
* Accept extern initialized file-scope variablesMichael Matz2017-05-071-1/+2
| | | | | | '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.
* struct-init: Fix zero initialization with multi-level designatorsMichael Matz2017-05-061-67/+59
| | | | | | | 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.
* Fix unsigned enum bit-fieldsMichael Matz2017-05-051-1/+3
| | | | | | 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.
* Fix segfault with invalid function defMichael Matz2017-05-051-1/+1
| | | | | | | 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.
* Tidy decl_designatorMichael Matz2017-05-021-26/+15
| | | | | Removing the need for the notfirst local variable, and tidy loop structure and error messaging a bit.
* Remove label_or_declMichael Matz2017-05-021-21/+5
| | | | | 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).
* Cleanups (float consts, sections, symbols)Michael Matz2017-05-021-65/+19
| | | | | | | | 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).
* Merge func_decl_list into decl0Michael Matz2017-05-021-67/+38
| | | | | Removes some code duplication and also implements one feature: checking for duplicate decls for old style parameters.
* Tidy decl_designatorMichael Matz2017-05-021-9/+2
| | | | The fixme therein is long solved.
* Tidy unary() a bitMichael Matz2017-05-021-27/+18
| | | | | | 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.
* Factor some codeMichael Matz2017-05-021-63/+47
| | | | | Three places that skip (and store) tokens in some fashion can be factored a bit.
* Extend type_to_strMichael Matz2017-05-021-1/+11
| | | | to also print storage-class specifiers.
* Reorganize type parsingMichael Matz2017-05-021-64/+57
| | | | | Various corner cases for declarator parsing were incorrect. This reorganizes and fixes it, and somewhat simplifies it as well.
* Tidy typename parsing a bitMichael Matz2017-05-021-26/+16
|
* Tidy arg parsing for builtinsMichael Matz2017-05-021-76/+52
| | | | Saves some lines of code.
* Remove VT_REFMichael Matz2017-05-021-10/+2
| | | | | | 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.
* Fix bogus check for VT_LLOCAL typesMichael Matz2017-05-021-4/+8
| | | | | | 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.
* fix __builtin_expectMichael Matz2017-05-021-25/+2
| | | | | | | | 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).
* Fix more bitfield corner casesMichael Matz2017-05-011-0/+3
| | | | | | | 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.
* Fix last changeMichael Matz2017-05-011-1/+1
| | | | | Skipping anonymous bit-fields is correct, but not other anonymous ones like unions or structs.
* Remove a bit-field TODOMichael Matz2017-04-291-0/+2
| | | | | | 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.
* Fix char bitfields corner caseMichael Matz2017-04-291-1/+1
| | | | See testcase.
* final adjustments for releasegrischka2017-04-251-9/+0
| | | | | | | | | | | | | | | | | | | | | - 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
* tccgen/win32: let __declspec(dllimport) imply externgrischka2017-04-041-134/+127
| | | | | | | | | | | | | | | | | | | | | | | 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
* tcc: re-enable correct option -r supportgrischka2017-02-201-53/+86
| | | | | | | | | | | | | | | 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
* fixes & cleanupsgrischka2017-02-131-41/+23
| | | | | | | | | | | | | | | | | | | | | | | | | | | | - 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 76cb1144ef91924c53c57ea71e6f67ce73ce1cc6 - 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 ...
* tccgen: yet another nocode_wanted fixgrischka2017-02-121-4/+2
| | | | | | | | | | | 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;
* tccgen: factor out gfunc_returngrischka2017-02-081-182/+172
| | | | | | | 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
* tccgen: gen_cast: cast FLOAT to DOUBLEgrischka2017-02-051-0/+9
| | | | | ... to avoid precision loss when casting to int, also when saving FLOATs to stack
* Fix some code suppression falloutMichael Matz2016-12-201-3/+16
| | | | | | | | | | 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.
* i386-gen: fix USE_EBXgrischka2016-12-191-1/+1
| | | | | | | | | | | | | 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
* tests: add memory leak testgrischka2016-12-181-8/+5
| | | | | | | | | | | | | 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: nocode_wanted++/--grischka2016-12-181-51/+37
| | | | | uses 'nocode_wanted' as a level couter instead of 'saved_nocode_wanted' everywhere.
* tccgen: fix expr_cond for alt. nocode_wantedgrischka2016-12-181-70/+74
| | | | | making shure that both the active and the passive branches do exacly the same thing.
* tccgen: nocode_wanted alternativelygrischka2016-12-181-92/+52
| | | | | | | | | | | | | | | 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.
* arm64: Fix a case of dead code suppressionMichael Matz2016-12-151-4/+6
| | | | 82_nocode_wanted.c:kb_wait_2_1 was miscompiled on arm64.
* struct-layout: Allow lowering of member alignmentMichael Matz2016-12-151-2/+1
| | | | | | 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.
* Support large alignment requestsMichael Matz2016-12-151-6/+30
| | | | | | | | 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.
* struct-layout: cleanup code a bitMichael Matz2016-12-151-94/+56
|
* bitfields: Fix MS layout some moreMichael Matz2016-12-151-4/+9
| | | | | | | | | | | | | | | | 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.
* bitfields: fix PCC layoutMichael Matz2016-12-151-23/+28
| | | | | Fixes some corner cases in PCC layout. Testcases coming up.
* bitfields: Implement MS compatible layoutMichael Matz2016-12-151-7/+30
| | | | | | | | 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 :-/
* Fix struct layout some moreMichael Matz2016-12-151-40/+113
| | | | | | 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.
* Split off record layoutingMichael Matz2016-12-151-78/+114
| | | | | | | | | | | 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.
* Fix 64bit enums and switch casesMichael Matz2016-12-151-38/+76
| | | | | | | 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.