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 <stdio.h> #include <setjmp.h> /************** 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