diff options
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/lto-streamer-out.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/lto/20101020-1_0.C | 8 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/lto/20101020-1_0.h | 23 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/lto/20101020-1_1.C | 11 | ||||
-rw-r--r-- | gcc/tree-cfg.c | 11 |
7 files changed, 66 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9845453..a10ba68 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2010-10-20 Richard Guenther <rguenther@suse.de> + + PR lto/45667 + * lto-streamer-out.c (output_gimple_stmt): Fix typo. + * tree-cfg.c (verify_gimple_call): Properly get the call fndecl. + (verify_gimple_assign_single): Disable ADDR_EXPR type check + when in LTO. + 2010-10-20 Vladimir Makarov <vmakarov@redhat.com> PR fortran/42169 diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c index 03b4f39..03150b7 100644 --- a/gcc/lto-streamer-out.c +++ b/gcc/lto-streamer-out.c @@ -1763,7 +1763,7 @@ output_gimple_stmt (struct output_block *ob, gimple stmt) if (op) { tree *basep = &op; - if (handled_component_p (*basep)) + while (handled_component_p (*basep)) basep = &TREE_OPERAND (*basep, 0); if (TREE_CODE (*basep) == VAR_DECL && !auto_var_in_fn_p (*basep, current_function_decl)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f69e743..519f7a7 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2010-10-20 Richard Guenther <rguenther@suse.de> + + PR lto/45667 + * g++.dg/lto/20101020-1_0.h: New testcase. + * g++.dg/lto/20101020-1_0.C: Likewise. + * g++.dg/lto/20101020-1_1.C: Likewise. + 2010-10-20 Dmitry Melnik <dm@ispras.ru> * gcc.dg/20101013-1.c: New test. diff --git a/gcc/testsuite/g++.dg/lto/20101020-1_0.C b/gcc/testsuite/g++.dg/lto/20101020-1_0.C new file mode 100644 index 0000000..e92bcf8 --- /dev/null +++ b/gcc/testsuite/g++.dg/lto/20101020-1_0.C @@ -0,0 +1,8 @@ +// { dg-lto-do link } + +#include "20101020-1_0.h" +A::A () +{ + foo (&A::bar); +} +int main() { return 0; } diff --git a/gcc/testsuite/g++.dg/lto/20101020-1_0.h b/gcc/testsuite/g++.dg/lto/20101020-1_0.h new file mode 100644 index 0000000..2de1d3c --- /dev/null +++ b/gcc/testsuite/g++.dg/lto/20101020-1_0.h @@ -0,0 +1,23 @@ +struct A; +typedef void (A::*Am1) (void *); +typedef void (A::*Am2) (); + +struct B +{ + Am2 am2; +}; + +struct A +{ + A (); + struct B b; + struct C *c; + struct D *d; + void foo (Am1); + void bar (void *); +}; + +struct C +{ +}; + diff --git a/gcc/testsuite/g++.dg/lto/20101020-1_1.C b/gcc/testsuite/g++.dg/lto/20101020-1_1.C new file mode 100644 index 0000000..5c83fbf --- /dev/null +++ b/gcc/testsuite/g++.dg/lto/20101020-1_1.C @@ -0,0 +1,11 @@ +#include "20101020-1_0.h" +struct D +{ +}; +void A::bar (void *) +{ +} +void A::foo (Am1) +{ +} + diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index ff0c2ad..bffa679 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -3107,8 +3107,7 @@ verify_gimple_call (gimple stmt) call, and the decl should have DECL_STATIC_CHAIN set. */ if (gimple_call_chain (stmt)) { - if (TREE_CODE (fn) != ADDR_EXPR - || TREE_CODE (TREE_OPERAND (fn, 0)) != FUNCTION_DECL) + if (!gimple_call_fndecl (stmt)) { error ("static chain in indirect gimple call"); return true; @@ -3698,7 +3697,13 @@ verify_gimple_assign_single (gimple stmt) return true; } - if (!types_compatible_p (TREE_TYPE (op), TREE_TYPE (TREE_TYPE (rhs1))) + /* Technically there is no longer a need for matching types, but + gimple hygiene asks for this check. In LTO we can end up + combining incompatible units and thus end up with addresses + of globals that change their type to a common one. */ + if (!in_lto_p + && !types_compatible_p (TREE_TYPE (op), + TREE_TYPE (TREE_TYPE (rhs1))) && !one_pointer_to_useless_type_conversion_p (TREE_TYPE (rhs1), TREE_TYPE (op))) { |