This is the mail archive of the gcc-patches@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]

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


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;


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