diff options
author | Artemiy Granat <a.granat@ispras.ru> | 2025-07-29 17:20:46 +0300 |
---|---|---|
committer | Alexander Monakov <amonakov@ispras.ru> | 2025-07-31 15:47:33 +0300 |
commit | ccead81bbc39668376eb5cf47066acb446cc43f3 (patch) | |
tree | 5757c9c2edbb80de5675d3903bab04a4ebc8c4c1 /gcc | |
parent | ff6f7d8e005ae94ffd55f1dba727e28531c3daf3 (diff) | |
download | gcc-ccead81bbc39668376eb5cf47066acb446cc43f3.zip gcc-ccead81bbc39668376eb5cf47066acb446cc43f3.tar.gz gcc-ccead81bbc39668376eb5cf47066acb446cc43f3.tar.bz2 |
i386: Ignore regparm attribute and warn for it in 64-bit mode
The regparm attribute does not affect code generation on x86-64 target.
Despite this, regparm was accepted silently, unlike other calling
convention attributes handled in the ix86_handle_cconv_attribute
function.
Due to lack of diagnostics, Linux kernel attempted to specify regparm(0)
on vmread_error_trampoline declaration, which is supposed to be invoked
with all arguments on stack:
https://lore.kernel.org/all/20220928232015.745948-1-seanjc@google.com/
To produce a warning for regparm in 64-bit mode, simply move the block
that produces diagnostics above the block that handles the regparm
attribute.
gcc/ChangeLog:
* config/i386/i386-options.cc (ix86_handle_cconv_attribute):
Move 64-bit mode check before regparm handling.
gcc/testsuite/ChangeLog:
* g++.dg/abi/regparm1.C: Require ia32 target.
* gcc.target/i386/20020224-1.c: Likewise.
* gcc.target/i386/pr103785.c: Use regparm attribute only if
not in 64-bit mode.
* gcc.target/i386/pr36533.c: Likewise.
* gcc.target/i386/pr59099.c: Likewise.
* gcc.target/i386/sibcall-8.c: Likewise.
* gcc.target/i386/sw-1.c: Likewise.
* gcc.target/i386/pr15184-2.c: Fix invalid comment.
* gcc.target/i386/attributes-ignore.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/config/i386/i386-options.cc | 24 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/abi/regparm1.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/20020224-1.c | 1 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/attributes-ignore.c | 8 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr103785.c | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr15184-2.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr36533.c | 24 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr59099.c | 9 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/sibcall-8.c | 14 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/sw-1.c | 5 |
10 files changed, 69 insertions, 25 deletions
diff --git a/gcc/config/i386/i386-options.cc b/gcc/config/i386/i386-options.cc index ca6bb83..1ae3df8 100644 --- a/gcc/config/i386/i386-options.cc +++ b/gcc/config/i386/i386-options.cc @@ -3615,6 +3615,18 @@ ix86_handle_cconv_attribute (tree *node, tree name, tree args, int, return NULL_TREE; } + if (TARGET_64BIT) + { + /* Do not warn when emulating the MS ABI. */ + if ((TREE_CODE (*node) != FUNCTION_TYPE + && TREE_CODE (*node) != METHOD_TYPE) + || ix86_function_type_abi (*node) != MS_ABI) + warning (OPT_Wattributes, "%qE attribute ignored", + name); + *no_add_attrs = true; + return NULL_TREE; + } + /* Can combine regparm with all attributes but fastcall, and thiscall. */ if (is_attribute_p ("regparm", name)) { @@ -3648,18 +3660,6 @@ ix86_handle_cconv_attribute (tree *node, tree name, tree args, int, return NULL_TREE; } - if (TARGET_64BIT) - { - /* Do not warn when emulating the MS ABI. */ - if ((TREE_CODE (*node) != FUNCTION_TYPE - && TREE_CODE (*node) != METHOD_TYPE) - || ix86_function_type_abi (*node) != MS_ABI) - warning (OPT_Wattributes, "%qE attribute ignored", - name); - *no_add_attrs = true; - return NULL_TREE; - } - /* Can combine fastcall with stdcall (redundant) and sseregparm. */ if (is_attribute_p ("fastcall", name)) { diff --git a/gcc/testsuite/g++.dg/abi/regparm1.C b/gcc/testsuite/g++.dg/abi/regparm1.C index c471046..3aae3dd 100644 --- a/gcc/testsuite/g++.dg/abi/regparm1.C +++ b/gcc/testsuite/g++.dg/abi/regparm1.C @@ -1,5 +1,5 @@ // PR c++/29911 (9381) -// { dg-do run { target i?86-*-* x86_64-*-* } } +// { dg-do run { target { { i?86-*-* x86_64-*-* } && ia32 } } } // { dg-require-effective-target c++11 } extern "C" int printf(const char *, ...); diff --git a/gcc/testsuite/gcc.target/i386/20020224-1.c b/gcc/testsuite/gcc.target/i386/20020224-1.c index 2905719..769332b 100644 --- a/gcc/testsuite/gcc.target/i386/20020224-1.c +++ b/gcc/testsuite/gcc.target/i386/20020224-1.c @@ -4,6 +4,7 @@ while callee was actually not poping it up (as the hidden argument was passed in register). */ /* { dg-do run } */ +/* { dg-require-effective-target ia32 } */ /* { dg-options "-O2 -fomit-frame-pointer" } */ extern void abort (void); diff --git a/gcc/testsuite/gcc.target/i386/attributes-ignore.c b/gcc/testsuite/gcc.target/i386/attributes-ignore.c new file mode 100644 index 0000000..93a3770 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/attributes-ignore.c @@ -0,0 +1,8 @@ +/* { dg-do compile { target { ! ia32 } } } */ + +void foo1(int i, int j) __attribute__((regparm(0))); /* { dg-warning "ignored" } */ +void foo2(int i, int j) __attribute__((stdcall)); /* { dg-warning "ignored" } */ +void foo3(int i, int j) __attribute__((fastcall)); /* { dg-warning "ignored" } */ +void foo4(int i, int j) __attribute__((cdecl)); /* { dg-warning "ignored" } */ +void foo5(int i, int j) __attribute__((thiscall)); /* { dg-warning "ignored" } */ +void foo6(int i, int j) __attribute__((sseregparm)); /* { dg-warning "ignored" } */ diff --git a/gcc/testsuite/gcc.target/i386/pr103785.c b/gcc/testsuite/gcc.target/i386/pr103785.c index 5503b96..49d6c56 100644 --- a/gcc/testsuite/gcc.target/i386/pr103785.c +++ b/gcc/testsuite/gcc.target/i386/pr103785.c @@ -11,7 +11,10 @@ struct wrapper_t struct wrapper_t **table; -__attribute__ ((weak, regparm (2))) +#ifndef __x86_64__ +__attribute__ ((regparm (2))) +#endif +__attribute__ ((weak)) void update (long k, long e) { diff --git a/gcc/testsuite/gcc.target/i386/pr15184-2.c b/gcc/testsuite/gcc.target/i386/pr15184-2.c index cb8201f..dd50c42 100644 --- a/gcc/testsuite/gcc.target/i386/pr15184-2.c +++ b/gcc/testsuite/gcc.target/i386/pr15184-2.c @@ -1,4 +1,4 @@ -/* PR 15184 second two tests +/* PR 15184 second two tests */ /* { dg-do compile { target ia32 } } */ /* { dg-options "-O2 -march=pentiumpro" } */ /* { dg-additional-options "-fno-PIE" { target ia32 } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr36533.c b/gcc/testsuite/gcc.target/i386/pr36533.c index 8d71ece..8699d26 100644 --- a/gcc/testsuite/gcc.target/i386/pr36533.c +++ b/gcc/testsuite/gcc.target/i386/pr36533.c @@ -55,14 +55,22 @@ typedef struct S1 *s18; } S7; -__attribute__((regparm (3), noinline)) int +#ifndef __x86_64__ +__attribute__((regparm (3))) +#endif +__attribute__((noinline)) +int fn1 (const char *x, void *y, S1 *z) { asm volatile ("" : : : "memory"); return *x + (y != 0); } -__attribute__((regparm (3), noinline)) int +#ifndef __x86_64__ +__attribute__((regparm (3))) +#endif +__attribute__((noinline)) +int fn2 (const char *x, int y, S2 *z) { asm volatile ("" : : : "memory"); @@ -84,7 +92,11 @@ fn3 (S3 *p) return (S3 *) ((char *) p + fn4 (p->s9)); } -__attribute__((regparm (3), noinline)) int +#ifndef __x86_64__ +__attribute__((regparm (3))) +#endif +__attribute__((noinline)) +int fn5 (void) { asm volatile ("" : : : "memory"); @@ -116,7 +128,11 @@ fn6 (S3 *w, int x, S2 *y, S4 *z) return a; } -__attribute__((regparm (3), noinline)) unsigned int +#ifndef __x86_64__ +__attribute__((regparm (3))) +#endif +__attribute__((noinline)) +unsigned int test (void *u, S6 *v, S1 **w, S7 *x, S2 *y, S1 *z) { unsigned b = v->s17->s16; diff --git a/gcc/testsuite/gcc.target/i386/pr59099.c b/gcc/testsuite/gcc.target/i386/pr59099.c index cf4a8da..21dfbc2 100644 --- a/gcc/testsuite/gcc.target/i386/pr59099.c +++ b/gcc/testsuite/gcc.target/i386/pr59099.c @@ -13,10 +13,17 @@ struct s }; -void* f (struct s *, struct s *) __attribute__ ((noinline, regparm(1))); +void* f (struct s *, struct s *) +#ifndef __x86_64__ +__attribute__ ((regparm(1))) +#endif +__attribute__ ((noinline)) +; void* +#ifndef __x86_64__ __attribute__ ((regparm(1))) +#endif f (struct s *p, struct s *p2) { void *gp, *gp1; diff --git a/gcc/testsuite/gcc.target/i386/sibcall-8.c b/gcc/testsuite/gcc.target/i386/sibcall-8.c index 3ab3809..29ebfe5 100644 --- a/gcc/testsuite/gcc.target/i386/sibcall-8.c +++ b/gcc/testsuite/gcc.target/i386/sibcall-8.c @@ -1,23 +1,29 @@ /* { dg-do run } */ /* { dg-options "-O2" } */ +#ifndef __x86_64__ +#define REGPARM __attribute__((regparm(1))) +#else +#define REGPARM +#endif + extern void abort (void); -static int __attribute__((regparm(1))) +static int REGPARM bar(void *arg) { return arg != bar; } -static int __attribute__((noinline,noclone,regparm(1))) -foo(int (__attribute__((regparm(1))) **bar)(void*)) +static int __attribute__((noinline,noclone)) REGPARM +foo(int (REGPARM **bar)(void*)) { return (*bar)(*bar); } int main() { - int (__attribute__((regparm(1))) *p)(void*) = bar; + int (REGPARM *p)(void*) = bar; if (foo(&p)) abort(); return 0; diff --git a/gcc/testsuite/gcc.target/i386/sw-1.c b/gcc/testsuite/gcc.target/i386/sw-1.c index 14db3ce..025f0e1 100644 --- a/gcc/testsuite/gcc.target/i386/sw-1.c +++ b/gcc/testsuite/gcc.target/i386/sw-1.c @@ -7,7 +7,10 @@ int c; int x[2000]; -__attribute__((regparm(1))) void foo (int a, int b) +#ifndef __x86_64__ +__attribute__((regparm(1))) +#endif +void foo (int a, int b) { int t[200]; if (a == 0 || c == 0) |