1 From 9238e38f62f9cd2b2af5c4bc1949497a1a47714b Mon Sep 17 00:00:00 2001
2 From: Richard Lowe <richlowe@richlowe.net>
3 Date: Sat, 27 Oct 2012 02:44:09 +0100
4 Subject: Implement -fstrict-calling-conventions
6 Stock GCC is overly willing to violate the ABI when calling local functions,
7 such that it passes arguments in registers on i386. This hampers debugging
8 with anything other than a fully-aware DWARF debugger, and is generally not
11 Implement a flag which disables this behaviour, enabled by default. The flag is
12 global, though only effective on i386, to more easily allow its globalization
13 later which, given the odds, is likely to be necessary.
15 gcc/common.opt | 4 ++++
16 gcc/config/i386/i386.c | 2 ++
17 gcc/doc/invoke.texi | 6 ++++++
18 gcc/testsuite/gcc.target/i386/local.c | 3 ++-
19 gcc/testsuite/gcc.target/i386/strict-cc.c | 24 +++++++++++++++++++++++
20 5 files changed, 38 insertions(+), 1 deletion(-)
21 create mode 100644 gcc/testsuite/gcc.target/i386/strict-cc.c
23 diff --git a/gcc/common.opt b/gcc/common.opt
24 index a75b44ee47e..6dfce7eb42d 100644
27 @@ -2658,6 +2658,10 @@ fstrict-aliasing
28 Common Var(flag_strict_aliasing) Optimization
29 Assume strict aliasing rules apply.
31 +fstrict-calling-conventions
32 +Common Var(flag_strict_calling_conventions) Init(1)
33 +Use strict ABI calling conventions even for static functions
37 Treat signed overflow as undefined. Negated as -fwrapv -fwrapv-pointer.
38 diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
39 index 5a7bc8c44a8..9d02aad9e13 100644
40 --- a/gcc/config/i386/i386.c
41 +++ b/gcc/config/i386/i386.c
43 and callee not, or vice versa. Instead look at whether the callee
44 is optimized or not. */
45 if (target && opt_for_fn (target->decl, optimize)
46 + && !flag_strict_calling_conventions
47 && !(profile_flag && !flag_fentry))
49 if (target->local && target->can_change_signature)
52 && (target_opts_for_fn (target->decl)->x_ix86_fpmath & FPMATH_SSE)
53 && opt_for_fn (target->decl, optimize)
54 + && !flag_strict_calling_conventions
55 && !(profile_flag && !flag_fentry))
57 if (target->local && target->can_change_signature)
58 diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
59 index 7f13ffb79e1..7cb80dc7346 100644
60 --- a/gcc/doc/invoke.texi
61 +++ b/gcc/doc/invoke.texi
62 @@ -7034,6 +7034,12 @@
63 Only warns when the converted pointer is dereferenced.
64 Does not warn about incomplete types.
66 +@item -fstrict-calling-conventions
67 +@opindex fstrict-calling-conventions
68 +Use strict ABI calling conventions even with local functions.
69 +This disable certain optimizations that may cause GCC to call local
70 +functions in a manner other than that described by the ABI.
72 @item -Wstrict-overflow
73 @itemx -Wstrict-overflow=@var{n}
74 @opindex Wstrict-overflow
75 diff --git a/gcc/testsuite/gcc.target/i386/local.c b/gcc/testsuite/gcc.target/i386/local.c
76 index f4444951e12..3a487583d81 100644
77 --- a/gcc/testsuite/gcc.target/i386/local.c
78 +++ b/gcc/testsuite/gcc.target/i386/local.c
80 /* { dg-do compile } */
81 -/* { dg-options "-O2 -funit-at-a-time" } */
82 +/* { dg-options "-O2 -funit-at-a-time -fno-strict-calling-conventions" { target ia32 } } */
83 +/* { dg-options "-O2 -funit-at-a-time" { target lp64 } } */
84 /* { dg-final { scan-assembler "magic\[^\\n\]*eax" { target ia32 } } } */
85 /* { dg-final { scan-assembler "magic\[^\\n\]*(edi|ecx)" { target { ! ia32 } } } } */
87 diff --git a/gcc/testsuite/gcc.target/i386/strict-cc.c b/gcc/testsuite/gcc.target/i386/strict-cc.c
89 index 00000000000..fa0543e52ff
91 +++ b/gcc/testsuite/gcc.target/i386/strict-cc.c
93 +/* { dg-do compile { target { ilp32 } } } */
94 +/* { dg-options "-O2 -funit-at-a-time -fstrict-calling-conventions" } */
95 +/* { dg-final { scan-assembler "pushl.*\\\$1" } } */
96 +/* { dg-final { scan-assembler "pushl.*\\\$2" } } */
97 +/* { dg-final { scan-assembler "pushl.*\\\$3" } } */
98 +/* { dg-final { scan-assembler "pushl.*\\\$4" } } */
99 +/* { dg-final { scan-assembler "pushl.*\\\$5" } } */
103 +/* Verify that local calling convention is not used if strict conventions. */
104 +static int t(int, int, int, int, int) __attribute__ ((noinline));
113 +t(int a, int b, int c, int d, int e)
115 + printf("%d\n", a, b, c, d, e);