Open Quuxplusone opened 9 years ago
Attached pats_constraint3_solve_dats.c
(267209 bytes, application/octet-stream): Generated C code
Typo in the description: 'patopt' -> 'patsopt'
Can you preprocess the source? I am very curious about the definition of ATS_TRYWITH_TRY. This smells like a setjmp/longjmp/returns_twice bug.
Very well could be. Which should it be? (gotta love that WARNING, eh?)
#define atspre_setjmp(env, mask) setjmp(env)
#define atspre_longjmp(env, ret) longjmp(env, ret)
/*
** WARNING: DO NOT USE THE FOLLOWING MACROS:
*/
#define ATS_TRYWITH_TRY(tmp_exn) \
do { \
ATS_ENTER_EXCEPTION_FRAME() ; \
tmp_exn = (ats_exn_ptr_type)((intptr_t)atspre_setjmp(ATS_CURRENT_FRAME->env,
0)) ; \
if ((intptr_t)tmp_exn == 0) { /* ... */
#define ATS_TRYWITH_WITH(tmp_exn) \
ATS_LEAVE_EXCEPTION_FRAME() ; \
} else { \
tmp_exn = ATS_CURRENT_FRAME->exn ; \
ATS_LEAVE_EXCEPTION_FRAME() ; /* exception handling */
#define ATS_TRYWITH_END() \
} \
} while(0)
/* end of WARNING */
So this is almost undoubtedly a setjmp issue. Relevant C standard quote
[7.13.2.1 p5]:
"""
All accessible objects have values, and all other components of the abstract
machine249)
have state, as of the time the longjmp function was called, except that the
values of
objects of automatic storage duration that are local to the function containing
the
invocation of the corresponding setjmp macro that do not have volatile-
qualified type
and have been changed between the setjmp invocation and longjmp call are
indeterminate.
"""
As the variable tmp502 is not declared volatile, its value is indeterminate. I
think this is working as intended with nothing to do in LLVM.
Can you help us understand this better? The following code is a minor
variation of the Wikipedia's article on setjmp and does not work consistently
between -O1 and -O2.
#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>
static jmp_buf buf;
void
second(int *p) {
*p = 1000000;
printf("second: *p = %i\n", *p);
longjmp(buf,1); // jumps back to where setjmp was called - making setjmp now return 1
}
void
first(int *p) {
second(p);
printf("first\n"); // does not print
}
int main() {
/*
int x = 0;
*/
int *p;
p = malloc(sizeof(int));
/*
printf("main: p = %p\n", p);
*/
if (p == 0)
{
fprintf (stderr, "malloc: failed!\n"); exit(1);
}
*p = 0;
if (!setjmp(buf) ) {
first(p); // when executed, setjmp returns 0
} else { // when longjmp jumps back, setjmp returns 1
printf("main: *p = %i\n", *p); // prints
}
return 0;
}
Nevermind, I get it.
pats_constraint3_solve_dats.c
(267209 bytes, application/octet-stream)