This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
bfd/i386/x86-64 type punning again
- From: DJ Delorie <dj at redhat dot com>
- To: binutils at sources dot redhat dot com
- Date: Tue, 30 Aug 2005 23:45:39 -0400
- Subject: bfd/i386/x86-64 type punning again
Yet another case of gcc-4.x noting strict aliasing rules being broken
by type punning. In the "for" case, it seems like we take the address
of a variable just to dereference it and get the variable back.
Stripping this off avoids the type punning completely. In the second
case, like ld, we use a temporary variable to avoid having the
address-of and the cast in the same statement.
Do we still like this type of solution?
* elf32-i386.c (elf_i386_check_relocs): Don't cast a unary &
address operator, as that breaks GCC's strict aliasing rules.
(elf_i386_size_dynamic_sections): Avoid the need for type
punning.
* elf64-x86-64.c (elf_x86_64_check_relocs): Don't cast a unary
& address operator, as that breaks GCC's strict aliasing
rules.
(elf_x86_64_size_dynamic_sections): Avoid the need for type
punning.
Index: elf32-i386.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-i386.c,v
retrieving revision 1.148
diff -p -U3 -r1.148 elf32-i386.c
--- elf32-i386.c 25 Aug 2005 02:32:09 -0000 1.148
+++ elf32-i386.c 31 Aug 2005 03:36:29 -0000
@@ -1165,6 +1165,7 @@ elf_i386_check_relocs (bfd *abfd,
}
else
{
+ void **vpp;
/* Track dynamic relocs needed for local syms too.
We really need local syms available to do this
easily. Oh well. */
@@ -1175,8 +1176,8 @@ elf_i386_check_relocs (bfd *abfd,
if (s == NULL)
return FALSE;
- head = ((struct elf_i386_dyn_relocs **)
- &elf_section_data (s)->local_dynrel);
+ vpp = &elf_section_data (s)->local_dynrel;
+ head = (struct elf_i386_dyn_relocs **)vpp;
}
p = *head;
@@ -1823,8 +1824,8 @@ elf_i386_size_dynamic_sections (bfd *out
{
struct elf_i386_dyn_relocs *p;
- for (p = *((struct elf_i386_dyn_relocs **)
- &elf_section_data (s)->local_dynrel);
+ for (p = ((struct elf_i386_dyn_relocs *)
+ elf_section_data (s)->local_dynrel);
p != NULL;
p = p->next)
{
Index: elf64-x86-64.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-x86-64.c,v
retrieving revision 1.106
diff -p -U3 -r1.106 elf64-x86-64.c
--- elf64-x86-64.c 25 Aug 2005 02:32:11 -0000 1.106
+++ elf64-x86-64.c 31 Aug 2005 03:36:30 -0000
@@ -946,6 +946,7 @@ elf64_x86_64_check_relocs (bfd *abfd, st
}
else
{
+ void **vpp;
/* Track dynamic relocs needed for local syms too.
We really need local syms available to do this
easily. Oh well. */
@@ -956,8 +957,10 @@ elf64_x86_64_check_relocs (bfd *abfd, st
if (s == NULL)
return FALSE;
- head = ((struct elf64_x86_64_dyn_relocs **)
- &elf_section_data (s)->local_dynrel);
+ /* Beware of type punned pointers vs strict aliasing
+ rules. */
+ vpp = &(elf_section_data (s)->local_dynrel);
+ head = (struct elf64_x86_64_dyn_relocs **)vpp;
}
p = *head;
@@ -1586,8 +1589,8 @@ elf64_x86_64_size_dynamic_sections (bfd
{
struct elf64_x86_64_dyn_relocs *p;
- for (p = *((struct elf64_x86_64_dyn_relocs **)
- &elf_section_data (s)->local_dynrel);
+ for (p = (struct elf64_x86_64_dyn_relocs *)
+ (elf_section_data (s)->local_dynrel);
p != NULL;
p = p->next)
{