Skip to content

Modification to malloc'd local variable between builtin setjmp and londjump calls not preserved #116668

Closed
@anoopkg6

Description

@anoopkg6

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)
{
  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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions