https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91951
Bug ID: 91951 Summary: goto + mixed declarations + cleanup attribute considered harmful Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: allison.karlitskaya at redhat dot com Target Milestone: --- Declaring a variable using __attribute__((__cleanup__)) and an initialiser and then jumping over it with goto will produce code that runs the cleanup function on the uninitialised variable (which will usually result in crashes when you try to free an invalid pointer). See https://blog.fishsoup.net/2015/11/05/attributecleanup-mixed-declarations-and-code-and-goto/ for an old description of the essence of the problem. This blog post implies that GCC gives a helpful warning about this problem, but modern GCC versions seem to have lost this warning. By comparison, clang gives a warning and turns the goto itself into a hard error in response to detecting the problem. GCC should at least give a strong warning about this, or (even better) follow the clang behaviour and error out. An even better alternative would be to ensure that the variable is initialised, even if the initialisation is skipped over with goto. desrt@x1:~$ gcc --version gcc (Debian 8.3.0-6) 8.3.0 Copyright (C) 2018 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. desrt@x1:~$ cat test.c #include <stdio.h> static void func (void **ptr) { printf ("free(%p)\n", *ptr); } int main (void) { goto out; __attribute__((__cleanup__(func))) void *x = NULL; out: return 0; } desrt@x1:~$ gcc -o test test.c -Wall -Wextra desrt@x1:~$ ./test free(0x559190032050) desrt@x1:~$ clang -o test test.c -Wall -Wextra test.c:14:44: warning: unused variable 'x' [-Wunused-variable] __attribute__((__cleanup__(func))) void *x = NULL; ^ test.c:12:3: error: cannot jump from this goto statement to its label goto out; ^ test.c:14:44: note: jump bypasses initialization of variable with __attribute__((cleanup)) __attribute__((__cleanup__(func))) void *x = NULL; ^ 1 warning and 1 error generated. desrt@x1:~$ clang --version clang version 7.0.1-8 (tags/RELEASE_701/final)