This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c++/15069] New: a bit test on a variable of enum type is miscompiled


When testing a bit of a variable with enum type, the test for the
highest bit (bit 2 in my case) is compiled to a bit test for bit 31.
But bit 31 is always zero for all possible values of the enum type.

Environment:
System: Linux honolulu.ilog.fr 2.4.21-0.13mdk #1 Fri Mar 14 15:08:06 EST 2003 i686 unknown unknown GNU/Linux
Architecture: i686

	
host: i686-pc-linux-gnu
build: i686-pc-linux-gnu
target: i686-pc-linux-gnu
configured with: ../gcc-3.4.0/configure --prefix=/home/haible/gnu/arch/linuxgcc34 --enable-shared --enable-threads --enable-__cxa_atexit --enable-languages=c,c++,f77,java,objc --enable-nls

How-To-Repeat:

============================== bug.cc ===================================
extern "C" void abort (void);

void* allocate_stream (unsigned char strmflags)
{
  if (strmflags == 0)
    abort ();
  return 0;
}

typedef enum {
  DIRECTION_PROBE = 0,
  DIRECTION_INPUT = 1,
  DIRECTION_INPUT_IMMUTABLE = 3,
  DIRECTION_OUTPUT = 4,
  DIRECTION_IO = 5
} direction_t;

void* make_unbuffered_stream (direction_t direction, int* eltype)
{
  unsigned char flags =
    (((direction) & (1L<<(0))) ? ((1L<<(4)) | (1L<<(6))) : 0)
    | (((direction) & (1L<<(2))) ? ((1L<<(5)) | (1L<<(7))) : 0)
    | (((direction) & (1L<<(1))) ? (1L<<(1)) : 0);
  if (*eltype == 0)
    flags &= ((1L<<(6)) | (1L<<(7))) | (1L<<(1));
  else
    flags &= ((1L<<(4)) | (1L<<(5))) | (1L<<(1));
  return allocate_stream (flags);
}

int main ()
{
  int x = 1;
  make_unbuffered_stream (DIRECTION_OUTPUT, &x);
  return 0;
}
=========================================================================

$ g++ bug.cc
$ ./a.out
Aborted

Here is the assembler code:
======================== g++ -O -S bug.cc ===============================
	.file	"bug.cc"
	.text
	.align 2
.globl _Z15allocate_streamh
	.type	_Z15allocate_streamh, @function
_Z15allocate_streamh:
.LFB2:
	pushl	%ebp
.LCFI0:
	movl	%esp, %ebp
.LCFI1:
	subl	$8, %esp
.LCFI2:
	cmpb	$0, 8(%ebp)
	jne	.L2
	call	abort
.L2:
	movl	$0, %eax
	leave
	ret
.LFE2:
	.size	_Z15allocate_streamh, .-_Z15allocate_streamh
	.align 2
.globl _Z22make_unbuffered_stream11direction_tPi
	.type	_Z22make_unbuffered_stream11direction_tPi, @function
_Z22make_unbuffered_stream11direction_tPi:
.LFB3:
	pushl	%ebp
.LCFI3:
	movl	%esp, %ebp
.LCFI4:
	subl	$8, %esp
.LCFI5:
	movl	8(%ebp), %edx
	movb	%dl, %al
	andb	$1, %al         	; test bit 0 - correct
	cmpb	$1, %al
	sbbl	%eax, %eax
	notl	%eax
	andl	$80, %eax
	testl	%edx, %edx		; test bit 31 instead of bit 2 - wrong
	jns	.L6
	orl	$160, %eax
.L6:
	testb	$2, %dl			; test bit 1 - correct
	je	.L7
	orl	$2, %eax
.L7:
	movb	%al, %dl
	movl	12(%ebp), %eax
	cmpl	$0, (%eax)
	jne	.L8
	andb	$-62, %dl
	jmp	.L9
.L8:
	andb	$50, %dl
.L9:
	movzbl	%dl, %eax
	movl	%eax, (%esp)
	call	_Z15allocate_streamh
	leave
	ret
.LFE3:
	.size	_Z22make_unbuffered_stream11direction_tPi, .-_Z22make_unbuffered_stream11direction_tPi
	.align 2
.globl main
	.type	main, @function
main:
.LFB4:
	pushl	%ebp
.LCFI6:
	movl	%esp, %ebp
.LCFI7:
	subl	$24, %esp
.LCFI8:
	andl	$-16, %esp
	subl	$16, %esp
	movl	$1, -4(%ebp)
	leal	-4(%ebp), %eax
	movl	%eax, 4(%esp)
	movl	$4, (%esp)
	call	_Z22make_unbuffered_stream11direction_tPi
	movl	$0, %eax
	leave
	ret
.LFE4:
	.size	main, .-main
	.section	.eh_frame,"a",@progbits
.Lframe1:
	.long	.LECIE1-.LSCIE1
.LSCIE1:
	.long	0x0
	.byte	0x1
	.string	"zP"
	.uleb128 0x1
	.sleb128 -4
	.byte	0x8
	.uleb128 0x5
	.byte	0x0
	.long	__gxx_personality_v0
	.byte	0xc
	.uleb128 0x4
	.uleb128 0x4
	.byte	0x88
	.uleb128 0x1
	.align 4
.LECIE1:
.LSFDE1:
	.long	.LEFDE1-.LASFDE1
.LASFDE1:
	.long	.LASFDE1-.Lframe1
	.long	.LFB2
	.long	.LFE2-.LFB2
	.uleb128 0x0
	.byte	0x4
	.long	.LCFI0-.LFB2
	.byte	0xe
	.uleb128 0x8
	.byte	0x85
	.uleb128 0x2
	.byte	0x4
	.long	.LCFI1-.LCFI0
	.byte	0xd
	.uleb128 0x5
	.align 4
.LEFDE1:
.LSFDE3:
	.long	.LEFDE3-.LASFDE3
.LASFDE3:
	.long	.LASFDE3-.Lframe1
	.long	.LFB3
	.long	.LFE3-.LFB3
	.uleb128 0x0
	.byte	0x4
	.long	.LCFI3-.LFB3
	.byte	0xe
	.uleb128 0x8
	.byte	0x85
	.uleb128 0x2
	.byte	0x4
	.long	.LCFI4-.LCFI3
	.byte	0xd
	.uleb128 0x5
	.align 4
.LEFDE3:
.LSFDE5:
	.long	.LEFDE5-.LASFDE5
.LASFDE5:
	.long	.LASFDE5-.Lframe1
	.long	.LFB4
	.long	.LFE4-.LFB4
	.uleb128 0x0
	.byte	0x4
	.long	.LCFI6-.LFB4
	.byte	0xe
	.uleb128 0x8
	.byte	0x85
	.uleb128 0x2
	.byte	0x4
	.long	.LCFI7-.LCFI6
	.byte	0xd
	.uleb128 0x5
	.align 4
.LEFDE5:
	.section	.note.GNU-stack,"",@progbits
	.ident	"GCC: (GNU) 3.4.0"
=========================================================================
------- Additional Comments From bruno at clisp dot org  2004-04-22 12:52 -------
Fix:

My workaround is to use the C compiler instead of the C++ compiler.

-- 
           Summary: a bit test on a variable of enum type is miscompiled
           Product: gcc
           Version: 3.4
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: bruno at clisp dot org
                CC: gcc-bugs at gcc dot gnu dot org
 GCC build triplet: i686-pc-linux-gnu
  GCC host triplet: i686-pc-linux-gnu
GCC target triplet: i686-pc-linux-gnu


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=15069


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]