Commit Graph

101 Commits

Author SHA1 Message Date
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
d0d25ec7df tccpp: Allow computed include like 42.h
The include directive needs to be parsed as pp-tokens, not
as token (i.e. no conversion to TOK_STR or TOK_NUM).  Also fix
parsing computed includes using quoted strings.
2016-12-15 17:47:10 +01:00
Michael Matz
0381387640 x86-asm: Correctly infer register size for bools
Register operands of type _Bool weren't correctly getting
the 8-bit sized registers (but rather used the default 32-bit
ones).
2016-12-15 17:47:10 +01:00
Michael Matz
ca8c1cd643 x86-64: Allow loads from some structs/unions
GCC allows register loads for asms based on type mode,
and correctly sized structs/union have an allowed mode
(basically 1,2,4,8 sized aggregates).
2016-12-15 17:47:10 +01:00
Michael Matz
9ae10cad1f tccasm: Lookup C symbols from ASM blocks
It's now possible to use symbols defined in C code to be used
from later inline asm blocks.  See testcase.
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
8765826465 inline-asm: Accept "flags" clobber 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
b7e0b693a6 tccpp: Implement __BASE_FILE__ macro
Like __FILE__ but always refers to the command line file name also
from inside headers.
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
Michael Matz
10c3514889 Accept symbols in initializers also on 64 bit
Those should use long or long long type, and generate a 64bit reloc.
2016-12-15 17:47:07 +01:00
Michael Matz
253afeed1e inline asm: Accept 'p' constraint and 'P' template mod
'p' is conservatively the same as 'r' and 'P' as template
modifier can be ignored in TCC.
2016-12-15 17:47:07 +01:00
Michael Matz
6763b02abc Accept empty struct member decls
struct S { /*nothing*/; int a; };

is an acceptable struct declaration, there may be stray semicolons
in the member list.
2016-12-15 17:47:06 +01:00
Michael Matz
d5d881d9e9 x86-asm: Accept 'q' modifier
In inline extended asm '%q1' refers to the 64bit register of operand 1.
2016-12-15 17:47:06 +01:00
grischka
2b7ee000cd tests: add .so/.dll creation test
Also remove bitfield test from tcctest.c because gcc
versions don't agree among each other.
2016-12-15 17:04:07 +01:00
David Mertens
d2e2f42382 Implement gcc bitfield algorithm; add -mms-bitfields 2016-11-28 09:01:12 -05:00
grischka
4a3741bf02 x86_64-asm: =m operand fixes
The problem was with tcctest.c:

    unsigned set;
    __asm__("btsl %1,%0" : "=m"(set) : "Ir"(20) : "cc");

when with tcc compiled with the HAVE_SELINUX option, run with
tcc -run, it would use large addresses far beyond the 32bits
range when tcc did not use the pc-relative mode for accessing
'set' in global data memory.  In fact the assembler did not
know about %rip at all.

Changes:
- memory operands use (%rax) not (%eax)
- conversion from VT_LLOCAL: use type VT_PTR
- support 'k' modifier
- support %rip register
- support X(%rip) pc-relative addresses

The test in tcctest.c is from Michael Matz.
2016-11-20 14:50:56 +01:00
grischka
71b16f4e18 tccpp : "tcc -E -P" : suppress empty lines
Also:
- regenerate all tests/pp/*.expect with gcc
- test "insert one space" feature
- test "0x1E-1" in asm mode case
- PARSE_FLAG_SPACES: ignore \f\v\r better
- tcc.h: move some things
2016-10-09 20:33:14 +02:00
grischka
b691585785 tccgen: arm/i386: save_reg_upstack
tccgen.c:gv() when loading long long from lvalue, before
was saving all registers which caused problems in the arm
function call register parameter preparation, as with

    void foo(long long y, int x);
    int main(void)
    {
      unsigned int *xx[1], x;
      unsigned long long *yy[1], y;
      foo(**yy, **xx);
      return 0;
    }

Now only the modified register is saved if necessary,
as in this case where it is used to store the result
of the post-inc:

        long long *p, v, **pp;
        v = 1;
        p = &v;
        p[0]++;
        printf("another long long spill test : %lld\n", *p);

i386-gen.c :
- found a similar problem with TOK_UMULL caused by the
  vstack juggle in tccgen:gen_opl()
  (bug seen only when using EBX as 4th register)
2016-10-04 17:36:51 +02:00
Pavlas, Zdenek
da63695cf3 switch: fix label sorting 2016-10-03 00:43:28 -07:00
Balazs Kezes
49d3118621 Incorrect function call code on ARMv6
On 2016-08-11 09:24 +0100, Balazs Kezes wrote:
> I think it's just that that copy_params() never restores the spilled
> registers. Maybe it needs some extra code at the end to see if any
> parameters have been spilled to stack and then restore them?

I've spent some time on this and I've found an alternative solution.
Although I'm not entirely sure about it but I've attached a patch
nevertheless.

And while poking at that I've found another problem affecting the
unsigned long long division on arm and I've attached a patch for that
too.

More details in the patches themselves. Please review and consider them
for merging! Thank you!

--
Balazs

[PATCH 1/2] Fix slow unsigned long long division on ARM

The macro AEABI_UXDIVMOD expands to this bit:

  #define AEABI_UXDIVMOD(name,type, rettype, typemacro)                     \
  ...
      while (num >= den) {                                                  \
  ...
          while ((q << 1) * den <= num && q * den <= typemacro ## _MAX / 2) \
              q <<= 1;                                                      \
  ...

With the current ULONG_MAX version the inner loop goes only until 4
billion so the outer loop will progress very slowly if num is large.
With ULLONG_MAX the inner loop works as expected. The current version is
probably a result of a typo.

The following bash snippet demonstrates the bug:

  $ uname -a
  Linux eper 4.4.16-2-ARCH #1 Wed Aug 10 20:03:13 MDT 2016 armv6l GNU/Linux
  $ cat div.c
  int printf(const char *, ...);
  int main(void) {
    unsigned long long num, denom;
    num = 12345678901234567ULL;
    denom = 7;
    printf("%lld\n", num / denom);
    return 0;
  }
  $ time tcc -run div.c
  1763668414462081

  real    0m16.291s
  user    0m15.860s
  sys     0m0.020s

[PATCH 2/2] Fix long long dereference during argument passing on ARMv6

For some reason the code spills the register to the stack. copy_params
in arm-gen.c doesn't expect this so bad code is generated. It's not
entirely clear why the saving part is necessary. It was added in commit
59c35638 with the comment "fixed long long code gen bug" with no further
clarification. Given that tcctest.c passes without this, maybe it's no
longer needed? Let's remove it.

Also add a new testcase just for this. After I've managed to make the
tests compile on a raspberry pi, I get the following diff without this
patch:

  --- test.ref    2016-08-22 22:12:43.380000000 +0100
  +++ test.out3   2016-08-22 22:12:49.990000000 +0100
  @@ -499,7 +499,7 @@
   2
   1 0 1 0
   4886718345
  -shift: 9 9 9312
  +shift: 291 291 291
   shiftc: 36 36 2328
   shiftc: 0 0 9998683865088
   manyarg_test:

More discussion on this thread:
https://lists.nongnu.org/archive/html/tinycc-devel/2016-08/msg00004.html
2016-10-01 23:10:11 +02:00
grischka
41349948f8 win64: fix va_arg
fixes 5c35ba66c5

Implementation was consistent within tcc but incompatible
with the ABI (for example library functions vprintf etc)

Also:
- tccpp.c/get_tok_str() : avoid "unknown format "%llu" warning
- x86_64_gen.c/gen_vla_alloc() : fix vstack leak
2016-07-10 20:44:49 +02:00
Michael Matz
f0fa5603cf x86-64: Run asmtest as well
This fixes and activates the asm test that's part of tcctest.c
also on x86-64, requiring a small fix for the 'm' constraint.
2016-05-11 19:00:02 +02:00
grischka
d48662d496 tccgen: scopes levels for local symbols (update 1)
Catch top level redeclarations too.

Also fix mistakes in tcctest.c and the tcc sources (win32)
showing up now.
2016-05-05 20:04:00 +02:00
Michael Matz
80343ab7d8 Fix assignment to/from volatile types
Code like this was broken:

   char volatile vi = i;

See testcase, happens in ideosyncratic legacy code sprinkling
volatile all over.
2016-03-26 17:57:22 +01:00
Michael Matz
8fc5a6a2a4 Fix tokenization of TOK_DOTS
We really need to use PEEKC during tokenization so as to
skip line continuations automatically.
2016-03-24 15:58:32 +01:00
Edmund Grimley Evans
9bf0e57509 tests/tcctest.c: Fix up format strings. 2015-11-04 20:20:26 +00:00
gus knight
89ad24e7d6 Revert all of my changes to directories & codingstyle. 2015-07-29 16:57:12 -04:00
gus knight
41031221c8 Trim trailing spaces everywhere. 2015-07-27 12:43:40 -04:00
grischka
30df3189b1 tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
  didn't work well)

Based partially on ideas / researches from PipCet

Some issues remain with VA_ARGS macros (if used in a
rather tricky way).

Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=')  GCC does that, other compilers don't.

 * cleanups
  - #line 01 "file" / # 01 "file" processing
  - #pragma comment(lib,"foo")
  - tcc -E: forward some pragmas to output (pack, comment(lib))
  - fix macro parameter list parsing mess from
    a3fc543459
    a715d7143d
    (some coffee might help, next time ;)
  - introduce TOK_PPSTR - to have character constants as
    written in the file (similar to TOK_PPNUM)
  - allow '\' appear in macros
  - new functions begin/end_macro to:
      - fix switching macro levels during expansion
      - allow unget_tok to unget more than one tok
  - slight speedup by using bitflags in isidnum_table

Also:
  - x86_64.c : fix decl after statements
  - i386-gen,c : fix a vstack leak with VLA on windows
  - configure/Makefile : build on windows (MSYS) was broken
  - tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 14:29:39 +02:00
seyko
43e4a406b4 Disable floating-point test for ARM soft-float
From: Matteo Cypriani <mcy@lm7.fr>
    Date: Fri, 5 Sep 2014 23:22:56 -0400
    Subject: Disable floating-point test for ARM soft-float

    tcc is not yet capable of doing softfloat floating-point operations on
    ARM, therefore we disable this test for these platforms. Note that tcc
    displays a warning to warn ARM users about this limitation
    (debian)
2015-03-03 17:28:13 +03:00
Edmund Grimley Evans
97e08be344 tests/tcctest.c: Test COMPAT_TYPE(char *, signed char *). 2015-02-24 19:35:31 +00:00
Vincent Lefevre
3e9a7e9d69 Corrected spelling mistakes in comments and strings 2014-04-07 13:31:00 +02:00
Michael Matz
c4427747e6 arm: Provide alloca()
This provides a simple implementation of alloca for ARM (and enables
the associated testcase).  As tcc for ARM doesn't contain an assembler,
we'll have to resort using gcc for compiling it.
2014-04-05 22:54:11 +02:00
Thomas Preud'homme
02d2ca8ac7 Fix and extend *FCAST test in tcctest.c
Result of float to unsigned integer conversion is undefined if float is
negative. This commit take the absolute value of the float before doing
the conversion to unsigned integer and add more float to integer
conversion test.
2014-02-05 15:26:46 +08:00
Thomas Preud'homme
1415d7e6b6 Don't perform builtin_frame_address on ARM 2014-02-03 12:28:25 +08:00
Thomas Preud'homme
c88c2706a2 Test long long to float conversions 2014-02-01 15:31:28 +08:00
Michael Matz
f42a02efda tcctest: One more signed zero test
This also checks that -(-0.0) is +0.0.
2014-01-12 04:53:29 +01:00
Michael Matz
05c9b76131 Fix floating point unary minus and plus
negate(x) is subtract(-0,x), not subtract(+0,x), which makes
a difference with signed zeros.  Also +x was expressed as x+0,
in order for the integer promotions to happen, but also mangles signed
zeros, so just don't do that with floating types.
2014-01-12 04:44:27 +01:00
Thomas Preud'homme
f2dbcf7594 Add ARM aeabi functions needed to run tcctest
Add implementation for float / integer conversion functions:
  __aeabi_d2lz, __aeabi_d2ulz, __aeabi_f2lz, __aeabi_f2ulz, __aeabi_l2d,
  __aeabi_l2f, __aeabi_ul2d, __aeabi_ul2f

Add implementation for long long helper functions:
  __aeabi_ldivmod, __aeabi_uldivmod, __aeabi_llsl, __aeabi_llsr, __aeabi_lasr

Add implementation for integer division functions:
  __aeabi_uidiv, __aeabi_uidivmod, __aeabi_idiv, __aeabi_idivmod,
2013-12-11 10:15:30 +08:00
James Lyon
41d76e1fcb Fixed silly error in Windows build of tests (abitest-cc not linking to libtcc)
I really should do this when less tired; I keep breaking one platform
while fixing another. I've also fixed some Windows issues with tcctest
since Windows printf() uses different format flags to those on Linux,
and removed some conditional compilation tests in tcctest since they
now should work.
2013-04-26 01:27:04 +01:00
James Lyon
e31579b076 Fixed tests on Windows (including out-of-tree problems)
Modified tcctest.c so that it uses 'double' in place of 'long double'
with MinGW since this is what TCC does, and what Visual C++ does. Added
an option -norunsrc to tcc to allow argv[0] to be set independently of
the compiled source when using tcc -run, which allows tests that rely on
the value of argv[0] to work in out-of-tree builds.

Also added Makefile rules to automatically update out-of-tree build
Makefiles when in-tree Makefiles have changed.
2013-04-17 20:32:07 +01:00
grischka
d5f4df09ff tests: cleanup
tests:
- add "hello" to test first basic compilation to file/memory
- add "more" test (tests2 suite)
- remove some tests

tests2:
- move into tests dir
- Convert some files from DOS to unix LF
- remove 2>&1 redirection

win32:
- tccrun.c: modify exception filter to exit correctly (needed for btest)
- tcctest.c: exclude weak_test() (feature does not exist on win32)
2013-02-05 14:27:38 +01:00
Thomas Preud'homme
f3e5649150 Don't do builtin_frame_address test with ARM gcc
gcc fails the builtin_frame_address test on ARM so we disable it. As a
consequence, the diff between gcc and tcc's output is unecessarily
bigger. Given the big size of the diff currently, this doesn't make a
big difference but may allow to detect a regression in tcc's
implementation of builtin_frame_address.
2013-01-26 20:31:14 +01:00
Thomas Preud'homme
e92dbe4686 Stop returning 0 in cmp_comparison_test
cmp_comparison_test has no return value and should thus not return 0.
2013-01-06 12:26:53 +01:00