Package: gcc-2.95 Version: 1:2.95.4-24 Severity: normal The file is_pair.c below compiled with
gcc-2.95 -O2 -S is_pair.c results in the following in is_pair.s movl (%ebx),%edx testb $6,%bl jne .L10 which I believe is incorrect for the input. Those insns are from the inlined scm_is_pair. "x" is %ebx and it's tested "x & 6" and there's a test on the contents at "*x". But notice the fetch *x has been moved back before the "&6" test. I think this is wrong. "(x&6)==0 && (*x...)" should mean *x is not evaluated, ie. x not dereferenced, until the "x&6" has been checked. I struck this in the latest version of guile (1.8.0), it results in segvs in the split_at function in the test suite. "-O2" is of course the default optimization level for autoconfed packages, so it wasn't just me mucking about with flags. The problem doesn't occur if you turn down to -O1, and I also noticed that without "noreturn" on scm_wrong_type_arg_msg it's ok (but perhaps that's only coincidence). I suppose gcc 2.95 is too old to be of great interest, but while it's still in debian it'd be nice if it was correct. The problem doesn't seem to occur with gcc 4. -- System Information: Debian Release: testing/unstable APT prefers unstable APT policy: (500, 'unstable') Architecture: i386 (i586) Shell: /bin/sh linked to /bin/dash Kernel: Linux 2.6.15-1-486 Locale: LANG=en_AU, LC_CTYPE=en_AU (charmap=ISO-8859-1) Versions of packages gcc-2.95 depends on: ii binutils 2.16.1cvs20051214-1 The GNU assembler, linker and bina ii cpp-2.95 1:2.95.4-24 The GNU C preprocessor ii libc6 2.3.6-7 GNU C Library: Shared libraries Versions of packages gcc-2.95 recommends: ii libc6-dev [libc-dev] 2.3.6-7 GNU C Library: Development Librari -- no debconf information
typedef unsigned int size_t; typedef unsigned int uintptr_t; typedef uintptr_t scm_t_bits; typedef struct scm_unused_struct * SCM; enum scm_tc8_tags { scm_tc8_flag = 4 + 0x00, scm_tc8_char = 4 + 0x08, scm_tc8_isym = 4 + 0x10, scm_tc8_iloc = 4 + 0x18 }; typedef struct scm_t_cell { SCM word_0; SCM word_1; } scm_t_cell; extern SCM scm_cons (SCM x, SCM y); extern SCM scm_list_2 (SCM e1, SCM e2); extern SCM scm_values (SCM args); extern void scm_wrong_type_arg_msg (const char *subr, int pos, SCM bad_value, const char *sz) __attribute__ ((noreturn)) ; extern int scm_is_pair (SCM x); extern inline int scm_is_pair (SCM x) { return ! (6 & ((scm_t_bits) x)) && ((1 & ((scm_t_bits) (((SCM *)((scm_t_cell *) (scm_t_bits) x)) [0]))) == 0); } static const char s_scm_srfi1_split_at [] = "split-at" ; SCM scm_srfi1_split_at (SCM lst, SCM n) { size_t nn; SCM pre = ((SCM) ( (( ( 4 ) ) << 8) + scm_tc8_flag )) ; SCM *loc = ⪯ for (nn = scm_to_uint32 (n); nn != 0; nn--) { if (!( scm_is_pair (lst) )) scm_wrong_type_arg_msg(s_scm_srfi1_split_at, 1, lst, "pair"); *loc = scm_cons ((( ( (((SCM *)((scm_t_cell *) (((scm_t_bits) (0? (*(SCM*)0=( ( ( lst ) ) )): ( ( lst ) ) )) )) ) [ ( 0 ) ]) ) ) ) , ((SCM) ( (( ( 4 ) ) << 8) + scm_tc8_flag )) ); loc = ((( & (((SCM *)((scm_t_cell *) (((scm_t_bits) (0? (*(SCM*)0=( ( ( *loc ) ) )): ( ( *loc ) ) )) )) ) [ ( 1 ) ]) ) ) ) ; lst = (( ( (((SCM *)((scm_t_cell *) (((scm_t_bits) (0? (*(SCM*)0=( ( ( lst ) ) )): ( ( lst ) ) )) )) ) [ ( 1 ) ]) ) ) ) ; } return scm_values (scm_list_2 (pre, lst)); }