I have mostly convinced myself that I have encountered some g++ 4.8.3 bug, but I thought I would ask this list first because I have very little experience with setjmp/longjmp. I have simplified my code in question to the following foo.cxx:
#include <setjmp.h>
#include <string.h>
// Changing MyStruct to be just a single int makes the compiler happy.
struct MyStruct
{
int a;
int b;
};
// Setting MyType to int makes the compiler happy.
#ifdef USE_STRUCT
typedef MyStruct MyType;
#elif USE_INT
typedef int MyType;
#endif
void SomeFunc(MyType val)
{
}
static void static_func(MyType val)
{
SomeFunc(val);
}
int main(int argc, char **argv)
{
jmp_buf env;
if (setjmp(env))
{
return 1;
}
MyType val;
#ifdef USE_STRUCT
val.a = val.b = 0;
#elif USE_INT
val = 0;
#endif
// Enabling the below memset call makes the compiler happy.
//memset(&val, 0, sizeof(val));
// Iterating 1 or 2 times makes the compiler happy.
for (unsigned i = 0; i < 3; i++)
{
// calling SomeFunc() directly makes the compiler happy.
static_func(val);
}
return 0;
}
I use g++ 4.8.3 to compile this code. What's interesting to me is that when I define USE_STRUCT, the compilation fails but succeeds with USE_INT. There are comments in the code that further indicate how to make compilation succeed with USE_STRUCT. Compilation only fails also with the -fPIC option to g++, but this is a required argument in my environment.
To see the compilation error:
g++ -DUSE_STRUCT -Wextra -Wno-unused-parameter -O3 -Werror -fPIC foo.cxx
foo.cxx: In function ‘int main(int, char**)’:
foo.cxx:26:5: error: variable ‘val’ might be clobbered by ‘longjmp’ or ‘vfork’ [-Werror=clobbered]
But using a simple int is OK:
g++ -DUSE_INT -Wextra -Wno-unused-parameter -O3 -Werror -fPIC foo.cxx
Can someone please explain to me why val might be clobbered if it is a struct but not if it is an int? Any insights on the other ways to make compilation succeed with the struct, as indicated in the comments in the code? Or is this pointing to a compiler bug?
Any insights and comments are greatly appreciated.