Example:
int a = 1;
void f(void)
{
int a = 2;
{
extern int a; // = 1 !!
....
To get this (more) correctly there is a new function to copy
syms between local to global stacks.
Also, this patch changes the meaning of VT_EXTERN back
to the simpler and IMO more useful notion of
DECLARED but not (yet) DEFINED.
and that for both variables and functions. That is, VT_EXTERN
in tcc doesn't have to do with the keyword 'extern' necessarily.
Also this patch does allow
int x[];
as alias for
extern int x[];
(as do gcc and msvc)
new glibc really can't avoid it anymore, so let's provide it.
I've tried doing it only on systems that possibly are glibc
based. (For others it would be harmless as it simply wouldn't
be picked up from libtcc1.a)
... which IMO are:
1) files don't need a _test suffix because all files in
the directory are tests ;)
2) we test the BEHAVIOR of the program, rather than its
binary bit contents.
Ok, but nobody said a test can't use two files ;)
(where the 104+_ construct is meant to prevent the file
from being picked up by the makefile as a test on its own).
Previously test 104 used a combination of *nix tools and system() calls
to emulate a `sh` script, which required split code paths for windows
due to different shell and different absolute path representation.
Also, it used a hardcoded tcc binary path, didn't set locale for sort.
Now the tools are used from a `sh` script which the program generates
and invokes, tmp files are at CWD and no conversion is required, tcc
path is taken from Makefile (exported), and `sort` uses LC_ALL=C.
my last inline changes caused parameter names to be overwritten
always (as VT_EXTERN now doesn't mark the current def anymore),
leading to a compile error when including windows.h. Rework this.
Also silence a warning that currently happens for mingw, which is
written with gnu-inline behaviour in mind. Our work-arounds
of using "static inline" actually create invalid C (which we warn
about). Until we implement this properly, just silence the warning.
there's no need for two new flags in type.t . We just can't use
VT_EXTERN as marker if functions are defined or not (like we can
for objects), and then can simply implement the rules of C99/C11
by not overwriting VT_STATIC/VT_EXTERN at all but rather only
look at them. A function already on the inline list can be
forced by removing the VT_INLINE flag, and then linkage
follows from some combination of VT_STATIC, VT_EXTERN and VT_INLINE.
build_got might realloc the symbol table (for the _GLOBAL_OFFSET_TABLE_
symbol), so we can't reuse sym (a pointer into it) after build_got.
Using it isn't necessary, as we pass the sym_index to put_got_entry,
and that recomputes sym.
By always instantiating extern inlines, the patch has discovered
2 assembly errors, which were fixed in the original mingw64 in 2009.
This fixes those errors.
Additionally it changes __CRT_INLINE in win32/include/_mingw.h
from `extern __inline__` to `static __inline__`.
__CRT_INLINE is used exclusively in header files and as such
it should not create externally visible instantiations like a `extern
inline` would (as per the C standard).
- add tests for standard conformant inline functions
- implement it
The old tinycc failed to provide a conforming implementation
of non-static inlines. It would expose external symbols where it
shouldn't and hide them where it should expose them.
This commit provides a hopefully comprehensive test suite
for how things should be done. The .expect file can be obtained
by compiling the example c file (embedded in the test)
with a conforming compiler such as gcc, clang or icc and then
printing the exported symbols (e.g., with nm+awk+sort).
(The implementation currently reserves two new VT_ flags.
If anyone can provide an implementation without reserving
two extra flags, please replace mine.)
The macro conflicts (=> redef warnings in a simple hello world)
with a definition introduced by glibc headers and
it's probably not "necessary" anyway since clang doesn't use it.
GCC wouldn't be able to implement this either (due to the separate
phases of compilation and assembly). We could allow it but it
makes not much sense and actively can confuse broken code into
segfaulting TCC. At least we can warn.
Warning exposes a problem in tcctest, and fixing that gives us
an opportunity to also test .pushsection/.popsection and .previous
directive support.
the real difference is in decl0 where we can use external_sym
just fine also for function definitions, we don't have to use
external_global_sym. Setting VT_EXTERN in external_sym isn't
necessary either (the type will have it set if necessary).
The rest is tidying: removing unused arguments and moving
some code around.
we can register a top-level exception filter which does
nothing else than call into _XcptFilter (provided by
the default C runtime environment) and signal handlers
for the few POSIX signals that Windows can handle start
working (that includes e.g. SEGV).
anonymous struct members were somewhat broken as the testcase
demonstrates. The reason is the jumping through hoops to fiddle
with the offsets I once introduced to avoid having to track
a cumulative offset. That's now not necessary anymore and actively
harmful, doing the obvious thing is now better.
see testcase, when the inner array dimension of multi-dimensional
VLAs isn't given TCC was generating invalid vstack accesses.
Those are actually invalid, so just diagnose them.
this test is run only on i386 so its failing went unnoticed for
a while, since 1fd3709379. IS_ASM_SYMs should not be tested
for conflicting types, the C typing overrides.
_Noreturn, just like __attribute__((noreturn)), is ignored.
I also added stdnoreturn.h, in all its glorious uselessness.
_Alignas only works for integer expressions right now. In order
to comply, we need:
- _Alignas(type) -> _Alignas(_Alignof(type)).
- stdalign.h as soon as it is done.
Note: DR 444 is supported; it works on struct members.
Signed-off-by: Devin Hussey <husseydevin@gmail.com>