mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-10 21:41:14 +08:00
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.
This commit is contained in:
parent
8f1591763f
commit
48e54fea7b
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
38
gcc/testsuite/g++.target/s390/pr94704-1.C
Normal file
38
gcc/testsuite/g++.target/s390/pr94704-1.C
Normal file
@ -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)
|
34
gcc/testsuite/g++.target/s390/pr94704-2.C
Normal file
34
gcc/testsuite/g++.target/s390/pr94704-2.C
Normal file
@ -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)
|
40
gcc/testsuite/g++.target/s390/pr94704-3.C
Normal file
40
gcc/testsuite/g++.target/s390/pr94704-3.C
Normal file
@ -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)
|
34
gcc/testsuite/g++.target/s390/pr94704-4.C
Normal file
34
gcc/testsuite/g++.target/s390/pr94704-4.C
Normal file
@ -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)
|
44
gcc/testsuite/g++.target/s390/s390.exp
Normal file
44
gcc/testsuite/g++.target/s390/s390.exp
Normal file
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user