[PATCH] Fix PR middle-end/26565, memcpy alignment issue

Richard Guenther rguenther@suse.de
Mon Mar 6 14:52:00 GMT 2006


This patch fixes PR26565, emitting unaligned stores for

void *memcpy(void *dest, const void *src, __SIZE_TYPE__ n);

struct timeval {
    long tv_sec;
};

struct outdata {
    char seq;
    struct timeval tv __attribute__((packed));
};

void send_probe(struct outdata *outdata, struct timeval *tp)
{
    memcpy(&outdata->tv, tp, sizeof outdata->tv);
}

on STRICT_ALIGNMENT targets.  builtins.c:get_pointer_alignment is simply
overly optimistic about the alignment it can infer.  Fixed by looking
through component references and taking into account their DECL_ALIGN.

The only way to workaround the bug I found is to use (char*)outdata+1 for
the destination parameter.  A direct assignment outdata->tv = *tp also 
works as expected.

Boostrapped and regtested on ia64-unknown-linux-gnu.

Ok for mainline, 4.1 and 4.0?

Thanks,
Richard.


:ADDPATCH middle-end:

2006-03-06  Richard Guenther  <rguenther@suse.de>

	PR middle-end/26565
	* builtins.c (get_pointer_alignment): Handle component
	references for field alignment.

Index: builtins.c
===================================================================
*** builtins.c	(revision 111638)
--- builtins.c	(working copy)
*************** get_pointer_alignment (tree exp, unsigne
*** 275,289 ****
  	case ADDR_EXPR:
  	  /* See what we are pointing at and look at its alignment.  */
  	  exp = TREE_OPERAND (exp, 0);
  	  if (TREE_CODE (exp) == FUNCTION_DECL)
! 	    align = FUNCTION_BOUNDARY;
  	  else if (DECL_P (exp))
! 	    align = DECL_ALIGN (exp);
  #ifdef CONSTANT_ALIGNMENT
  	  else if (CONSTANT_CLASS_P (exp))
! 	    align = CONSTANT_ALIGNMENT (exp, align);
  #endif
! 	  return MIN (align, max_align);
  
  	default:
  	  return align;
--- 275,295 ----
  	case ADDR_EXPR:
  	  /* See what we are pointing at and look at its alignment.  */
  	  exp = TREE_OPERAND (exp, 0);
+ 	  while (handled_component_p (exp))
+ 	    {
+ 	      if (TREE_CODE (exp) == COMPONENT_REF)
+ 		align = MIN (align, DECL_ALIGN (TREE_OPERAND (exp, 1)));
+ 	      exp = TREE_OPERAND (exp, 0);
+ 	    }
  	  if (TREE_CODE (exp) == FUNCTION_DECL)
! 	    align = MIN (align, FUNCTION_BOUNDARY);
  	  else if (DECL_P (exp))
! 	    align = MIN (align, DECL_ALIGN (exp));
  #ifdef CONSTANT_ALIGNMENT
  	  else if (CONSTANT_CLASS_P (exp))
! 	    align = MIN (align, (unsigned)CONSTANT_ALIGNMENT (exp, align));
  #endif
! 	  return align;
  
  	default:
  	  return align;



More information about the Gcc-patches mailing list