diff options
author | Jakub Jelinek <jakub@redhat.com> | 2020-04-29 22:38:01 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2020-04-29 22:38:01 +0200 |
commit | 48e54fea7ba4a7cb7b3d1505951383120220e394 (patch) | |
tree | 2ef2723eb255443976a306a383c44f7e6026c052 /gcc | |
parent | 8f1591763fd50b143af0dc1770741f326a97583a (diff) | |
download | gcc-48e54fea7ba4a7cb7b3d1505951383120220e394.zip gcc-48e54fea7ba4a7cb7b3d1505951383120220e394.tar.gz gcc-48e54fea7ba4a7cb7b3d1505951383120220e394.tar.bz2 |
s390: Fix up -Wpsabi diagnostics + [[no_unique_address]] empty member fix [PR94704]
So, based on the yesterday's discussions, similarly to powerpc64le-linux
I've done some testing for s390x-linux too.
First of all, I found a bug in my patch from yesterday, it was printing
the wrong type like 'double' etc. rather than the class that contained such
the element. Fix below.
For s390x-linux, I was using
struct X { };
struct Y { int : 0; };
struct Z { int : 0; Y y; };
struct U : public X { X q; };
struct A { double a; };
struct B : public X { double a; };
struct C : public Y { double a; };
struct D : public Z { double a; };
struct E : public U { double a; };
struct F { [[no_unique_address]] X x; double a; };
struct G { [[no_unique_address]] Y y; double a; };
struct H { [[no_unique_address]] Z z; double a; };
struct I { [[no_unique_address]] U u; double a; };
struct J { double a; [[no_unique_address]] X x; };
struct K { double a; [[no_unique_address]] Y y; };
struct L { double a; [[no_unique_address]] Z z; };
struct M { double a; [[no_unique_address]] U u; };
#define T(S, s) extern S s; extern void foo##s (S); int bar##s () { foo##s (s); return 0; }
T (A, a)
T (B, b)
T (C, c)
T (D, d)
T (E, e)
T (F, f)
T (G, g)
T (H, h)
T (I, i)
T (J, j)
T (K, k)
T (L, l)
T (M, m)
as testcase and looking for "\tld\t%f0,".
While g++ 9 with -std=c++17 used to pass in fpr just
A, g++ 9 -std=c++14, as well as current trunk -std=c++14 & 17
and clang++ from today -std=c++14 & 17 all pass A, B, C
in fpr and nothing else. The intent stated by Jason seems to be
that A, B, C, F, G, J, K should all be passed in fpr.
Attached are two (updated) versions of the patch on top of the
powerpc+middle-end patch just posted.
The first one emits two separate -Wpsabi warnings like powerpc, one for
the -std=c++14 vs. -std=c++17 ABI difference and one for GCC 9 vs. 10
[[no_unique_address]] passing changes, the other one is silent about the
second case.
2020-04-29 Jakub Jelinek <jakub@redhat.com>
PR target/94704
* config/s390/s390.c (s390_function_arg_vector,
s390_function_arg_float): Use DECL_FIELD_ABI_IGNORED instead of
cxx17_empty_base_field_p. In -Wpsabi diagnostics use the type
passed to the function rather than the type of the single element.
Rename cxx17_empty_base_seen variable to empty_base_seen, change
type to int, and adjust diagnostics depending on if the field
has [[no_unique_attribute]] or not.
* g++.target/s390/s390.exp: New file.
* g++.target/s390/pr94704-1.C: New test.
* g++.target/s390/pr94704-2.C: New test.
* g++.target/s390/pr94704-3.C: New test.
* g++.target/s390/pr94704-4.C: New test.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/config/s390/s390.c | 56 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/testsuite/g++.target/s390/pr94704-1.C | 38 | ||||
-rw-r--r-- | gcc/testsuite/g++.target/s390/pr94704-2.C | 34 | ||||
-rw-r--r-- | gcc/testsuite/g++.target/s390/pr94704-3.C | 40 | ||||
-rw-r--r-- | gcc/testsuite/g++.target/s390/pr94704-4.C | 34 | ||||
-rw-r--r-- | gcc/testsuite/g++.target/s390/s390.exp | 44 |
8 files changed, 248 insertions, 16 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 72e38d8..60f9cd4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,14 @@ 2020-04-29 Jakub Jelinek <jakub@redhat.com> + PR target/94704 + * config/s390/s390.c (s390_function_arg_vector, + s390_function_arg_float): Use DECL_FIELD_ABI_IGNORED instead of + cxx17_empty_base_field_p. In -Wpsabi diagnostics use the type + passed to the function rather than the type of the single element. + Rename cxx17_empty_base_seen variable to empty_base_seen, change + type to int, and adjust diagnostics depending on if the field + has [[no_unique_attribute]] or not. + PR target/94832 * config/i386/avx512bwintrin.h (_mm512_alignr_epi8, _mm512_mask_alignr_epi8, _mm512_maskz_alignr_epi8): Wrap macro operands diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 50994bc..74b490a 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -11911,7 +11911,8 @@ s390_function_arg_vector (machine_mode mode, const_tree type) /* The ABI says that record types with a single member are treated just like that member would be. */ - bool cxx17_empty_base_seen = false; + int empty_base_seen = 0; + const_tree orig_type = type; while (TREE_CODE (type) == RECORD_TYPE) { tree field, single = NULL_TREE; @@ -11921,9 +11922,13 @@ s390_function_arg_vector (machine_mode mode, const_tree type) if (TREE_CODE (field) != FIELD_DECL) continue; - if (cxx17_empty_base_field_p (field)) + if (DECL_FIELD_ABI_IGNORED (field)) { - cxx17_empty_base_seen = true; + if (lookup_attribute ("no_unique_address", + DECL_ATTRIBUTES (field))) + empty_base_seen |= 2; + else + empty_base_seen |= 1; continue; } @@ -11949,16 +11954,23 @@ s390_function_arg_vector (machine_mode mode, const_tree type) if (!VECTOR_TYPE_P (type)) return false; - if (warn_psabi && cxx17_empty_base_seen) + if (warn_psabi && empty_base_seen) { static unsigned last_reported_type_uid; - unsigned uid = TYPE_UID (TYPE_MAIN_VARIANT (type)); + unsigned uid = TYPE_UID (TYPE_MAIN_VARIANT (orig_type)); if (uid != last_reported_type_uid) { last_reported_type_uid = uid; - inform (input_location, "parameter passing for argument of type " - "%qT when C++17 is enabled changed to match " - "C++14 in GCC 10.1", type); + if (empty_base_seen & 1) + inform (input_location, + "parameter passing for argument of type %qT when C++17 " + "is enabled changed to match C++14 in GCC 10.1", + orig_type); + else + inform (input_location, + "parameter passing for argument of type %qT with " + "%<[[no_unique_address]]%> members changed in GCC 10.1", + orig_type); } } return true; @@ -11983,7 +11995,8 @@ s390_function_arg_float (machine_mode mode, const_tree type) /* The ABI says that record types with a single member are treated just like that member would be. */ - bool cxx17_empty_base_seen = false; + int empty_base_seen = 0; + const_tree orig_type = type; while (TREE_CODE (type) == RECORD_TYPE) { tree field, single = NULL_TREE; @@ -11992,9 +12005,13 @@ s390_function_arg_float (machine_mode mode, const_tree type) { if (TREE_CODE (field) != FIELD_DECL) continue; - if (cxx17_empty_base_field_p (field)) + if (DECL_FIELD_ABI_IGNORED (field)) { - cxx17_empty_base_seen = true; + if (lookup_attribute ("no_unique_address", + DECL_ATTRIBUTES (field))) + empty_base_seen |= 2; + else + empty_base_seen |= 1; continue; } @@ -12013,16 +12030,23 @@ s390_function_arg_float (machine_mode mode, const_tree type) if (TREE_CODE (type) != REAL_TYPE) return false; - if (warn_psabi && cxx17_empty_base_seen) + if (warn_psabi && empty_base_seen) { static unsigned last_reported_type_uid; - unsigned uid = TYPE_UID (TYPE_MAIN_VARIANT (type)); + unsigned uid = TYPE_UID (TYPE_MAIN_VARIANT (orig_type)); if (uid != last_reported_type_uid) { last_reported_type_uid = uid; - inform (input_location, "parameter passing for argument of type " - "%qT when C++17 is enabled changed to match " - "C++14 in GCC 10.1", type); + if (empty_base_seen & 1) + inform (input_location, + "parameter passing for argument of type %qT when C++17 " + "is enabled changed to match C++14 in GCC 10.1", + orig_type); + else + inform (input_location, + "parameter passing for argument of type %qT with " + "%<[[no_unique_address]]%> members changed in GCC 10.1", + orig_type); } } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0fce8fb..9bc4723 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2020-04-29 Jakub Jelinek <jakub@redhat.com> + + PR target/94704 + * g++.target/s390/s390.exp: New file. + * g++.target/s390/pr94704-1.C: New test. + * g++.target/s390/pr94704-2.C: New test. + * g++.target/s390/pr94704-3.C: New test. + * g++.target/s390/pr94704-4.C: New test. + 2020-04-29 Patrick Palka <ppalka@redhat.com> PR c++/94830 diff --git a/gcc/testsuite/g++.target/s390/pr94704-1.C b/gcc/testsuite/g++.target/s390/pr94704-1.C new file mode 100644 index 0000000..56675f2 --- /dev/null +++ b/gcc/testsuite/g++.target/s390/pr94704-1.C @@ -0,0 +1,38 @@ +// PR target/94704 +// { dg-do compile } +// { dg-options "-O2 -std=c++14" } +// Test that for all the calls in this testcase the C++17 empty base +// artificial fields and [[no_unique_address]] empty class non-static +// data members are ignored in the decision whether passed arguments +// have a single floating point field. +// { dg-final { scan-assembler-times {(?n)^\s+ld\s+%f0,} 7 } } + +struct X { }; +struct Y { int : 0; }; +struct Z { int : 0; Y y; }; +struct U : public X { X q; }; +struct A { double a; }; +struct B : public X { double a; }; +struct C : public Y { double a; }; +struct D : public Z { double a; }; +struct E : public U { double a; }; +struct F { [[no_unique_address]] X x; double a; }; +struct G { [[no_unique_address]] Y y; double a; }; +struct H { [[no_unique_address]] Z z; double a; }; +struct I { [[no_unique_address]] U u; double a; }; +struct J { double a; [[no_unique_address]] X x; }; +struct K { double a; [[no_unique_address]] Y y; }; +struct L { double a; [[no_unique_address]] Z z; }; +struct M { double a; [[no_unique_address]] U u; }; +#define T(S, s) extern S s; extern void foo##s (S); int bar##s () { foo##s (s); return 0; } +// { dg-message "parameter passing for argument of type 'F' with '\\\[\\\[no_unique_address\\\]\\\]' members changed in GCC 10.1" "" { target *-*-* } .-1 } +// { dg-message "parameter passing for argument of type 'G' with '\\\[\\\[no_unique_address\\\]\\\]' members changed in GCC 10.1" "" { target *-*-* } .-2 } +// { dg-message "parameter passing for argument of type 'J' with '\\\[\\\[no_unique_address\\\]\\\]' members changed in GCC 10.1" "" { target *-*-* } .-3 } +// { dg-message "parameter passing for argument of type 'K' with '\\\[\\\[no_unique_address\\\]\\\]' members changed in GCC 10.1" "" { target *-*-* } .-4 } +T (A, a) +T (B, b) +T (C, c) +T (F, f) +T (G, g) +T (J, j) +T (K, k) diff --git a/gcc/testsuite/g++.target/s390/pr94704-2.C b/gcc/testsuite/g++.target/s390/pr94704-2.C new file mode 100644 index 0000000..087c877 --- /dev/null +++ b/gcc/testsuite/g++.target/s390/pr94704-2.C @@ -0,0 +1,34 @@ +// PR target/94704 +// { dg-do compile } +// { dg-options "-O2 -std=c++14" } +// Test that for no calls in this testcase the C++17 empty base +// artificial fields and [[no_unique_address]] empty class non-static +// data members are ignored in the decision whether passed arguments +// have a single floating point field. +// { dg-final { scan-assembler-not {(?n)^\s+ld\s+%f0,} } } + +struct X { }; +struct Y { int : 0; }; +struct Z { int : 0; Y y; }; +struct U : public X { X q; }; +struct A { double a; }; +struct B : public X { double a; }; +struct C : public Y { double a; }; +struct D : public Z { double a; }; +struct E : public U { double a; }; +struct F { [[no_unique_address]] X x; double a; }; +struct G { [[no_unique_address]] Y y; double a; }; +struct H { [[no_unique_address]] Z z; double a; }; +struct I { [[no_unique_address]] U u; double a; }; +struct J { double a; [[no_unique_address]] X x; }; +struct K { double a; [[no_unique_address]] Y y; }; +struct L { double a; [[no_unique_address]] Z z; }; +struct M { double a; [[no_unique_address]] U u; }; +#define T(S, s) extern S s; extern void foo##s (S); int bar##s () { foo##s (s); return 0; } +// { dg-bogus "parameter passing for argument of type" } +T (D, d) +T (E, e) +T (H, h) +T (I, i) +T (L, l) +T (M, m) diff --git a/gcc/testsuite/g++.target/s390/pr94704-3.C b/gcc/testsuite/g++.target/s390/pr94704-3.C new file mode 100644 index 0000000..7e656fb --- /dev/null +++ b/gcc/testsuite/g++.target/s390/pr94704-3.C @@ -0,0 +1,40 @@ +// PR target/94704 +// { dg-do compile } +// { dg-options "-O2 -std=c++17" } +// Test that for all the calls in this testcase the C++17 empty base +// artificial fields and [[no_unique_address]] empty class non-static +// data members are ignored in the decision whether passed arguments +// have a single floating point field. +// { dg-final { scan-assembler-times {(?n)^\s+ld\s+%f0,} 7 } } + +struct X { }; +struct Y { int : 0; }; +struct Z { int : 0; Y y; }; +struct U : public X { X q; }; +struct A { double a; }; +struct B : public X { double a; }; +struct C : public Y { double a; }; +struct D : public Z { double a; }; +struct E : public U { double a; }; +struct F { [[no_unique_address]] X x; double a; }; +struct G { [[no_unique_address]] Y y; double a; }; +struct H { [[no_unique_address]] Z z; double a; }; +struct I { [[no_unique_address]] U u; double a; }; +struct J { double a; [[no_unique_address]] X x; }; +struct K { double a; [[no_unique_address]] Y y; }; +struct L { double a; [[no_unique_address]] Z z; }; +struct M { double a; [[no_unique_address]] U u; }; +#define T(S, s) extern S s; extern void foo##s (S); int bar##s () { foo##s (s); return 0; } +// { dg-message "parameter passing for argument of type 'B' when C\\+\\+17 is enabled changed to match C\\+\\+14 in GCC 10.1" "" { target *-*-* } .-1 } +// { dg-message "parameter passing for argument of type 'C' when C\\+\\+17 is enabled changed to match C\\+\\+14 in GCC 10.1" "" { target *-*-* } .-2 } +// { dg-message "parameter passing for argument of type 'F' with '\\\[\\\[no_unique_address\\\]\\\]' members changed in GCC 10.1" "" { target *-*-* } .-3 } +// { dg-message "parameter passing for argument of type 'G' with '\\\[\\\[no_unique_address\\\]\\\]' members changed in GCC 10.1" "" { target *-*-* } .-4 } +// { dg-message "parameter passing for argument of type 'J' with '\\\[\\\[no_unique_address\\\]\\\]' members changed in GCC 10.1" "" { target *-*-* } .-5 } +// { dg-message "parameter passing for argument of type 'K' with '\\\[\\\[no_unique_address\\\]\\\]' members changed in GCC 10.1" "" { target *-*-* } .-6 } +T (A, a) +T (B, b) +T (C, c) +T (F, f) +T (G, g) +T (J, j) +T (K, k) diff --git a/gcc/testsuite/g++.target/s390/pr94704-4.C b/gcc/testsuite/g++.target/s390/pr94704-4.C new file mode 100644 index 0000000..a9727b1 --- /dev/null +++ b/gcc/testsuite/g++.target/s390/pr94704-4.C @@ -0,0 +1,34 @@ +// PR target/94704 +// { dg-do compile } +// { dg-options "-O2 -std=c++17" } +// Test that for no calls in this testcase the C++17 empty base +// artificial fields and [[no_unique_address]] empty class non-static +// data members are ignored in the decision whether passed arguments +// have a single floating point field. +// { dg-final { scan-assembler-not {(?n)^\s+ld\s+%f0,} } } + +struct X { }; +struct Y { int : 0; }; +struct Z { int : 0; Y y; }; +struct U : public X { X q; }; +struct A { double a; }; +struct B : public X { double a; }; +struct C : public Y { double a; }; +struct D : public Z { double a; }; +struct E : public U { double a; }; +struct F { [[no_unique_address]] X x; double a; }; +struct G { [[no_unique_address]] Y y; double a; }; +struct H { [[no_unique_address]] Z z; double a; }; +struct I { [[no_unique_address]] U u; double a; }; +struct J { double a; [[no_unique_address]] X x; }; +struct K { double a; [[no_unique_address]] Y y; }; +struct L { double a; [[no_unique_address]] Z z; }; +struct M { double a; [[no_unique_address]] U u; }; +#define T(S, s) extern S s; extern void foo##s (S); int bar##s () { foo##s (s); return 0; } +// { dg-bogus "parameter passing for argument of type" } +T (D, d) +T (E, e) +T (H, h) +T (I, i) +T (L, l) +T (M, m) diff --git a/gcc/testsuite/g++.target/s390/s390.exp b/gcc/testsuite/g++.target/s390/s390.exp new file mode 100644 index 0000000..a0e6b82 --- /dev/null +++ b/gcc/testsuite/g++.target/s390/s390.exp @@ -0,0 +1,44 @@ +# Specific regression driver for S390. +# Copyright (C) 2020 Free Software Foundation, Inc. +# +# This file is part of GCC. +# +# GCC is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GCC is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# <http://www.gnu.org/licenses/>. */ + +# GCC testsuite that uses the `dg.exp' driver. + +# Exit immediately if this isn't a s390 target. +if {![istarget s390*-*-*] } then { + return +} + +# Load support procs. +load_lib g++-dg.exp + +global DEFAULT_CXXFLAGS +if ![info exists DEFAULT_CXXFLAGS] then { + set DEFAULT_CXXFLAGS " -pedantic-errors" +} + +# Initialize `dg'. +dg-init + +# Main loop. +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.C]] \ + "" $DEFAULT_CXXFLAGS + +# All done. +dg-finish + |