aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/lto-streamer-out.c2
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/g++.dg/lto/20101020-1_0.C8
-rw-r--r--gcc/testsuite/g++.dg/lto/20101020-1_0.h23
-rw-r--r--gcc/testsuite/g++.dg/lto/20101020-1_1.C11
-rw-r--r--gcc/tree-cfg.c11
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)))
{