From: jim@modcomp.COM (Jim Houston)
Subject: bug in -fvolatile in gcc 2.2.2
Organization: GNUs Not Usenet
Distribution: gnu
Date: Wed, 14 Oct 1992 20:55:24 GMT

The attached shar file is a bug report for gcc 2.2.2 with a proposed
fix.  I really enjoy using your compiler and also had fun looking at 
this problem.

Thanks! 

Jim Houston, Modcomp, uunet!modcomp!jim,  (305)977-1547

#--------------------------------CUT HERE-------------------------------------
#! /bin/sh
#
# This is a shell archive.  Save this into a file, edit it
# and delete all lines above this comment.  Then give this
# file to sh by executing the command "sh file".  The files
# will be extracted into the current directory owned by
# you with default permissions.
#
# The files contained herein are:
#
# -rw-rw-r--   1 jim      ngcp        1626 Oct 14 15:28 README
# -rw-r--r--   1 jim      ngcp         670 Oct 14 13:47 expr.c.diff
# -rw-rw-r--   1 jim      ngcp         190 Oct 13 15:19 xx.c
#
echo 'x - README'
if test -f README; then echo 'shar: not overwriting README'; else
sed 's/^X//' << '________This_Is_The_END________' > README
XGNU Compiler Bug in gcc version 2.2.2 on m88k ocs/bcs compliant SysV.3
X
XSUMMARY
X
X  The -fvolatile option says that anything referenced using a pointer should
X  be treated as a volatile.  The optimization of fields done during the parse
X  stage of the compilation by-passes this check which is only in expand_expr().
X
XTO REPRODUCE THE PROBLEM
X
X  The problem can  be reproduced with the included file xx.c and the command:
X
X	cc1 -O -fvolatile xx.c
X
X  The example is a subroutine with a single if statement which references
X  two 16 bit fields using a pointer.  The compiler combines these into
X  a single 32 bit reference whether the -fvolatile option is specified
X  or not...  The -fvolatile option should force the two fields to be 
X  referenced independently.
X  
X  We are really pleased to see this level of optimization but it is
X  convenient to be able to turn it off.  We use GNU cc to build our
X  multi-processor kernel.  The sample code is used to reference 16 bit
X  wide memory which will fault on 32 bit references.
X
XSOLUTION????
X
X  This optimization is being done in optimize_bit_field().  I noticed that
X  it uses get_inner_reference to find the larger object which contains the 
X  bit field or structure member and that this routine is used to check
X  if the reference is volatile.  I added code to get_inner_reference()
X  set *pvolatilep if flag_volatile is set and an INDIRECT_REF is found in
X  the tree.  This seems to fix the bug.  expr.c.diff is a context diff
X  for my change to expr.c
X
X
XP.S.
X
X  I also noticed that this optimization is not done if the two  fields
X  are in the first word of the structure.  
________This_Is_The_END________
if test `wc -l < README` -ne 40; then
	echo 'shar: README was damaged during transit (should have been 40 bytes)'
fi
fi		; : end of overwriting check
echo 'x - expr.c.diff'
if test -f expr.c.diff; then echo 'shar: not overwriting expr.c.diff'; else
sed 's/^X//' << '________This_Is_The_END________' > expr.c.diff
X*** expr.c.0	Wed Oct 14 13:37:49 1992
X--- expr.c	Wed Oct 14 13:39:35 1992
X***************
X*** 2515,2530 ****
X--- 2515,2532 ----
X  
X    /* Compute cumulative bit-offset for nested component-refs and array-refs,
X       and find the ultimate containing object.  */
X  
X    *pbitpos = 0;
X  
X    while (1)
X      {
X+       if ((TREE_CODE (exp) == INDIRECT_REF) && flag_volatile)
X+ 	*pvolatilep = 1;
X        if (TREE_CODE (exp) == COMPONENT_REF || TREE_CODE (exp) == BIT_FIELD_REF)
X  	{
X  	  tree pos = (TREE_CODE (exp) == COMPONENT_REF
X  		      ? DECL_FIELD_BITPOS (TREE_OPERAND (exp, 1))
X  		      : TREE_OPERAND (exp, 2));
X  
X  	  if (TREE_CODE (pos) == PLUS_EXPR)
X  	    {
________This_Is_The_END________
if test `wc -l < expr.c.diff` -ne 23; then
	echo 'shar: expr.c.diff was damaged during transit (should have been 23 bytes)'
fi
fi		; : end of overwriting check
echo 'x - xx.c'
if test -f xx.c; then echo 'shar: not overwriting xx.c'; else
sed 's/^X//' << '________This_Is_The_END________' > xx.c
X
Xstruct abc
X{
X	int a;
X	unsigned short  magicu;
X	unsigned short  magicl;
X};
X
Xy(def)
Xregister struct abc *def;
X{
X	if (def->magicu == 12345 && def->magicl == 56789 )
X		return(1);
X	return(0);
X}
________This_Is_The_END________
if test `wc -l < xx.c` -ne 15; then
	echo 'shar: xx.c was damaged during transit (should have been 15 bytes)'
fi
fi		; : end of overwriting check
exit 0

Newsgroups: gnu.gcc.bug