I really hope this is a bug in my code and not a gcc bug otherwise it looks
serious. The problem basically is that we have an infinite for(;;) loop which
calls a function and adds its return value to a local variable 'sum'.
The loop is terminated with a longjmp.
If the program is compiled at -O0 everything is ok and 'sum' has the sum.
If compiled with >-O1 the sum is always zero.
If we enable a printf printing the value of sum in each iteration, the
result is correct.
The reduced testcase is this:
/
/* lightweight c++ 1.4 */
/** system headers **/
#include
#include
/** global scope **/
struct A;
/** Structures **/
struct A_ViRtUaLTaBlE_StRuCt {
int (*next_APSA1_virtual) (struct A * const this);
};
struct A {
int c;
struct A_ViRtUaLTaBlE_StRuCt *const _v_p_t_r_;
};
struct AuToDt_t {
const struct AuToDt_t *X;
void *x;
void *(*y) (void *);
};
struct longjmp_StaCk {
jmp_buf *x;
struct longjmp_StaCk *y;
void *X;
const struct AuToDt_t *i;
};
/** Virtua Table declarations **/
static struct A_ViRtUaLTaBlE_StRuCt A_A_ViRtUaLTaBlE;
/* Function Prototypes /
static inline void A_ctor_(struct A *const this);
static inline int A_next_(struct A *const this);
void *malloc(unsigned int);
void free();
/* Global variables **/
struct longjmp_StaCk longjmp_iNiTObjFaKe, *__restrict longjmp_StaCkTop =
&longjmp_iNiTObjFaKe;
void __lwc_unwind(void *) __attribute__ ((noreturn));
void __lwc_unwind(void *X)
{
longjmp_StaCkTop->X = X;
while (longjmp_StaCkTop->i) {
longjmp_StaCkTop->i->y(longjmp_StaCkTop->i->x);
longjmp_StaCkTop->i = longjmp_StaCkTop->i->X;
}
longjmp(*longjmp_StaCkTop->x, 1);
}
static inline void *__lwcbuiltin_get_estack()
{
return longjmp_StaCkTop;
}
static inline void __lwcbuiltin_set_estack(void *v)
{
longjmp_StaCkTop = v;
}
/ Internal Functions */
static inline void A___ICoNsTRuCTion(struct A *x, const int y)
{
int i;
for (i = 0; i < y; i++) {
struct A *X = &x[i];
*(struct A_ViRtUaLTaBlE_StRuCt * *) &X->_v_p_t_r_ = &A_A_ViRtUaLTaBlE;
}
}
static inline int next_APSA1_virtual(struct A *const this)
{
return this->_v_p_t_r_->next_APSA1_virtual(this);
}
/* Program function definitions */
static inline void A_ctor_(struct A *const this)
{
this->c = 0;
}
static inline int A_next_(struct A *const this)
{
if (this->c > 10)
__lwc_unwind(0);
return this->c++;
}
int main()
{
struct A *a = ({
struct A * lwcUniQUe = (struct A *)malloc(sizeof(struct A));
A___ICoNsTRuCTion(lwcUniQUe, 1); A_ctor_(lwcUniQUe);
lwcUniQUe;}
);
int sum = 0;
{
struct longjmp_StaCk longjmp_CoNtExT;
jmp_buf lwcUniQUe2;
longjmp_CoNtExT.x = &lwcUniQUe2;
longjmp_CoNtExT.y = longjmp_StaCkTop;
longjmp_StaCkTop = &longjmp_CoNtExT;
longjmp_CoNtExT.X = 0;
longjmp_CoNtExT.i = 0;
if (!(setjmp(lwcUniQUe2))) {
{
for (;;) {
sum += next_APSA1_virtual(a);
// printf("sum=%i\n", sum);
}
}
longjmp_StaCkTop = longjmp_CoNtExT.y;
} else {
longjmp_StaCkTop = longjmp_CoNtExT.y;
}
}
printf("%i\n", sum);
return 0;
}
/ Virtual tables /
static struct A_ViRtUaLTaBlE_StRuCt A_A_ViRtUaLTaBlE = { .next_APSA1_virtual =
A_next_,} ;
///
--
Summary: Miscompilation (infinite loop & longjmp?)
Product: gcc
Version: 3.4.4
Status: UNCONFIRMED
Severity: normal
Priority: P2
Component: c
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: sxanth at ceid dot upatras dot gr
CC: gcc-bugs at gcc dot gnu dot org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=22346