https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119251

            Bug ID: 119251
           Summary: New diagnostic: -Wcompound-literal-address
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: alx at kernel dot org
  Target Milestone: ---

Taking the address of a compound literal is dangerous, as their lifetime is
scoped to a block.

It would be good to have a diagnostic when one takes the address of one,
because chances are high that the address will leak the block, and result in
UB.

alx@devuan:~/tmp$ cat cl.c | grep -Tn ^
                  1:    #include <stdlib.h>
                  2:    #include <string.h>
                  3:
                  4:    int *
                  5:    f(void)
                  6:    {
                  7:            int  *p;
                  8:
                  9:            // Correctly diagnosed.
                 10:            p = memcpy(malloc(sizeof(int) * 3),
                 11:                    ({ (int [3]){1, 2, 3}; }),
                 12:                    sizeof(int) * 3);
                 13:
                 14:            // Correctly diagnosed (probably only because
the compiler knows memset(3).
                 15:            p = ({ memset((int [3]){}, 0, sizeof(int) * 3);
});
                 16:
                 17:            // It might be interesting to be able to
diagnose this?
                 18:            p = memset((int [3]){}, 0, sizeof(int) * 3);
                 19:
                 20:            return p;
                 21:    }
alx@devuan:~/tmp$ gcc -Wall -Wextra -S cl.c 
cl.c: In function ‘f’:
cl.c:10:13: warning: using a dangling pointer to an unnamed temporary
[-Wdangling-pointer=]
   10 |         p = memcpy(malloc(sizeof(int) * 3),
      |             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   11 |                 ({ (int [3]){1, 2, 3}; }),
      |                 ~~~~~~~~~~~~~~~~~~~~~~~~~~
   12 |                 sizeof(int) * 3);
      |                 ~~~~~~~~~~~~~~~~
cl.c:11:29: note: unnamed temporary defined here
   11 |                 ({ (int [3]){1, 2, 3}; }),
      |                             ^
cl.c:15:11: warning: using a dangling pointer to an unnamed temporary
[-Wdangling-pointer=]
   15 |         p = ({ memset((int [3]){}, 0, sizeof(int) * 3); });
      |         ~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cl.c:15:32: note: unnamed temporary defined here
   15 |         p = ({ memset((int [3]){}, 0, sizeof(int) * 3); });
      |                                ^

Reply via email to