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

Reply via email to