<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/116668>116668</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Modification to malloc'd local variable between builtin setjmp and londjump calls not preserved
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
anoopkg6
</td>
</tr>
</table>
<pre>
Any modification to malloc'd local variable between __builtin_setjmp and __builtin_longjmp calls does not persist. It is optimized by either by earlyCSE or GVN (global value numbering) pass. __builtin_setjmp has attribute (llvm::Attribute::ReturnsTwice).
//bug.c
#include <stdio.h>
```
#include <stdlib.h>
void* buf[20];
attribute((noinline))
void foo(void)
{
printf("Calling longjmp from inside function foo\n");
__builtin_longjmp(buf, 1);
printf("This point should never be reached\n");
}
int main(void)
{
// Without malloc
int *local_var = malloc(sizeof(int));
*local_var = 10;
printf("local_val=%d \n", *local_var);
if (__builtin_setjmp(buf) == 0)
{
` *local_var` = 20;
printf("Calling function foo local_var=%d \n", *local_var);
foo();
}
printf("longjmp has been called local_val=%d \n", *local_var);
}
```
/*******************Output should be as follows: **********************
local_val=10
Calling function foo local_var=20
Calling longjmp from inside function foo
longjmp has been called local_val=20
**********************************************************************/
$clang -O2 bug.c
$./a.out
local_val=10
Calling function foo local_var=20
Calling longjmp from inside function foo
longjmp has been called local_val=10
Value of local_var is modified between setjmp and longjmp calls to 20, but after return from longjmp local_var remains 10 because of GVN optimization.
After some analyses I have attached setjmp_longjmp_bug.zip files have two tests case, bug1.c and and bug2.c. bug1.c is compiled at -O1 and has information after each pass using -dump-after-all in file bug1_dump_earlycse_o1. earlyCSE optimizes malloc'd local_var.
Similarly, in bug2.c, GVN optimizes malloc'd local variable local_var at -O2. It's dump after each pass is in bug2_dump_gvn_o2 file. Both dump files are marked with "???" where wrong optimization (constant folding) happens.
[setjmp_longjmp_bug.zip](https://github.com/user-attachments/files/17803940/setjmp_longjmp_bug.zip)
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzcVsuO2zoS_Rp6U7AgUZYtLbxw2_Egi5kAkyCzNCipJDGhSIEPG52vH5CS_OrODZLVxW2w1S0-iqceqnOYMbyViFuSvZDssGDOdkpvmVRq-N6uF6WqX7c7-Qq9qnnDK2a5kmAV9EwIVRG6qUGoigk4M81ZKRBKtBdECadT6biwXJ4M2m_9AEzWd5NCydbPVkwIA7VCA1JZGFAbbmwEHy1wA2qwvOc_sIbyFZDbDnX4j2nxuv_8AZSGf339DxCat0KVAYZwCNL1JWouW0ILGJgx0Vs4HTPArNW8dBa9BSHOPUl3JN3t5unx9b9onZbmy4VXSGgRkfhA4t30pEdCj6Vro2qeSLmshKsRSLo3tuYq6kj6YVpdx9N4f7Pg5f3u8DwrXhO6g9I1JHuhMckOJH0Z164OEJoTmkvFpeDSo_TjehwapQjNR0vTPNlMNmDQXNomWKB7JgSXLczpabTqgUvDa4TGySrk31vL9pJQ6q3NWN4ml9Dcg6Z7SB423l_4peMGBsWlBdMpJ2qQePZZRtDIqg7rd64im8N9hPzhnnH5cxdhzBP8j9tOOTuX77jojxO6C3V8OjMNJD1cCzw3_AcqD5ZLO8U1vTP7dCyJ33dz3iVIeiA0q-Hq1f7ByKN53vjCfC7dOayFv9FfGl89Brj3eR0_IvQTfj-9A-l_3iuA-2TDzcLvoAeY6u4pZnPy4ClCY8X577L0DcR3BqzhTyL3VB9vvrojobs_G5-cHdy1VEsEZqBRQqiLIekO_tjubQSI904nE-xfZoY-bfzlNzxd9eu402vk_nnj-NjOV5VgsoXlJwoPXX0VEXpkkXL2b5mhGcL4_BpYUDW3yz2ZjhzuuXSi6DtifqRjq3yPoHsonQXWWNSgAwmOSOfNN-saff81kMRQYsWcCbd7ap4YPAiHB-bcBbNG9QhMMvFq0MBH6NgZPS2Hzj8BnOnk5BPygw_QcIFm3GovCiwaa6BiBkfIbRJVwSn_W7qWRlU0T3MDleoH7uPHLCw_JWGXDy2XjdL9qHBGnz3_BPkAzvh0LWvXD8uwtmRCAJcBSrB98munIEwqgyeVRHcqZVIx5o1s8sF7iMpn3nPhz3lXuJzg-5e7YL5j6Ka_bkkJ_lEvpQjdGPAA3zjGzXzL6EB7lidFg1sRvCjbjcfGiDON0DP9HWu4cNuB78LpcRqUwqVDjXDRSrYPefckVilpLJPWd8t6UmYdGwaUZg5A9vJ-vr3goXln7eB77MjkLbedK6NK9YQenfEJCUXTo7SG0GMATOgx2eRxWqxiQo8_MT5T56LepnWRFmyB22STJkVGi0266LY1liXSpqyaTVGXRRXjCtdJWm9SLEqaVAu-pTFdJUmSJ3lMMxpt8ixf11leZNmGFnlFVrH_PkTkJWakdLvgxjjcJsl6vc4XgpUoTJDglEq8QFj1wc0OC731h5alaw1ZxYIba25mLLcCt__-bW0-6YmnBlB_c9cOELS4RoP6jPXCabH9i_gH5Tz-WQ5afcPKEnoMXoQcjG6et_T_AQAA__9Xnc3z">