<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/160527>160527</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[analyzer] Explicit Return and __attribute__((cleanup(..)))
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
PengZheng
</td>
</tr>
</table>
<pre>
Uncommenting the explicit return in `process_data` will trigger the following:
```Bash
peng@hackerlife2:~/Desktop$ /home/peng/Downloads/LLVM-21.1.2-Linux-X64/bin/scan-build /home/peng/Downloads/LLVM-21.1.2-Linux-X64/bin/clang test.c
scan-build: Using '/home/peng/Downloads/LLVM-21.1.2-Linux-X64/bin/clang-21' for static analysis
test.c:30:5: warning: Potential leak of memory pointed to by 'data' [unix.Malloc]
30 | return;
| ^~~~~~
1 warning generated.
scan-build: Analysis run complete.
scan-build: 1 bug found.
scan-build: Run 'scan-view /tmp/scan-build-2025-09-24-215520-185566-1' to examine bug reports.
```
```C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// This could be unix.Malloc or any other allocation function
void* my_malloc(size_t size) {
return malloc(size);
}
// The cleanup function.
// IMPORTANT: It takes a pointer to the variable, so char** for a char* variable.
void free_pointer(char **p) {
printf("Cleanup function called for address: %p\n", (void*)*p);
free(*p); // Dereference to get the actual pointer and free it.
}
void process_data() {
// The magic happens here. The variable 'data' is tied to the 'free_pointer' function.
__attribute__((cleanup(free_pointer))) char *data = my_malloc(100);
if (!data) {
perror("Allocation failed");
return;
}
strcpy(data, "Hello, Clang Static Analyzer!");
printf("Data processed: %s\n", data);
// Uncommenting the next line will trigger LEAK WARNING
// return;
// No need to call free(data) here.
// The cleanup function is called automatically when process_data() returns.
}
int main() {
process_data();
printf("Back in main. Memory should be freed.\n");
return 0;
}
```
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJykVk1v4zgS_TXlS8GCRFmWffBBiePdxibZRrZ7ZzAXg5JKEicUKZBUEvehf_uAkuzYTmYuLQiwxY_6eO9VkdxaUSuiDSQ3kGxnvHeNNpuvpOo_GlL1LNflYfNdFbptSTmhanQNIb11UhTCoSHXG4VCISzDzuiCrN2X3HFYhvgqpERnRF2TGbZVWkr9KlQNcQbh8C7D8b3htoEw60jVsAgbXjyTkaIiBnH2E9huS_bZ6Q7YAoHtGt0SsN2wmu22-lVJzUsLbHd___-HOYuCKGDze6H6t_nvywWwXS4UsJ0tuJrnvZDlr1gpJPc4kHVBAWH2bhTiDL9bDxKw9FcdzFkELMVKG7SOO1EgV1werLAQZpPzOItDiLPEO37lRo3Q4lftPFlcoiT-jLrCllptDthpoRyV6DTmBx_kQBVLEZKbXom34IFLqQtIthBmiBiHCOkt-mdkGuKbcQbxNAPJ3U__QJhFxyiwJkWGOyqDDwhlUxpoeoWFbjtJjj4uizDva6x0rz6x8dQrH_4w-CLo1dPp2u6C4jkLWTIP13O2mLMoSVg4j1ZJslzOB2CdRnrjrVA0ODLUaeNscKXLq89b_8FioQrZl4QQ31pXCh00EN99NiVF_ndzRqj6NOend8B2-K0RFgvdyxJzwjNOUBvk6oDaNWRwGOJOaIVVrwr_B8LsRYsSWIbtYd-ORLKVFT9o79D_AFsjpEcCp9K9WAhsPTIM6fYqLMJCEld9d3IYvE9_efj636dv2eM3z80Xh44_k0U-6c14rH39v3AjeC4J2C1ajUXDDbDMR-xVzo8Dp3XBlBNWhmg_GQO28utw3NmdJdUZoVwFbAWM3V4FiwWXksrRUVkastbHCizpILlVwJgPCthqwtAjMVqfJO9DGEwfB3HKfUuGKjKkCvJ51uSGXHnhei5PCHA1ZoHCBef4DuldNE7v45ynMwZaXosCG951pCw2ZCgYxo94nVe0sOjEWOo-HGDpJYjpBY_e0X7PnTMi7x3t90MYq4lyYKvLzevxxSMR3ilCvL1QXhSG73oaXYgKB8PRGOV5mv7pyBhtRgKzM4VzIakcKFqfN6CPTekEq_-wzhTdAdhqdObZZf8mKbX_fzv08P-NjXXoSD98YtG1l3NNbX2WE1dUTvKxZ_KZsrpIeaLvwxGq6M2h9N3n4pi8v8v-g79lT49fHv91aeE8Vz8zDT9qVDTy7CV-1OkR4EEkH5V0XcteLlOF8N7p1sPCpTzga0PqM32O0dgLLQvlsOX-BFtdVOX15s_RveHFs79IeAsBPowHlm2OrdDnVQYnsI9Gpi4WXrStY7eelZu4XMdrPqNNlCarlLFolcyaTcUXhT8LSl4tWZwUi0WxDFfrRVUtWJrEq5nY-MMjXLNFFCdLlgQU52mcRiXlyzTOWQWLkFouZCDlSxtoU8-EtT1tomWYsHQmeU7SDrcqxhS94jDrI0-2M7Pxm-Z5X1tYhFJYZ9_NOOHkcB3jR1EmW7w73reexnR9N_nHcg2CU5HOeiM3jXOdb3ijBGrhmj4PCt0C23nP08-8M_pPKhyw3RCvv6lMCb1s2F8BAAD__8yMGnc">