🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: gnu.gcc.bug
Article #5987

gcc 272 pointer bug

#5987
From: Labalutsch
Date: Mon, 20 Jan 1997 00:00
142 lines
3919 bytes
Hello.

I have problems with gcc v2.7.2 using the following C code:

/* --- C code starts here --- */

#include <stdio.h>
#include <stdlib.h>

extern char
  *force_bug __P( (char *, int *) );

int
main( argv, argc)
  int	argc;
  char	**argv;
{
  char	*bufp, buf[ 2];
  int	result;

  buf[ 0]= '\x01';
  buf[ 1]= '\x02';
  result= 0;
  bufp= force_bug( buf, &result);
  printf( "read %d chars - expected result = 0x0102 - got 0x%04x\n",
	  bufp- &buf[ 0], (unsigned int) result);
  return( 0);
}

char *
force_bug( p, pres)
  char	*p;
  int	*pres;
{
  /* gcc-2.7.2 will produce code like the following statements were given:
   *   *pres= ( (unsigned char) *p << 8) | (unsigned char) *p;
   *   return( p+ 2);
   * gcc-2.7.2 would produce correct code if the sequence would be:
   *   *pres= (unsigned char) *p++ << 8;
   *   *pres |= (unsigned char) *p++;
   *   return( p);
   * but this sequence can't be used as a while-expression
   */

  *pres= ( (unsigned char) *p++ << 8) | (unsigned char) *p++;
  return( p);
}

/* --- C code ends here --- */

IMHO, the evaluation order for the `bitwise-or' operator is left to right.
At least according to K&R.  Additionally the left-hand side of the `or'
operator is parenthesized giving it highest priority.  Side-effects aren't
an argument, as no function call is involved here.  Neither is the
incremented
pointer an l-value in this case.  So the above sequence is correct, at least
to my understanding of C programming.
Below you see the gcc-generated assembler output - I've put some comments
in (in order to make it more understandable ;-).

/* --- gcc generated assembly output starts here --- */

	.file	"buggy.c"
gcc2_compiled.:
___gnu_compiled_c:
.text
LC0:
	.ascii "read %d chars - expected result = 0x0102 - got 0x%04x\12\0"
	.align 2
.globl _main
_main:
	pushl %ebp
	movl %esp,%ebp
	subl $8,%esp
	pushl %ebx
	call ___main
	movb $1,-6(%ebp)
	movzbw -6(%ebp),%ax
	orb $2,%ah
	movw %ax,-6(%ebp)
	movl $0,-4(%ebp)
	leal -4(%ebp),%eax
	pushl %eax
	leal -6(%ebp),%ebx
	pushl %ebx
	call _force_bug
	movl %eax,%edx
	movl -4(%ebp),%eax
	pushl %eax
	movl %edx,%eax
	subl %ebx,%eax
	pushl %eax
	pushl $LC0
	call _printf
	xorl %eax,%eax
	movl -12(%ebp),%ebx
	movl %ebp,%esp
	popl %ebp
	ret
	.align 2
.globl _force_bug
_force_bug:
	pushl %ebp
	movl %esp,%ebp
	pushl %ebx
	movl 8(%ebp),%ebx	; get parameter `p'
	movl 12(%ebp),%ecx	; get parameter `pres'
	movzbl (%ebx),%edx	; register `edx'= *p
	movl %edx,%eax		; register `eax'= register `edx'
	sall $8,%eax		; register `eax' <<= 8
	orl %edx,%eax		; register `eax' |= register `edx'
	movl %eax,(%ecx)	; *pres= register `eax'
	addl $2,%ebx		; p += 2
	movl %ebx,%eax		; return( p)
	movl -4(%ebp),%ebx
	movl %ebp,%esp
	popl %ebp
	ret

/* --- gcc generated assembly output ends here --- */

This bug can be reproduced *every* time - independent of what options in use.
The above sequence was compiled by gcc-2.7.2 with the following options:
  gcc -m486 -O2 -S buggy.c -o buggy.s

Even the option `-g' instead of `-O2' gives the same behaviour.

Some information about the system I'm using:

  Linux 1.2.13 running a i80486-DX2/66
  gcc 2.7.2 (a.out only)
  libc 4.6.27

Best regards.

CU Thommy
<Labalutsch@aol.com> (Thomas M. Ott)
===[PGP key on request]===

` Let Jesus be your anchor. '
` So when Satan rocks your boat - throw Jesus overboard. '
Technical Details
Message-ID: <970120092332_1510729510@emout20.mail.aol.com>
Path: arc1-ca.pugleaf.net!unknown!not-for-mail

Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: 113d02,8a19bb07509800c5,start
X-Google-Attributes: gid113d02,public
From: Labalutsch@aol.com
Subject: gcc 272 pointer bug
Date: 1997/01/20
Message-ID: <970120092332_1510729510@emout20.mail.aol.com>
X-Deja-AN: 211131171
sender: bug-gcc-request@prep.ai.mit.edu
x-gateway: relay6.UU.NET from bug-gcc to gnu.gcc.bug; Mon, 20 Jan 1997 10:32:42 EST
newsgroups: gnu.gcc.bug