From ea2edf88eec93dd0ec532d2e837a7ac1bf62a1c2 Mon Sep 17 00:00:00 2001 From: Richard Guenther Date: Mon, 22 Feb 2010 15:53:27 +0000 Subject: [PATCH] re PR middle-end/43045 ([lto] ICE non-trivial conversion at assignment) 2010-02-22 Richard Guenther PR lto/43045 * tree-inline.c (declare_return_variable): Use the type of the call stmt lhs if available. * gfortran.dg/lto/20100222-1_0.f03: New testcase. * gfortran.dg/lto/20100222-1_1.c: Likewise. From-SVN: r156966 --- gcc/ChangeLog | 6 ++++ gcc/testsuite/ChangeLog | 6 ++++ .../gfortran.dg/lto/20100222-1_0.f03 | 35 +++++++++++++++++++ gcc/testsuite/gfortran.dg/lto/20100222-1_1.c | 25 +++++++++++++ gcc/tree-inline.c | 9 ++++- 5 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gfortran.dg/lto/20100222-1_0.f03 create mode 100644 gcc/testsuite/gfortran.dg/lto/20100222-1_1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cb5b113c0f9..b0ab9cd9132 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2010-02-22 Richard Guenther + + PR lto/43045 + * tree-inline.c (declare_return_variable): Use the type of + the call stmt lhs if available. + 2010-02-22 Duncan Sands * passes.c (register_pass): Always consider all pass lists when diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3f89fd36f7f..04cbe4571a2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2010-02-22 Richard Guenther + + PR lto/43045 + * gfortran.dg/lto/20100222-1_0.f03: New testcase. + * gfortran.dg/lto/20100222-1_1.c: Likewise. + 2010-02-22 Richard Guenther PR tree-optimization/42749 diff --git a/gcc/testsuite/gfortran.dg/lto/20100222-1_0.f03 b/gcc/testsuite/gfortran.dg/lto/20100222-1_0.f03 new file mode 100644 index 00000000000..fece7815430 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/lto/20100222-1_0.f03 @@ -0,0 +1,35 @@ +! { dg-lto-do run } +! This testcase tests c_funloc and c_funptr from iso_c_binding. It uses +! functions defined in c_funloc_tests_3_funcs.c. +module c_funloc_tests_3 + implicit none +contains + function ffunc(j) bind(c) + use iso_c_binding, only: c_funptr, c_int + integer(c_int) :: ffunc + integer(c_int), value :: j + ffunc = -17*j + end function ffunc +end module c_funloc_tests_3 +program main + use iso_c_binding, only: c_funptr, c_funloc + use c_funloc_tests_3, only: ffunc + implicit none + interface + function returnFunc() bind(c,name="returnFunc") + use iso_c_binding, only: c_funptr + type(c_funptr) :: returnFunc + end function returnFunc + subroutine callFunc(func,pass,compare) bind(c,name="callFunc") + use iso_c_binding, only: c_funptr, c_int + type(c_funptr), value :: func + integer(c_int), value :: pass,compare + end subroutine callFunc + end interface + type(c_funptr) :: p + p = returnFunc() + call callFunc(p, 13,3*13) + p = c_funloc(ffunc) + call callFunc(p, 21,-17*21) +end program main +! { dg-final { cleanup-modules "c_funloc_tests_3" } } diff --git a/gcc/testsuite/gfortran.dg/lto/20100222-1_1.c b/gcc/testsuite/gfortran.dg/lto/20100222-1_1.c new file mode 100644 index 00000000000..994da0a505d --- /dev/null +++ b/gcc/testsuite/gfortran.dg/lto/20100222-1_1.c @@ -0,0 +1,25 @@ +/* These functions support the test case c_funloc_tests_3. */ +#include +#include + +int printIntC(int i) +{ + return 3*i; +} + +int (*returnFunc(void))(int) +{ + return &printIntC; +} + +void callFunc(int(*func)(int), int pass, int compare) +{ + int result = (*func)(pass); + if(result != compare) + { + printf("FAILED: Got %d, expected %d\n", result, compare); + abort(); + } + else + printf("SUCCESS: Got %d, expected %d\n", result, compare); +} diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 9c560b1056c..de8ca707ce2 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -2542,9 +2542,16 @@ declare_return_variable (copy_body_data *id, tree return_slot, tree modify_dest) tree caller = id->dst_fn; tree result = DECL_RESULT (callee); tree callee_type = TREE_TYPE (result); - tree caller_type = TREE_TYPE (TREE_TYPE (callee)); + tree caller_type; tree var, use; + /* Handle type-mismatches in the function declaration return type + vs. the call expression. */ + if (modify_dest) + caller_type = TREE_TYPE (modify_dest); + else + caller_type = TREE_TYPE (TREE_TYPE (callee)); + /* We don't need to do anything for functions that don't return anything. */ if (!result || VOID_TYPE_P (callee_type))