I use tcc version 0.9.28rc 2025-10-07 mob@ce8b343 (x86_64 Linux) and have
noticed the following behavior when I try to use
`__attribute__((cleanup(<func_name>)))` in any variable I need to use it.
Here's the sample code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define xstr(s) #s
#define str(s) xstr(s)
#define scope(F) __attribute__ ((cleanup(F)))
void reclaimmem(void *ptr_ptr)
{
void *ptr = * (void **) ptr_ptr;
if (!ptr) return;
printf("%15s: '%s' %p\n", __func__, (char*) ptr, ptr);
free(ptr);
ptr = NULL;
}
int main(void)
{
scope(reclaimmem) char *s1 = strdup("foo");
if (s1) printf("%15s: '%s' %p\n", str(s1), s1, s1);
scope(reclaimmem) char *s2 = strdup("bar");
if (s2) printf("%15s: '%s' %p\n", str(s2), s2, s2);
return 0;
}
When I run `tcc -E tmp.c`, I get
void reclaimmem(void *ptr_ptr)
{
void *ptr = * (void **) ptr_ptr;
if (!ptr) return;
printf("%15s: '%s' %p\n", __func__, (char*) ptr, ptr);
free(ptr);
ptr = ((void*)0);
}
int main(void)
{
char *s1 = strdup("foo");
if (s1) printf("%15s: '%s' %p\n", "s1", s1, s1);
char *s2 = strdup("bar");
if (s2) printf("%15s: '%s' %p\n", "s2", s2, s2);
return 0;
}
as my preprocessing output (I intentionally left out unnecessary parsed
headers' code).
If I try the same command with either `gcc -E tmp.c` or `clang -E tmp.c`, I get
the following output:
# 10 "tmp.c"
void reclaimmem(void *ptr_ptr)
{
void *ptr = * (void **) ptr_ptr;
if (!ptr) return;
printf("%15s: '%s' %p\n", __func__, (char*) ptr, ptr);
free(ptr);
ptr =
# 17 "tmp.c" 3 4
((void *)0)
# 17 "tmp.c"
;
}
int main(void)
{
__attribute__ ((cleanup(reclaimmem))) char *s1 = strdup("foo");
if (s1) printf("%15s: '%s' %p\n", "s1", s1, s1);
__attribute__ ((cleanup(reclaimmem))) char *s2 = strdup("bar");
if (s2) printf("%15s: '%s' %p\n", "s2", s2, s2);
return 0;
}
The crazy thing is that TCC *supports* this attribute, because we can find it
in tests/tests2/101.cleanup.c, *AND* can get preprocessed just fine!
Here's a small portion of it:
# 31 "101_cleanup.c"
void check2(char **hum);
void check(int *j)
{
char * __attribute__ ((cleanup(check2))) stop_that = "wololo";
int chk = 0;
{
char * __attribute__ ((cleanup(check2))) stop_that = "plop";
{
non_plopage:
printf("---- %d\n", chk);
}
if (!chk) {
chk = 1;
goto non_plopage;
}
}
{
char * __attribute__ ((cleanup(check2))) stop_that = "tata !";
goto out;
stop_that = "titi";
}
again:
chk = 2;
{
char * __attribute__ ((cleanup(check2))) cascade1 = "1";
{
char * __attribute__ ((cleanup(check2))) cascade2 = "2";
{
char * __attribute__ ((cleanup(check2))) cascade3 = "3";
goto out;
cascade3 = "nope";
}
So, clearly something is wrong here...
Any advice?
P.S.: Can we please transfer all tickets from
https://savannah.nongnu.org/bugs/?group=tinycc to
https://github.com/TinyCC/tinycc/ and retain the official repo at
http://repo.or.cz/w/tinycc.git ?
It's so hard to report bugs or search for existing solutions that are scattered
all over the internet.
_______________________________________________
Tinycc-devel mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/tinycc-devel