A
ais523
I've found what I think might be a compiler bug, but which might just be
me failing to understand things.
Here's the simplest example I've found to reproduce the bug:
== cut here ==
#include <setjmp.h>
#include <string.h>
int main(void)
{
char *volatile b = "test";
char *a = b;
jmp_buf j;
int i = 0;
while (1) {
/* a, b, and i are all determinate here, either from the
previous iteration of the while loop or from being
initialized at the start of the program
However, gcc produces a warning:
setjmp-issue.c:21:9: warning: variable ¡__s1¢ might be clobbered by ¡longjmp¢ or ¡vfork¢ [-Wclobbered]
if (strcmp(a, "test") == 0) {
^
*/
if (strcmp(a, "test") == 0) {
if (setjmp(j) == 0) {
/* setjmp returns twice; if it returns 0, it was due to
being called directly, thus a is stil determinate */
i = 1;
} else {
/* if setjmp returns 1, it was due to a longjmp; i is
indeterminate at this point (7.13.2.1p3), a is still
determinate because it hasn't changed since the longjmp */
i = 0;
a = "test";
/* now i is determinate again because I assigned an explicit
value to it */
}
}
/* a, b, and i are all determinate here; b never became
indeterminate because it's volatile, a and i are either
determinate from the if block, or have the same values as on
the previous iteration of the while loop */
if (b && i)
longjmp(j, 1);
}
return 0;
}
== cut here ==
A version without the comments, making it easier to see the control
flow:
== cut here ==
#include <setjmp.h>
#include <string.h>
int main(void)
{
char *volatile b = "test";
char *a = b;
jmp_buf j;
int i = 0;
while (1) {
if (strcmp(a, "test") == 0) {
if (setjmp(j) == 0) {
i = 1;
} else {
i = 0;
a = "test";
}
}
if (b && i)
longjmp(j, 1);
}
return 0;
}
== cut here ==
gcc 4.8.1 thinks that the strcmp() call here is undefined behaviour, but
as far as I can tell, `a` has a defined and determinate value no
matter how the control flow reaches that point: it's initialized to a
determinate value, and the only time that its value becomes
indeterminate (due to setjmp() returning), it's assigned a defined value
again before being used. I've also taken care to avoid undefined
behaviour elsewhere in the program.
Am I missing something here? Or is the compiler?
me failing to understand things.
Here's the simplest example I've found to reproduce the bug:
== cut here ==
#include <setjmp.h>
#include <string.h>
int main(void)
{
char *volatile b = "test";
char *a = b;
jmp_buf j;
int i = 0;
while (1) {
/* a, b, and i are all determinate here, either from the
previous iteration of the while loop or from being
initialized at the start of the program
However, gcc produces a warning:
setjmp-issue.c:21:9: warning: variable ¡__s1¢ might be clobbered by ¡longjmp¢ or ¡vfork¢ [-Wclobbered]
if (strcmp(a, "test") == 0) {
^
*/
if (strcmp(a, "test") == 0) {
if (setjmp(j) == 0) {
/* setjmp returns twice; if it returns 0, it was due to
being called directly, thus a is stil determinate */
i = 1;
} else {
/* if setjmp returns 1, it was due to a longjmp; i is
indeterminate at this point (7.13.2.1p3), a is still
determinate because it hasn't changed since the longjmp */
i = 0;
a = "test";
/* now i is determinate again because I assigned an explicit
value to it */
}
}
/* a, b, and i are all determinate here; b never became
indeterminate because it's volatile, a and i are either
determinate from the if block, or have the same values as on
the previous iteration of the while loop */
if (b && i)
longjmp(j, 1);
}
return 0;
}
== cut here ==
A version without the comments, making it easier to see the control
flow:
== cut here ==
#include <setjmp.h>
#include <string.h>
int main(void)
{
char *volatile b = "test";
char *a = b;
jmp_buf j;
int i = 0;
while (1) {
if (strcmp(a, "test") == 0) {
if (setjmp(j) == 0) {
i = 1;
} else {
i = 0;
a = "test";
}
}
if (b && i)
longjmp(j, 1);
}
return 0;
}
== cut here ==
gcc 4.8.1 thinks that the strcmp() call here is undefined behaviour, but
as far as I can tell, `a` has a defined and determinate value no
matter how the control flow reaches that point: it's initialized to a
determinate value, and the only time that its value becomes
indeterminate (due to setjmp() returning), it's assigned a defined value
again before being used. I've also taken care to avoid undefined
behaviour elsewhere in the program.
Am I missing something here? Or is the compiler?