aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorKugan Vivekanandarajah <kuganv@linaro.org>2015-11-22 23:07:58 +0000
committerKugan Vivekanandarajah <kugan@gcc.gnu.org>2015-11-22 23:07:58 +0000
commitc6392c416d5d794fff4f8b3d51e5f9248a5a5bf2 (patch)
tree55f2f883214379511399e4b40061339fb37d2209 /gcc
parentcfba61d25c4acaa74c352c492150e197a4cafcba (diff)
downloadgcc-c6392c416d5d794fff4f8b3d51e5f9248a5a5bf2.zip
gcc-c6392c416d5d794fff4f8b3d51e5f9248a5a5bf2.tar.gz
gcc-c6392c416d5d794fff4f8b3d51e5f9248a5a5bf2.tar.bz2
re PR target/68390 (Incorrect code due to indirect tail call of varargs function with hard float ABI)
gcc/ChangeLog: 2015-11-23 Kugan Vivekanandarajah <kuganv@linaro.org> PR target/68390 * config/arm/arm.c (arm_function_ok_for_sibcall): Get function type for indirect function call. gcc/testsuite/ChangeLog: 2015-11-23 Kugan Vivekanandarajah <kuganv@linaro.org> PR target/68390 * gcc/testsuite/gcc.c-torture/execute/pr68390.c: New test. From-SVN: r230730
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/arm/arm.c7
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr68390.c27
4 files changed, 44 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 51e0707..c584fd9 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2015-11-23 Kugan Vivekanandarajah <kuganv@linaro.org>
+
+ PR target/68390
+ * config/arm/arm.c (arm_function_ok_for_sibcall): Get function type
+ for indirect function call.
+
2015-11-22 Bilyan Borisov <bilyan.borisov@arm.com>
* config/aarch64/aarch64-simd.md
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 290b537..e0cdc20 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -6686,8 +6686,13 @@ arm_function_ok_for_sibcall (tree decl, tree exp)
a VFP register but then need to transfer it to a core
register. */
rtx a, b;
+ tree decl_or_type = decl;
- a = arm_function_value (TREE_TYPE (exp), decl, false);
+ /* If it is an indirect function pointer, get the function type. */
+ if (!decl)
+ decl_or_type = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (exp)));
+
+ a = arm_function_value (TREE_TYPE (exp), decl_or_type, false);
b = arm_function_value (TREE_TYPE (DECL_RESULT (cfun->decl)),
cfun->decl, false);
if (!rtx_equal_p (a, b))
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 7163326..3074642 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2015-11-23 Kugan Vivekanandarajah <kuganv@linaro.org>
+
+ PR target/68390
+ * gcc/testsuite/gcc.c-torture/execute/pr68390.c: New test.
+
2015-11-22 Jerry DeLisle <jvdelisle@gcc.gnu.org>
* gfortran.dg/fmt_g0_1.f08: Update test. Leading zero.
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr68390.c b/gcc/testsuite/gcc.c-torture/execute/pr68390.c
new file mode 100644
index 0000000..86f07fe
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr68390.c
@@ -0,0 +1,27 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+__attribute__ ((noinline))
+double direct(int x, ...)
+{
+ return x*x;
+}
+
+__attribute__ ((noinline))
+double broken(double (*indirect)(int x, ...), int v)
+{
+ return indirect(v);
+}
+
+int main ()
+{
+ double d1, d2;
+ int i = 2;
+ d1 = broken (direct, i);
+ if (d1 != i*i)
+ {
+ __builtin_abort ();
+ }
+ return 0;
+}
+