old implementation use only a global static array for storing
ScopeTracker which have the advantage to be fast, but you can't
use cleanup in a function that have move than SCOPE_TCK_STORE_SIZE
scopes.
I don't want to use only dynarray_* as it would slow down tcc for
every functions, so I keep both stores.
The major difficulty was to handle cleanup when a goto happen
to do so, I've had a "ScopeTracker" struct.
I can't use local_scope because that would not work with code like below
as local_scope would be at the same level:
{
char * __attribute__ ((cleanup(clean_function))) str = "hej";
goto next;
}
{
next:
}
read() is allowed to short-read, and return less bytes then requested.
The caller must restart read() when this happens (and they want more
bytes).
This patch is still buggy, because errors are not always checked.
Still, less buggy than before.
symbols are local when defined and referred to from the executable.
Also, we need to relocate the .got section when this is a static link
(our static linking effectively generates code as if this were a dynamic
link with PLT and GOT, and then emulates the runtime loader).
Support multiple __label__ declarations at the beginning of a block
as long as they're contiguous.
gcc and clang accept:
{ __label__ a,b; __label__ c; /*...*/ }
.
Tcc would fail it. This patch makes it accept it.
The patch:
- if (tok == TOK_LABEL) {
+ while (tok == TOK_LABEL) {
In gfunc_call, regisger will be saved before gcall_or_jmp. The register
stored the function will be saved too, though in some generator the SValue
of this function will be immediately poped after gcall_or_jmp, and no need to be saved. So I modify some generator to avoid save redundant SValue before gcall_or_jmp.
Before this patch, save_reg can't reuse the temporary local variable
created before to save register. It may consume a lot of stack memory. this patch make save_reg reuse the temporary local variable.
when parsing the type in this cast:
(int (__attribute__(X) *)(int))foo
we ignored the attribute, which matters if it's e.g. a 'stdcall'
attribute on the function pointer. Only this particular placement
was misparsed. Putting the attribute after the '*' or outside the inner
parens worked. This idiom seems to be used on SQLite, perhaps this
fixes a compilation problem on win32 with that.
like qualifier merging the array sizes are merged as well
for the operands of ?:, and they must not statically influence
the types of decls.
Also fix some style problems, spaces aren't stinky :)
char **argv;
_Generic(argv, char**: (void)0);
_Generic(0?(char const*)0:argv[0], char const*: (void)0);
_Generic(argv, char**: (void)0);
would fail because the type of argv would get modified by the
ternary. Now allocate a separate type on the value stack to
prevent this error.
tcc would reject e.g.,
void f(){ struct {_Bool x:_Generic(({0;}),default:1);} my_x; }
with `expected constant`. This patch makes it accept it.
(The patch also makes tcc's _Generic a little more "generic" than that
of gcc and clang in that that tcc now also accepts
`struct {_Bool x:_Generic(({0;}),default:1);} my_x;` in file scope
while gcc and clang don't, but I think there's no harm in that
and gcc and clang might as well accept it in filescope too, given
that they have no problem with
e.g., `/*filescope:*/int x=1, y=2, z=_Generic(x+y, int:3);`)
The type within the cast (int (__attribute__((foo)) *)(void))
was misparsed because of the presence of the attribute (parse_btype
prematurely concluded that (__attribute__() *) is a type.
Also see testcase. This construct is used in sqlite it seems.
Prevent any decoration that would otherwise affect an exported
PE function. For example, given the following:
__declspec(dllexport) __stdcall
int decorated(int arg) {
return 0;
}
__declspec(dllexport) __stdcall __attribute__((nodecorate))
int undecorated(int arg) {
return 0;
}
The following exported functions can now be seen in the DLL:
_decorated@4
undecorated
The attribute is recognised for all targets but only
affects PE codegen. I'm not sure whether this would be
useful for other targets; its intended use was to allow
the creation of a DLL matching an existing set of signatures.
linkers don't treat relocations using symindex 0 (undefined)
very well, it can't be misused as indicator for an absolute number.
Just don't bother with special casing this, rather emit an indirect
call/jump right away. ARM64 needs the same (and didn't handle
calls via constant absolute func pointers before).
The testcase as is doesn't fail without the patch, it actually
needs separate compilation (to -fPIC .o file, then to shared lib)
to fail.
the lvalue Syms for arguments didn't correctly reflect
their own types in all cases (a side-effect of the type being
stored in type->t and the ->r members (as VT_LVAL_xxx), so the below
used an int load (not a byte load) in the conditional.
extern void bar (void);
void foo (signed char c)
{
signed char x = c;
if (c)
bar();
}