[PATCH] Fix C++ strict-aliasing issues with memcpy folding
Richard Guenther
rguenther@suse.de
Fri Jan 22 16:10:00 GMT 2010
This fixes the bogus aliasing we introduce for memcpy folding for C++
code and LTO. This allows fixing std::functional aliasing issues
using memcpy.
Other than C, C++ allows the dynamic type of an object with a declared
type to change. This is used both from our standard library
implementation and from its boost roots. While I can't find C++
standard wording on the effect of memcpy to the dynamic type of
an object with a declared type the only reasonable assumption is
that the dynamic type, if any, is transfered (which, surprisingly
leaves us with the GCC union type-punning way of doing
type-punning in C++).
For 4.6 I hope to get the folding back when it is safe, determined
by tracking dynamic type changes in a to-be-written alignment
tracking/propagation pass.
Bootstrap and regtest on x86_64-unknown-linux-gnu pending.
Ok?
Thanks,
Richard.
2010-01-22 Richard Guenther <rguenther@suse.de>
PR middle-end/42834
* c-opts.c (c_common_post_options): Adjust flag_strict_aliasing
to 2 if it was set for C++.
* builtins.c (fold_builtin_memory_op): Disable memcpy
inline-expansion for flag_strict_aliasing >= 2.
lto/
* lto-lang.c (lto_post_options): Use C++ strict-aliasing mode.
* g++.dg/torture/pr42834.C: New testcase.
Index: gcc/c-opts.c
===================================================================
*** gcc/c-opts.c (revision 156153)
--- gcc/c-opts.c (working copy)
*************** c_common_post_options (const char **pfil
*** 1060,1065 ****
--- 1060,1070 ----
if (flag_objc_exceptions && !flag_objc_sjlj_exceptions)
flag_exceptions = 1;
+ /* In C++ TBAA is less strict than in C as it allows the dynamic type
+ of objects with a declared type to change. */
+ if (c_dialect_cxx ())
+ flag_strict_aliasing = flag_strict_aliasing ? 2 : 0;
+
/* -Wextra implies the following flags
unless explicitly overridden. */
if (warn_type_limits == -1)
Index: gcc/builtins.c
===================================================================
*** gcc/builtins.c (revision 156153)
--- gcc/builtins.c (working copy)
*************** fold_builtin_memory_op (location_t loc,
*** 8244,8249 ****
--- 8244,8257 ----
return NULL_TREE;
}
+ /* The C++ standard allows the dynamic type of an object to be
+ different from its declared type, so memcpy has to transfer
+ the effective type even in that case. We can't do any
+ meaningful folding with the knowledge of just the memcpy
+ statement here in that case. */
+ if (flag_strict_aliasing >= 2)
+ return NULL_TREE;
+
if (!host_integerp (len, 0))
return NULL_TREE;
/* FIXME:
Index: gcc/testsuite/g++.dg/torture/pr42834.C
===================================================================
*** gcc/testsuite/g++.dg/torture/pr42834.C (revision 0)
--- gcc/testsuite/g++.dg/torture/pr42834.C (revision 0)
***************
*** 0 ****
--- 1,13 ----
+ // { dg-do run }
+
+ int main()
+ {
+ int i = 0;
+ float f = 1.0;
+ int *p = (int *)&f;
+ __builtin_memcpy (&i, p, 4);
+ if (*(float *)&i != 1.0)
+ __builtin_abort ();
+ return 0;
+ }
+
Index: gcc/lto/lto-lang.c
===================================================================
*** gcc/lto/lto-lang.c (revision 156153)
--- gcc/lto/lto-lang.c (working copy)
*************** lto_post_options (const char **pfilename
*** 674,679 ****
--- 674,682 ----
support. */
flag_excess_precision_cmdline = EXCESS_PRECISION_FAST;
+ /* Use the more stricter C++ mode. */
+ flag_strict_aliasing = flag_strict_aliasing ? 2 : 0;
+
lto_read_all_file_options ();
/* Initialize the compiler back end. */
More information about the Gcc-patches
mailing list