aboutsummaryrefslogtreecommitdiff
path: root/tccgen.c
Commit message (Collapse)AuthorAgeFilesLines
* 'long' reviewgrischka2017-09-241-90/+83
| | | | | | | | | | | | | | | | | | | | | add some features for more complete 'long' support tcc.h: - use LONG_SIZE=4/8 instead of TCC_LONG_ARE_64_BIT tccgen.c: - add ptrdiff_type, update size_type - support shift and ?: operations - support long enum types - display 'long' from type_to_str - nwchar_t is unsigned short on windows - unrelated: use memcpy in init_putv for long doubles to avoid random bytes in the image (if tcc was compiled by gcc) for diff purposes. tccpp.c: - make parse_number return correct types - improve multi-character-constants 'XX' 'abcd' Changelog: - update
* Revert "simplify VT_LONG parsing"matthias2017-07-251-3/+3
| | | | | | | | | Too simple long parsion. Take me a long long long time to see my mistake, Sorry (long long long wasn't see as an error) This reverts commit a4cd2805f95e1369254762478883e91050f2cba1.
* simplify VT_LONG parsingMatthias Gatto2017-07-251-3/+3
|
* remove inside_generic hackMatthias Gatto2017-07-241-7/+0
| | | | | define uint64_t and int64_t as 'long' instead of 'long long' when __LP64__ is define.
* tccgen: nodata_wanted fix, default ONE_SOURCE, etc...grischka2017-07-231-4/+11
| | | | | | | | | | | | | | | | | | | | | | | | | tccgen.c: doubles need to be aligned, on ARM. The section_reserve() in init_putv does not do that. -D ONE_SOURCE: is now the default and not longer needed. Also, tcc.h now sets the default native target. These both make compiling tcc simple as "gcc tcc.c -o tcc -ldl" again. arm-asm.c: enable pseudo asm also for inline asm tests/tests2/Makefile: disable bitfield tests except on windows and x86_64 and don't generate-always tcc.c: fix a loop with -dt on errors configure: print compiler version (as recognized) tccpp.c: actually define symbols for tcc -dt clear static variables (needed for -dt or libtcc usage) 96_nodata_wanted.c: use __label__ instead of asm lib/files: use native symbols (__i386__ etc.) instead of TCC_TARGET_...
* mutiples fix for _Genericmatthias2017-07-211-14/+42
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * check that _Generic don't match unsigned char * with char * this case is usefull as with -funsigned-char, 'char *' are unsigned * change VT_LONG so it's now a qualifier VT_LONG are never use for code generation, but only durring parsing state, in _Generic we need to be able to make diference between 'long' and 'long long' So VT_LONG is now use as a type qualifier, it's old behaviour is still here, but we can keep trace of what was a long and what wasn't * add TOK_CLONG and TOK_CULONG tcc was directly converting value like '7171L' into TOK_CLLONG or TOK_CINT depending of the machine architecture. because of that, we was unable to make diference between a long and a long long, which doesn't work with _Generic. So now 7171L is a TOK_CLONG, and we can handle _Generic properly * check that _Generic can make diference between long and long long * uncomment "type match twice" as it should now pass tests on any platforms * add inside_generic global the point of this variable is to use VT_LONG in comparaison only when we are evaluating a _Generic. problem is with my lastest patchs tcc can now make the diference between a 'long long' and a 'long', but in 64 bit stddef.h typedef uint64_t as typedef signed long long int int64_t and stdint.h as unsigned long int, so tcc break when stdint.h and stddef.h are include together. Another solution woud be to modifie include/stddef.h so it define uint64_t as unsigned long int when processor is 64 bit, but this could break some legacy code, so for now, VT_LONG are use only inside generc. * check that _Generic parse first argument correctly * check that _Generic evaluate correctly exresion like "f() / 2"
* tcc -dt -run ... : simpler is bettergrischka2017-07-201-48/+44
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * -dt now with lowercase t * test snippets now separated by real preprocessor statements which is valid C also for other compilers #if defined test_xxx < test snippet x > #elif defined test_yyy < test snippet y > #elif ... #endif * simpler implementation, behaves like -run if no 'test_...' macros are seen, works with -E too * for demonstration I combined some of the small tests for errors and warnings (56..63,74) in "60_errors_and_warnings.c" Also: * libtcc.c: put tcc_preprocess() and tcc_assemble() under the setjmp clause to let them return to caller after errors. This is for -dt -E. * tccgen.c: - get rid of save/restore_parse_state(), macro_ptr is saved by begin_macro anyway, now line_num too. - use expr_eq for parsing _Generic's controlling_type - set nocode_wanted with const_wanted. too, This is to keep VT_JMP on vtop when parsing preprocessor expressions. * tccpp.c: tcc -E: suppress trailing whitespace from lines with comments (that -E removes) such as NO_GOTPLT_ENTRY,\t /* never generate ... */
* fix typo sellector -> selectorMatthias Gatto2017-07-181-1/+1
|
* fix typo: march -> matchmatthias2017-07-181-1/+1
|
* unqualify volatile in _Generic type checkingMatthias Gatto2017-07-181-0/+1
|
* tccgen: nodata_wantedgrischka2017-07-161-34/+61
| | | | | | | | | | | | | | | | | | | | | | | | The existing variable 'nocode_wanted' is now used to control output of static data too. So... (nocode_wanted == 0) code and data (normal within functions) (nocode_wanted < 0) means: no code, but data (global or static data) (nocode_wanted > 0) means: no code and no data (code and data suppressed) (nocode_wanted & 0xC0000000) means: we're in declaration of static data Also: new option '-dT' to be used with -run tcc -dT -run file.c This will look in file.c for certain comment-boundaries: /*-* test-xxx: ...some description */ and then for each test below run it from memory. This way various features and error messages can be tested with one single file. See 96_nodata_wanted.c for an example. Also: tccgen.c: one more bitfield fix
* #pragma comment(option,"-..."), bitfields test, etc...grischka2017-07-141-31/+34
| | | | | | | | | | | | | | | | | | tccpp.c: * #pragma comment(option,"-some-option") to set commandline option from C code. May work only for some options. libtcc.c: * option "-d1..9": sets a 'g_debug' global variable. (for development) tests2/Makefile: * new make targets: tests2.37 / tests2.37+ run single test from tests2, optionally update .expect * new variable GEN-ALWAYS to always generate certain .expects * bitfields test tccgen.c: * bitfields: fix a bug and improve slightly more * _Generic: ignore "type match twice"
* Fix function typesMichael Matz2017-07-141-11/+19
| | | | | various cases of function type uses were broken by recent attribute refactoring, this fixes and adds testcases for them.
* tccasm: Fix local statics referenced from asmsMichael Matz2017-07-101-0/+6
| | | | | | | | | | | 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).
* Fix statement exprs returning a local labelMichael Matz2017-07-101-2/+2
| | | | | | 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).
* enums: Accept GNU extensionMichael Matz2017-07-101-2/+2
| | | | See testcase. Happens e.g. in the linux kernel.
* refactor bitfieldsgrischka2017-07-091-189/+379
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* refactor enumsgrischka2017-07-091-84/+83
| | | | | | 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.
* refactor sym & attributesgrischka2017-07-091-197/+187
| | | | | | | | | | | | 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()
* unsorted adjustmentsgrischka2017-07-091-4/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | - 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 37999a4fbf3487b363fd0c2f9b7ab622401b202a 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
* add C11's _GenericMatthias Gatto2017-07-051-0/+71
| | | | | | | | | | 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.
* Revert "String literals are always const"Michael Matz2017-07-041-3/+3
| | | | | | | | | | | This reverts commit d4fe9aba3fc6f4b9cc97b100e86ffe7af5c29619. 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.
* Extend skip_or_save_blockMichael Matz2017-07-031-1/+1
| | | | | Make it stop also before outer level closing parens. This way we can now also skip/save the expression inside "foobar(42 + 41)".
* Improve skip_or_save_blockMichael Matz2017-07-031-7/+7
| | | | | Stop at level 0 only for matching outer '}' (which is added). Otherwise stop only at stop tokens (which aren't added).
* String literals are always constMichael Matz2017-07-031-3/+3
| | | | | | 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.
* Limit access end-of-struct warning a bitMichael Matz2017-05-271-1/+1
| | | | | | | 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.
* configure: --config-musl/-uClibc switch & misc cleanupsgrischka2017-05-131-27/+33
| | | | | | | | | | | | | | | - 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" 7443db0d5f841b81a55e918bf8c228dd20f9ddb2 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
* 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).