Re: [RFA PATCH]: i386: Use generic division to generate INVALID and DIVZERO exceptions

2020-04-19 Thread Richard Biener
On Sun, 19 Apr 2020, Uros Bizjak wrote:

> This patch implements the idea from glibc, where generic division
> operations instead of assembly are used where appropriate.
> 
> --commit--
> i386: Use generic division to generate INVALID and DIVZERO exceptions
> 
> Introduce math_force_eval to evaluate generic division to generate
> INVALID and DIVZERO exceptions.
> 
> libgcc/ChangeLog:
> 
> 2020-04-19  Uroš Bizjak  
> 
> * config/i386/sfp-exceptions.c (math_force_eval): New define.
> (__sfp_handle_exceptions): Use math_force_eval to evaluete
> generic division to generate INVALID and DIVZERO exceptions.
> 
> libatomic/ChangeLog:
> 
> 2020-04-19  Uroš Bizjak  
> 
> * config/x86/fenv.c (math_force_eval): New define.
> (__atomic_feraiseexcept): Use math_force_eval to evaluete
> generic division to generate INVALID and DIVZERO exceptions.
> 
> libgfortran/ChangeLog:
> 
> 2020-04-19  Uroš Bizjak  
> 
> * config/fpu-387.h (_math_force_eval): New define.
> (local_feraiseexcept): Use math_force_eval to evaluete
> generic division to generate INVALID and DIVZERO exceptions.
> --/commit--
> 
> The patch was bootstrapped and regression tested on x86_64-linux-gnu
> {,-m32}. Also, as part of glibc's patch evaluation, I have extensively
> tested it to check that it really generates only correct exceptions
> for both, x87 and SSE math.
> 
> Additionally, the patch improves code for DIVZERO exception, as we can
> now use FDIVRP mnemonic. This mnemonic has its own share of confusion
> (see e.g. SYSV386_COMPAT macro definition) and its use in asm should
> be avoided.
> --/commit message--
> 
> The patch looks safe to me, but I'd like to ask RMs for approval.

If it doesn't fix a regression can it wait for stage1 please?

Thanks,
Richard.


Re: [PATCH] libstdc++: don't use #include_next in c_global headers

2020-04-19 Thread Marc Glisse

On Mon, 20 Apr 2020, Helmut Grohne wrote:


Now you are probably going to say that "-isystem /usr/include" is a bad
idea and that you shouldn't do that. I'm inclined to agree. This isn't a
problem just yet. Debian wants to move /usr/include/stdlib.h to
/usr/include//stdlib.h. After that move, the problematic flag
becomes "-isystem /usr/include/". Unfortunately, around 30
Debian packages[1] do pass exactly that flag. Regardless whether doing
so is a bad idea, I guess we will have to support that.


Urgh, no to "support that". I don't like those #include_next of a header 
with a different name and wouldn't mind seeing them go. But even if your 
patch, or some other patch, happens to make things kind of work, please do 
**not** consider this a supported feature, and keep fixing those broken 
packages (including the big bad cmake which regularly adds such flags to 
innocent packages).


With (or without) your patch, if a user has the bad -isystem and does 
#include , it will never see libstdc++'s version of stdlib.h, 
which contains important extra content, so that's still not working 
properly.


--
Marc Glisse


[PATCH] libstdc++: don't use #include_next in c_global headers

2020-04-19 Thread Helmut Grohne
The  and  headers need their counter parts  and
 from the libc respectively, but libstdc++ wraps these
headers. Now  and  include these headers using

$ echo '#include ' | g++ -x c++ -E - -isystem /usr/include >/dev/null
In file included from :1:
/usr/include/c++/9/cstdlib:75:15: fatal error: stdlib.h: No such file or 
directory
   75 | #include_next 
  |   ^~
compilation terminated.
$

What happens here is that g++ includes
libstdc++-v3/include/c_global/cstdlib. That header temporarily #defines
_GLIBCXX_INCLUDE_NEXT_C_HEADERS and then does #include_next .
libstdc++-v3's replacement libstdc++-v3/include/c_comaptibility/stdlib.h
happens to come earlier and is not considered.  Unfortunately, the
-isystem above inserted glibc's header before the location containing
, so the #include_next continues searching and fails to find
.

Now you are probably going to say that "-isystem /usr/include" is a bad
idea and that you shouldn't do that. I'm inclined to agree. This isn't a
problem just yet. Debian wants to move /usr/include/stdlib.h to
/usr/include//stdlib.h. After that move, the problematic flag
becomes "-isystem /usr/include/". Unfortunately, around 30
Debian packages[1] do pass exactly that flag. Regardless whether doing
so is a bad idea, I guess we will have to support that.

I am proposing to replace those two #include_next with plain #include.
That'll solve the problem described above, but it is not entirely
obvious that doing so doesn't break something else.

After switching those #include_next to #include,
libstdc++-v3/include/c_global/cstdlib will continue to temporarily
will #include . Now, it'll search all include directories. It
may find libstdc++-v3/include/c_comaptibility/stdlib.h or the libc's
version. We cannot tell which. If it finds the one from libstdc++-v3,
the header will notice the _GLIBCXX_INCLUDE_NEXT_C_HEADERS macro and
immediately #include_next  skipping the rest of the header.
That in turn will find the libc version. So in both cases, it ends up
using the right one. Precisely what we wanted. #include_next is simply
not useful here.

The #include_next was originally added via PRs libstdc++/14608 and
libstdc++/60401. At that time, the _GLIBCXX_INCLUDE_NEXT_C_HEADERS guard
macro was also added. It seems like the #include_next was a meant as an
extra safe-guard, but actually breaks a practical use case.

For these reasons, I think that using #include_next here is harmful and
that replacing it with plain #include solves the problem without
introducing regressions.

[1] Including but not limited chromium-browser, inkscape, various kde
packages, opencv, and vtk.

libstdc++-v3/ChangeLog:

* include/c_global/cmath: Don't use #include_next.
* include/c_global/cstdlib: Likewise.
---
 libstdc++-v3/include/c_global/cmath   | 2 +-
 libstdc++-v3/include/c_global/cstdlib | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

Given the patch's size, I think that the copyright dance is not
necessary. The issue affects at least gcc-8 to gcc-10. Please Cc me in
replies.

Helmut

diff --git a/libstdc++-v3/include/c_global/cmath 
b/libstdc++-v3/include/c_global/cmath
index b99aaf8df40..8b2bb7c0785 100644
--- a/libstdc++-v3/include/c_global/cmath
+++ b/libstdc++-v3/include/c_global/cmath
@@ -42,7 +42,7 @@
 #include 
 #include 
 #define _GLIBCXX_INCLUDE_NEXT_C_HEADERS
-#include_next 
+#include 
 #undef _GLIBCXX_INCLUDE_NEXT_C_HEADERS
 #include 
 
diff --git a/libstdc++-v3/include/c_global/cstdlib 
b/libstdc++-v3/include/c_global/cstdlib
index f42db41fc51..80b39f6144f 100644
--- a/libstdc++-v3/include/c_global/cstdlib
+++ b/libstdc++-v3/include/c_global/cstdlib
@@ -72,7 +72,7 @@ namespace std
 // Need to ensure this finds the C library's  not a libstdc++
 // wrapper that might already be installed later in the include search path.
 #define _GLIBCXX_INCLUDE_NEXT_C_HEADERS
-#include_next 
+#include 
 #undef _GLIBCXX_INCLUDE_NEXT_C_HEADERS
 #include 
 
-- 
2.26.0




[committed] libstdc++: Define operator<=> for std::stack and std::queue

2020-04-19 Thread Jonathan Wakely via Gcc-patches
Some more C++20 changes from P1614R2, "The Mothership has Landed".

* include/bits/stl_queue.h (queue): Define operator<=> for C++20.
* include/bits/stl_stack.h (stack): Likewise.
* testsuite/23_containers/queue/cmp_c++20.cc: New test.
* testsuite/23_containers/stack/cmp_c++20.cc: New test.

Tested powerpc64le-linux, committed to master.

commit 717e91dbc44c6bf55a498f45f6045191ceb10a11
Author: Jonathan Wakely 
Date:   Sun Apr 19 21:30:15 2020 +0100

libstdc++: Define operator<=> for std::stack and std::queue

Some more C++20 changes from P1614R2, "The Mothership has Landed".

* include/bits/stl_queue.h (queue): Define operator<=> for C++20.
* include/bits/stl_stack.h (stack): Likewise.
* testsuite/23_containers/queue/cmp_c++20.cc: New test.
* testsuite/23_containers/stack/cmp_c++20.cc: New test.

diff --git a/libstdc++-v3/include/bits/stl_queue.h 
b/libstdc++-v3/include/bits/stl_queue.h
index d2b2705c7c3..8635d426790 100644
--- a/libstdc++-v3/include/bits/stl_queue.h
+++ b/libstdc++-v3/include/bits/stl_queue.h
@@ -114,6 +114,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
friend bool
operator<(const queue<_Tp1, _Seq1>&, const queue<_Tp1, _Seq1>&);
 
+#if __cpp_lib_three_way_comparison
+  template
+   friend compare_three_way_result_t<_Seq1>
+   operator<=>(const queue<_Tp1, _Seq1>&, const queue<_Tp1, _Seq1>&);
+#endif
+
 #if __cplusplus >= 201103L
   template
using _Uses = typename
@@ -380,6 +386,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 operator>=(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y)
 { return !(__x < __y); }
 
+#if __cpp_lib_three_way_comparison
+  template
+inline compare_three_way_result_t<_Seq>
+operator<=>(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y)
+{ return __x.c <=> __y.c; }
+#endif
+
 #if __cplusplus >= 201103L
   template
 inline
diff --git a/libstdc++-v3/include/bits/stl_stack.h 
b/libstdc++-v3/include/bits/stl_stack.h
index 355966a90e0..1ce98a94ab9 100644
--- a/libstdc++-v3/include/bits/stl_stack.h
+++ b/libstdc++-v3/include/bits/stl_stack.h
@@ -116,6 +116,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
friend bool
operator<(const stack<_Tp1, _Seq1>&, const stack<_Tp1, _Seq1>&);
 
+#if __cpp_lib_three_way_comparison
+  template
+   friend compare_three_way_result_t<_Seq1>
+   operator<=>(const stack<_Tp1, _Seq1>&, const stack<_Tp1, _Seq1>&);
+#endif
+
 #if __cplusplus >= 201103L
   template
using _Uses = typename
@@ -355,6 +361,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 operator>=(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y)
 { return !(__x < __y); }
 
+#if __cpp_lib_three_way_comparison
+  template
+inline compare_three_way_result_t<_Seq>
+operator<=>(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y)
+{ return __x.c <=> __y.c; }
+#endif
+
 #if __cplusplus >= 201103L
   template
 inline
diff --git a/libstdc++-v3/testsuite/23_containers/queue/cmp_c++20.cc 
b/libstdc++-v3/testsuite/23_containers/queue/cmp_c++20.cc
new file mode 100644
index 000..5d0d4c9749e
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/queue/cmp_c++20.cc
@@ -0,0 +1,60 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library 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.
+
+// This library 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 this library; see the file COPYING3.  If not see
+// .
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+
+#include 
+#include 
+
+void
+test01()
+{
+  std::queue c1{ {1, 2, 3} }, c2{ {1, 2, 3, 4} }, c3{ {1, 2, 4} };
+  VERIFY( c1 == c1 );
+  VERIFY( std::is_eq(c1 <=> c1) );
+  VERIFY( c1 < c2 );
+  VERIFY( std::is_lt(c1 <=> c2) );
+  VERIFY( c1 < c3 );
+  VERIFY( std::is_lt(c1 <=> c3) );
+  VERIFY( c2 < c3 );
+  VERIFY( std::is_lt(c2 <=> c3) );
+
+  static_assert( std::totally_ordered> );
+
+  static_assert( std::three_way_comparable,
+  std::strong_ordering> );
+  static_assert( ! std::three_way_comparable,
+std::strong_ordering> );
+  static_assert( ! std::three_way_comparable,
+std::weak_ordering> );
+  static_assert( std::three_way_comparable,
+  std::partial_ordering> );
+
+  struct E
+  {
+   

Aw: [Patch fortran/93364] [9/10 Regression] ICE in gfc_set_array_spec, at fortran/array.c:879

2020-04-19 Thread Harald Anlauf
Hi again,

I was so focussed on whether I got this correct for the gcc git repository that
I forgot to mention that this has been cleanly regtested on x86_64-pc-linux-gnu.

Sorry for the added noise.

Harald


> Gesendet: Sonntag, 19. April 2020 um 22:49 Uhr
> Von: "Harald Anlauf" 
> An: "fortran" , "gcc-patches" 
> Betreff: [Patch fortran/93364] [9/10 Regression] ICE in gfc_set_array_spec, 
> at fortran/array.c:879
>
> Hi,
>
> a missing check in gfc_set_array_spec for for sum of rank and corank
> not exceeding GFC_MAX_DIMENSIONS could trigger an assert on invalid code.
>
> The attached patch fixes that.  OK for mainline / backport to 9-branch?
>
> Harald
>
>
> 2020-04-19  Harald Anlauf  
>
>   PR fortran/93364
>   * array.c (gfc_set_array_spec): Check for sum of rank and corank
>   not exceeding GFC_MAX_DIMENSIONS.
>
>
> 2020-04-19  Harald Anlauf  
>
>   PR fortran/93364
>   * gfortran.dg/pr93364.f90: New test.
>
>
> diff --git a/gcc/fortran/array.c b/gcc/fortran/array.c
> index 57972bc9176..471523fb767 100644
> --- a/gcc/fortran/array.c
> +++ b/gcc/fortran/array.c
> @@ -864,6 +864,10 @@ gfc_set_array_spec (gfc_symbol *sym, gfc_array_spec *as, 
> locus *error_loc)
>return false;
>  }
>
> +  /* Check F2018:C822.  */
> +  if (sym->as->rank + sym->as->corank > GFC_MAX_DIMENSIONS)
> +goto too_many;
> +
>if (as->corank)
>  {
>sym->as->cotype = as->cotype;
> diff --git a/gcc/testsuite/gfortran.dg/pr93364.f90 
> b/gcc/testsuite/gfortran.dg/pr93364.f90
> new file mode 100644
> index 000..61d7fa149a6
> --- /dev/null
> +++ b/gcc/testsuite/gfortran.dg/pr93364.f90
> @@ -0,0 +1,13 @@
> +! { dg-do compile }
> +! { dg-options "-fcoarray=single" }
> +!
> +! PR fortran/93364 - check fix for ICE in gfc_set_array_spec
> +
> +type(t) function f()
> +  codimension :: t[1,2,1,2,1,2,1,*]
> +  dimension :: t(1,2,1,2,1,2,1,2)
> +end
> +
> +! { dg-error "has not been declared" " " { target *-*-* } 6 }
> +! { dg-error "is of type 't'" " " { target *-*-* } 6 }
> +! { dg-error "rank \\+ corank of" " " { target *-*-* } 8 }
>


[Patch fortran/93364] [9/10 Regression] ICE in gfc_set_array_spec, at fortran/array.c:879

2020-04-19 Thread Harald Anlauf
Hi,

a missing check in gfc_set_array_spec for for sum of rank and corank
not exceeding GFC_MAX_DIMENSIONS could trigger an assert on invalid code.

The attached patch fixes that.  OK for mainline / backport to 9-branch?

Harald


2020-04-19  Harald Anlauf  

PR fortran/93364
* array.c (gfc_set_array_spec): Check for sum of rank and corank
not exceeding GFC_MAX_DIMENSIONS.


2020-04-19  Harald Anlauf  

PR fortran/93364
* gfortran.dg/pr93364.f90: New test.


diff --git a/gcc/fortran/array.c b/gcc/fortran/array.c
index 57972bc9176..471523fb767 100644
--- a/gcc/fortran/array.c
+++ b/gcc/fortran/array.c
@@ -864,6 +864,10 @@ gfc_set_array_spec (gfc_symbol *sym, gfc_array_spec *as, 
locus *error_loc)
   return false;
 }

+  /* Check F2018:C822.  */
+  if (sym->as->rank + sym->as->corank > GFC_MAX_DIMENSIONS)
+goto too_many;
+
   if (as->corank)
 {
   sym->as->cotype = as->cotype;
diff --git a/gcc/testsuite/gfortran.dg/pr93364.f90 
b/gcc/testsuite/gfortran.dg/pr93364.f90
new file mode 100644
index 000..61d7fa149a6
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr93364.f90
@@ -0,0 +1,13 @@
+! { dg-do compile }
+! { dg-options "-fcoarray=single" }
+!
+! PR fortran/93364 - check fix for ICE in gfc_set_array_spec
+
+type(t) function f()
+  codimension :: t[1,2,1,2,1,2,1,*]
+  dimension :: t(1,2,1,2,1,2,1,2)
+end
+
+! { dg-error "has not been declared" " " { target *-*-* } 6 }
+! { dg-error "is of type 't'" " " { target *-*-* } 6 }
+! { dg-error "rank \\+ corank of" " " { target *-*-* } 8 }



[committed] libstdc++: Remove operator!= overloads for unordered containers

2020-04-19 Thread Jonathan Wakely via Gcc-patches
Some more C++20 changes from P1614R2, "The Mothership has Landed".

* include/bits/unordered_map.h (unordered_map, unordered_multimap):
Remove redundant operator!= for C++20.
* include/bits/unordered_set.h (unordered_set, unordered_multiset):
Likewise.
* include/debug/unordered_map (unordered_map, unordered_multimap):
Likewise.
* include/debug/unordered_set (unordered_set, unordered_multiset):
Likewise.

Tested powerpvc64le-linux, committed to master.

commit 7ab9c2430ffb13de8433aa7d654192b5d2b1e7a9
Author: Jonathan Wakely 
Date:   Sun Apr 19 21:04:40 2020 +0100

libstdc++: Remove operator!= overloads for unordered containers

Some more C++20 changes from P1614R2, "The Mothership has Landed".

* include/bits/unordered_map.h (unordered_map, unordered_multimap):
Remove redundant operator!= for C++20.
* include/bits/unordered_set.h (unordered_set, unordered_multiset):
Likewise.
* include/debug/unordered_map (unordered_map, unordered_multimap):
Likewise.
* include/debug/unordered_set (unordered_set, unordered_multiset):
Likewise.

diff --git a/libstdc++-v3/include/bits/unordered_map.h 
b/libstdc++-v3/include/bits/unordered_map.h
index 767f0d57976..ab1b1d52442 100644
--- a/libstdc++-v3/include/bits/unordered_map.h
+++ b/libstdc++-v3/include/bits/unordered_map.h
@@ -2092,11 +2092,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
   const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
 { return __x._M_h._M_equal(__y._M_h); }
 
+#if __cpp_impl_three_way_comparison < 201907L
   template
 inline bool
 operator!=(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
   const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
 { return !(__x == __y); }
+#endif
 
   template
 inline bool
@@ -2104,11 +2106,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
   const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
 { return __x._M_h._M_equal(__y._M_h); }
 
+#if __cpp_impl_three_way_comparison < 201907L
   template
 inline bool
 operator!=(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
   const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
 { return !(__x == __y); }
+#endif
 
 _GLIBCXX_END_NAMESPACE_CONTAINER
 
diff --git a/libstdc++-v3/include/bits/unordered_set.h 
b/libstdc++-v3/include/bits/unordered_set.h
index 9c2cd45be9c..c9c9e9f38b7 100644
--- a/libstdc++-v3/include/bits/unordered_set.h
+++ b/libstdc++-v3/include/bits/unordered_set.h
@@ -1704,11 +1704,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
   const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
 { return __x._M_h._M_equal(__y._M_h); }
 
+#if __cpp_impl_three_way_comparison < 201907L
   template
 inline bool
 operator!=(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
   const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
 { return !(__x == __y); }
+#endif
 
   template
 inline bool
@@ -1716,11 +1718,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
   const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
 { return __x._M_h._M_equal(__y._M_h); }
 
+#if __cpp_impl_three_way_comparison < 201907L
   template
 inline bool
 operator!=(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
   const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
 { return !(__x == __y); }
+#endif
 
 _GLIBCXX_END_NAMESPACE_CONTAINER
 
diff --git a/libstdc++-v3/include/debug/unordered_map 
b/libstdc++-v3/include/debug/unordered_map
index 7be1d2ee952..17fbba3aade 100644
--- a/libstdc++-v3/include/debug/unordered_map
+++ b/libstdc++-v3/include/debug/unordered_map
@@ -741,13 +741,14 @@ namespace __debug
   const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
 { return __x._M_base() == __y._M_base(); }
 
+#if __cpp_impl_three_way_comparison < 201907L
   template
 inline bool
 operator!=(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
   const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
 { return !(__x == __y); }
-
+#endif
 
   /// Class std::unordered_multimap with safety/checking/debug instrumentation.
   template& __y)
 { return __x._M_base() == __y._M_base(); }
 
+#if __cpp_impl_three_way_comparison < 201907L
   template
 inline bool
 operator!=(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
   const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
 { return !(__x == __y); }
+#endif
 
 } // namespace __debug
 } // namespace std
diff --git a/libstdc++-v3/include/debug/unordered_set 
b/libstdc++-v3/include/debug/unordered_set
index 9941bbe1c24..4d30852186c 100644
--- a/libstdc++-v3/include/debug/unordered_set
+++ b/libstdc++-v3/include/debug/unordered_set
@@ -612,12 +612,13 @@ nam

[committed] libstdc++: Fix redundant assignment (PR 94629)

2020-04-19 Thread Jonathan Wakely via Gcc-patches
This appears to be a copy&paste error, which cppcheck diagnoses.

PR other/94629
* include/debug/formatter.h (_Error_formatter::_Parameter): Fix
redundant assignment in constructor.

Tested powerpc64le-linux, committed to master.

commit a2c0fa35d0dc8912b0c1a658234221de61e60840
Author: Jonathan Wakely 
Date:   Sun Apr 19 20:54:38 2020 +0100

libstdc++: Fix redundant assignment (PR 94629)

This appears to be a copy&paste error, which cppcheck diagnoses.

PR other/94629
* include/debug/formatter.h (_Error_formatter::_Parameter): Fix
redundant assignment in constructor.

diff --git a/libstdc++-v3/include/debug/formatter.h 
b/libstdc++-v3/include/debug/formatter.h
index 998f8056601..bb9b3e5653a 100644
--- a/libstdc++-v3/include/debug/formatter.h
+++ b/libstdc++-v3/include/debug/formatter.h
@@ -299,7 +299,6 @@ namespace __gnu_debug
  _M_variant._M_iterator._M_name = __name;
  _M_variant._M_iterator._M_address = std::__addressof(__it);
  _M_variant._M_iterator._M_type = _GLIBCXX_TYPEID(_Iterator);
- _M_variant._M_iterator._M_constness =
  _M_variant._M_iterator._M_constness =
__it._S_constant() ? __const_iterator : __mutable_iterator;
  _M_variant._M_iterator._M_sequence = __it._M_get_sequence();


[PATCH] coroutines: Fix handling of ramp return value [PR94661]

2020-04-19 Thread Iain Sandoe
Hi,

Coroutine ramp functions have synthesised return values (the
user-authored function body cannot have an explicit 'return').
The current implementation attempts to optimise by building
the return in-place, in the manner of C++17 code.  Clearly,
that was too ambitious and the fix builds a target expr for
the constructed version and passes that to finish_return_stmt.

This also means that we now get the same error messages as 
non-coroutines code, for implicit use of deleted CTORs etc.



This is not part of PR94288, but the testcase for that also  has
the issue, so it’s preferable to apply this first.

tested on x86_64-darwin16,
OK if it passes regstrap on x86-64-Linux too?
thanks
Iain


gcc/cp/ChangeLog:

2020-04-19  Iain Sandoe  

PR c++/94661
* coroutines.cc (morph_fn_to_coro): Simplify return
value computation.

gcc/testsuite/ChangeLog:

2020-04-19  Iain Sandoe  

PR c++/94661
* g++.dg/coroutines/ramp-return-a.C: New test.
* g++.dg/coroutines/ramp-return-b.C: New test.
* g++.dg/coroutines/ramp-return-c.C: New test.
---
 gcc/cp/coroutines.cc  | 47 +-
 .../g++.dg/coroutines/ramp-return-a.C | 24 +++
 .../g++.dg/coroutines/ramp-return-b.C | 22 +++
 .../g++.dg/coroutines/ramp-return-c.C | 22 +++
 gcc/testsuite/g++.dg/coroutines/ramp-return.h | 64 +++
 5 files changed, 147 insertions(+), 32 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/coroutines/ramp-return-a.C
 create mode 100644 gcc/testsuite/g++.dg/coroutines/ramp-return-b.C
 create mode 100644 gcc/testsuite/g++.dg/coroutines/ramp-return-c.C
 create mode 100644 gcc/testsuite/g++.dg/coroutines/ramp-return.h

diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index 0a8e7521c4f..e1890ace956 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -3726,23 +3726,14 @@ morph_fn_to_coro (tree orig, tree *resumer, tree 
*destroyer)
 }
 
   tree gro_context_body = push_stmt_list ();
-  tree gro, gro_bind_vars;
-  if (same_type_p (TREE_TYPE (get_ro), fn_return_type))
-{
-  gro = DECL_RESULT (orig);
-  gro_bind_vars = NULL_TREE; /* We don't need a separate var.  */
-}
-  else
-{
-  gro = build_lang_decl (VAR_DECL, get_identifier ("coro.gro"),
-TREE_TYPE (TREE_OPERAND (get_ro, 0)));
-  DECL_CONTEXT (gro) = current_scope ();
-  r = build_stmt (fn_start, DECL_EXPR, gro);
-  add_stmt (r);
-  gro_bind_vars = gro; /* We need a temporary var.  */
-}
-
-  /* Initialize our actual var.  */
+  tree gro = build_lang_decl (VAR_DECL, get_identifier ("coro.gro"), 
+ TREE_TYPE (get_ro));
+  DECL_CONTEXT (gro) = current_scope ();
+  add_decl_expr (gro);
+  tree gro_bind_vars = gro;
+
+  /* We have to sequence the call to get_return_object before initial
+ suspend.  */
   r = build2_loc (fn_start, INIT_EXPR, TREE_TYPE (gro), gro, get_ro);
   r = coro_build_cvt_void_expr_stmt (r, fn_start);
   add_stmt (r);
@@ -3779,30 +3770,22 @@ morph_fn_to_coro (tree orig, tree *resumer, tree 
*destroyer)
  logically doing things related to the end of the function.  */
 
   /* The ramp is done, we just need the return value.  */
-  if (!same_type_p (TREE_TYPE (gro), fn_return_type))
+  if (!same_type_p (TREE_TYPE (get_ro), fn_return_type))
 {
   /* construct the return value with a single GRO param.  */
   vec *args = make_tree_vector_single (gro);
-  r = build_special_member_call (DECL_RESULT (orig),
+  r = build_special_member_call (NULL_TREE,
 complete_ctor_identifier, &args,
 fn_return_type, LOOKUP_NORMAL,
 tf_warning_or_error);
-  r = coro_build_cvt_void_expr_stmt (r, input_location);
-  add_stmt (r);
-  release_tree_vector (args);
+  r = build_cplus_new (fn_return_type, r, tf_warning_or_error);
 }
-  /* Else the GRO is the return and we already built it in place.  */
+  else
+r = rvalue (gro); /* The GRO is the return value.  */
 
-  bool no_warning;
-  r = check_return_expr (DECL_RESULT (orig), &no_warning);
-  if (error_operand_p (r) && warn_return_type)
-/* Suppress -Wreturn-type for the ramp.  */
-TREE_NO_WARNING (orig) = true;
+  finish_return_stmt (r);
 
-  r = build_stmt (input_location, RETURN_EXPR, DECL_RESULT (orig));
-  TREE_NO_WARNING (r) |= no_warning;
-  r = maybe_cleanup_point_expr_void (r);
-  add_stmt (r);
+  /* Finish up the ramp function.  */
   BIND_EXPR_VARS (gro_context_bind) = gro_bind_vars;
   BIND_EXPR_BODY (gro_context_bind) = pop_stmt_list (gro_context_body);
   BIND_EXPR_BODY (ramp_bind) = pop_stmt_list (ramp_body);
diff --git a/gcc/testsuite/g++.dg/coroutines/ramp-return-a.C 
b/gcc/testsuite/g++.dg/coroutines/ramp-return-a.C
new file mode 100644
index 000..c6e445e0529
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutine

New Swedish PO file for 'gcc' (version 10.1-b20200322)

2020-04-19 Thread Translation Project Robot
Hello, gentle maintainer.

This is a message from the Translation Project robot.

A revised PO file for textual domain 'gcc' has been submitted
by the Swedish team of translators.  The file is available at:

https://translationproject.org/latest/gcc/sv.po

(This file, 'gcc-10.1-b20200322.sv.po', has just now been sent to you in
a separate email.)

All other PO files for your package are available in:

https://translationproject.org/latest/gcc/

Please consider including all of these in your next release, whether
official or a pretest.

Whenever you have a new distribution with a new version number ready,
containing a newer POT file, please send the URL of that distribution
tarball to the address below.  The tarball may be just a pretest or a
snapshot, it does not even have to compile.  It is just used by the
translators when they need some extra translation context.

The following HTML page has been updated:

https://translationproject.org/domain/gcc.html

If any question arises, please contact the translation coordinator.

Thank you for all your work,

The Translation Project robot, in the
name of your translation coordinator.




[RFA PATCH]: i386: Use generic division to generate INVALID and DIVZERO exceptions

2020-04-19 Thread Uros Bizjak via Gcc-patches
This patch implements the idea from glibc, where generic division
operations instead of assembly are used where appropriate.

--commit--
i386: Use generic division to generate INVALID and DIVZERO exceptions

Introduce math_force_eval to evaluate generic division to generate
INVALID and DIVZERO exceptions.

libgcc/ChangeLog:

2020-04-19  Uroš Bizjak  

* config/i386/sfp-exceptions.c (math_force_eval): New define.
(__sfp_handle_exceptions): Use math_force_eval to evaluete
generic division to generate INVALID and DIVZERO exceptions.

libatomic/ChangeLog:

2020-04-19  Uroš Bizjak  

* config/x86/fenv.c (math_force_eval): New define.
(__atomic_feraiseexcept): Use math_force_eval to evaluete
generic division to generate INVALID and DIVZERO exceptions.

libgfortran/ChangeLog:

2020-04-19  Uroš Bizjak  

* config/fpu-387.h (_math_force_eval): New define.
(local_feraiseexcept): Use math_force_eval to evaluete
generic division to generate INVALID and DIVZERO exceptions.
--/commit--

The patch was bootstrapped and regression tested on x86_64-linux-gnu
{,-m32}. Also, as part of glibc's patch evaluation, I have extensively
tested it to check that it really generates only correct exceptions
for both, x87 and SSE math.

Additionally, the patch improves code for DIVZERO exception, as we can
now use FDIVRP mnemonic. This mnemonic has its own share of confusion
(see e.g. SYSV386_COMPAT macro definition) and its use in asm should
be avoided.
--/commit message--

The patch looks safe to me, but I'd like to ask RMs for approval.

Uros.
diff --git a/libatomic/config/x86/fenv.c b/libatomic/config/x86/fenv.c
index d7b1bbe5ea1..be1db42245c 100644
--- a/libatomic/config/x86/fenv.c
+++ b/libatomic/config/x86/fenv.c
@@ -47,6 +47,12 @@ struct fenv
   unsigned short int __unused5;
 };
 
+#ifdef __SSE_MATH__
+# define math_force_eval(x) asm volatile ("" : : "x" (x));
+#else
+# define math_force_eval(x) asm volatile ("" : : "f" (x));
+#endif
+
 /* Raise the supported floating-point exceptions from EXCEPTS.  Other
bits in EXCEPTS are ignored.  */
 
@@ -56,12 +62,7 @@ __atomic_feraiseexcept (int excepts)
   if (excepts & FE_INVALID)
 {
   float f = 0.0f;
-#ifdef __SSE_MATH__
-  asm volatile ("%vdivss\t{%0, %d0|%d0, %0}" : "+x" (f));
-#else
-  asm volatile ("fdiv\t{%y0, %0|%0, %y0}" : "+t" (f));
-  /* No need for fwait, exception is triggered by emitted fstp.  */
-#endif
+  math_force_eval (f / f);
 }
   if (excepts & FE_DENORM)
 {
@@ -74,12 +75,7 @@ __atomic_feraiseexcept (int excepts)
   if (excepts & FE_DIVBYZERO)
 {
   float f = 1.0f, g = 0.0f;
-#ifdef __SSE_MATH__
-  asm volatile ("%vdivss\t{%1, %d0|%d0, %1}" : "+x" (f) : "xm" (g));
-#else
-  asm volatile ("fdivs\t%1" : "+t" (f) : "m" (g));
-  /* No need for fwait, exception is triggered by emitted fstp.  */
-#endif
+  math_force_eval (f / g);
 }
   if (excepts & FE_OVERFLOW)
 {
diff --git a/libgcc/config/i386/sfp-exceptions.c 
b/libgcc/config/i386/sfp-exceptions.c
index 31a24ced704..57047ab1d07 100644
--- a/libgcc/config/i386/sfp-exceptions.c
+++ b/libgcc/config/i386/sfp-exceptions.c
@@ -41,18 +41,19 @@ struct fenv
   unsigned short int __unused5;
 };
 
+#ifdef __SSE_MATH__
+# define math_force_eval(x) asm volatile ("" : : "x" (x));
+#else
+# define math_force_eval(x) asm volatile ("" : : "f" (x));
+#endif
+
 void
 __sfp_handle_exceptions (int _fex)
 {
   if (_fex & FP_EX_INVALID)
 {
   float f = 0.0f;
-#ifdef __SSE_MATH__
-  asm volatile ("%vdivss\t{%0, %d0|%d0, %0}" : "+x" (f));
-#else
-  asm volatile ("fdiv\t{%y0, %0|%0, %y0}" : "+t" (f));
-  /* No need for fwait, exception is triggered by emitted fstp.  */
-#endif
+  math_force_eval (f / f);
 }
   if (_fex & FP_EX_DENORM)
 {
@@ -65,12 +66,7 @@ __sfp_handle_exceptions (int _fex)
   if (_fex & FP_EX_DIVZERO)
 {
   float f = 1.0f, g = 0.0f;
-#ifdef __SSE_MATH__
-  asm volatile ("%vdivss\t{%1, %d0|%d0, %1}" : "+x" (f) : "xm" (g));
-#else
-  asm volatile ("fdivs\t%1" : "+t" (f) : "m" (g));
-  /* No need for fwait, exception is triggered by emitted fstp.  */
-#endif
+  math_force_eval (f / g);
 }
   if (_fex & FP_EX_OVERFLOW)
 {
diff --git a/libgfortran/config/fpu-387.h b/libgfortran/config/fpu-387.h
index 13be2045b72..08c994f69da 100644
--- a/libgfortran/config/fpu-387.h
+++ b/libgfortran/config/fpu-387.h
@@ -91,6 +91,11 @@ my_fenv_t;
 _Static_assert (sizeof(my_fenv_t) <= (size_t) GFC_FPE_STATE_BUFFER_SIZE,
"GFC_FPE_STATE_BUFFER_SIZE is too small");
 
+#ifdef __SSE_MATH__
+# define _math_force_eval(x) __asm__ __volatile__ ("" : : "x" (x));
+#else
+# define _math_force_eval(x) __asm__ __volatile__ ("" : : "f" (x));
+#endif
 
 /* Raise the supported floating-point exceptions from EXCEPTS.  Other
bits in EXCEPTS are ignored.  Code originally borrowed from
@@ -102,12 +107,7 @@ local_feraiseexcept (int excepts)
   if (excepts & _FPU_MASK_IM)
 {
   

[committed] libphobos: Merge upstream phobos bf0d0a37c (PR94455)

2020-04-19 Thread Iain Buclaw via Gcc-patches
Hi,

This patch merges libphobos with upstream phobos bf0d0a37c.

Fixes std.array.Appender and RefAppender to use .opSlice() instead of data()

Previously, Appender.data() was used to extract a slice of the Appender's array.
Now use the [] slice operator instead.  The same goes for RefAppender.

Bootstrapped and regression tested on x86_64-linux-gnu, and committed to
mainline.

Regards
Iain.

---
 libphobos/src/MERGE   |   2 +-
 libphobos/src/std/array.d | 138 --
 2 files changed, 87 insertions(+), 53 deletions(-)

diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE
index 31a053ca2bb..6025cdcc1f7 100644
--- a/libphobos/src/MERGE
+++ b/libphobos/src/MERGE
@@ -1,4 +1,4 @@
-99003a75a883d4ae28b276763f4d1f2a360cf1dd
+bf0d0a37c4c2d8762ceff7d8677e7584b770800f
 
 The first line of this file holds the git revision number of the last
 merge done from the dlang/phobos repository.
diff --git a/libphobos/src/std/array.d b/libphobos/src/std/array.d
index b03f5e9d2d0..179fa664795 100644
--- a/libphobos/src/std/array.d
+++ b/libphobos/src/std/array.d
@@ -2859,9 +2859,18 @@ if (isDynamicArray!A)
 }
 
 /**
+ * Use opSlice() from now on.
  * Returns: The managed array.
  */
 @property inout(ElementEncodingType!A)[] data() inout @trusted pure nothrow
+{
+return this[];
+}
+
+/**
+ * Returns: The managed array.
+ */
+@property inout(ElementEncodingType!A)[] opSlice() inout @trusted pure 
nothrow
 {
 /* @trusted operation:
  * casting Unqual!T[] to inout(T)[]
@@ -3117,13 +3126,13 @@ if (isDynamicArray!A)
 string b = "abcdefg";
 foreach (char c; b)
 app.put(c);
-assert(app.data == "abcdefg");
+assert(app[] == "abcdefg");
 
 int[] a = [ 1, 2 ];
 auto app2 = appender(a);
 app2.put(3);
 app2.put([ 4, 5, 6 ]);
-assert(app2.data == [ 1, 2, 3, 4, 5, 6 ]);
+assert(app2[] == [ 1, 2, 3, 4, 5, 6 ]);
 }
 
 @safe unittest
@@ -3214,7 +3223,7 @@ if (isDynamicArray!A)
 if (__traits(compiles, (Appender!A a) => mixin("a." ~ fn ~ "(args)")))
 {
 // we do it this way because we can't cache a void return
-scope(exit) *this.arr = impl.data;
+scope(exit) *this.arr = impl[];
 mixin("return impl." ~ fn ~ "(args);");
 }
 
@@ -3226,7 +3235,7 @@ if (isDynamicArray!A)
 void opOpAssign(string op : "~", U)(U rhs)
 if (__traits(compiles, (Appender!A a){ a.put(rhs); }))
 {
-scope(exit) *this.arr = impl.data;
+scope(exit) *this.arr = impl[];
 impl.put(rhs);
 }
 
@@ -3240,12 +3249,20 @@ if (isDynamicArray!A)
 return impl.capacity;
 }
 
-/**
- * Returns the managed array.
+/* Use opSlice() instead.
+ * Returns: the managed array.
  */
 @property inout(ElementEncodingType!A)[] data() inout
 {
-return impl.data;
+return impl[];
+}
+
+/**
+ * Returns: the managed array.
+ */
+@property inout(ElementEncodingType!A)[] opSlice() inout
+{
+return impl[];
 }
 }
 
@@ -3255,11 +3272,11 @@ unittest
 {
 int[] a = [1, 2];
 auto app2 = appender(&a);
-assert(app2.data == [1, 2]);
+assert(app2[] == [1, 2]);
 assert(a == [1, 2]);
 app2 ~= 3;
 app2 ~= [4, 5, 6];
-assert(app2.data == [1, 2, 3, 4, 5, 6]);
+assert(app2[] == [1, 2, 3, 4, 5, 6]);
 assert(a == [1, 2, 3, 4, 5, 6]);
 
 app2.reserve(5);
@@ -3291,33 +3308,33 @@ Appender!(E[]) appender(A : E[], E)(auto ref A array)
 auto app = appender!(char[])();
 string b = "abcdefg";
 foreach (char c; b) app.put(c);
-assert(app.data == "abcdefg");
+assert(app[] == "abcdefg");
 }
 {
 auto app = appender!(char[])();
 string b = "abcdefg";
 foreach (char c; b) app ~= c;
-assert(app.data == "abcdefg");
+assert(app[] == "abcdefg");
 }
 {
 int[] a = [ 1, 2 ];
 auto app2 = appender(a);
-assert(app2.data == [ 1, 2 ]);
+assert(app2[] == [ 1, 2 ]);
 app2.put(3);
 app2.put([ 4, 5, 6 ][]);
-assert(app2.data == [ 1, 2, 3, 4, 5, 6 ]);
+assert(app2[] == [ 1, 2, 3, 4, 5, 6 ]);
 app2.put([ 7 ]);
-assert(app2.data == [ 1, 2, 3, 4, 5, 6, 7 ]);
+assert(app2[] == [ 1, 2, 3, 4, 5, 6, 7 ]);
 }
 
 int[] a = [ 1, 2 ];
 auto app2 = appender(a);
-assert(app2.data == [ 1, 2 ]);
+assert(app2[] == [ 1, 2 ]);
 app2 ~= 3;
 app2 ~= [ 4, 5, 6 ][];
-assert(app2.data == [ 1, 2, 3, 4, 5, 6 ]);
+assert(app2[] == [ 1, 2, 3, 4, 5, 6 ]);
 app2 ~= [ 7 ];
-assert(app2.data == [ 1, 2, 3, 4, 5, 6, 7 ]);
+assert(app2[] == [ 1, 2, 3, 4, 5, 6, 7 ]);
 
 app2.reserve(5);
 assert(app2.capacity >= 5);
@@ -3327,12 +3344,12 @@ Appender!(E[]) appender(A : E[], E)(auto ref A array)
 app2.shrinkTo(3);
 }
 catch (Exception) assert(0);
-assert(app2.data == [ 1, 

Re: [Patch, fortran] PR fortran/90350 - ubound ICE on assumed size array even though explicit bound is specified

2020-04-19 Thread José Rui Faustino de Sousa via Gcc-patches

Hi Thomas!

> ? In other words, maybe a check on the upper bound
> of the last dimension would be better?
>

You mean enforcing:

C928 (R921) The second subscript shall not be omitted from a 
subscript-triplet in the last dimension of an assumed-size array.


right?

If I have correctly understood the way things are done this is a more 
general test which is already done at resolve.c around line 4690.


One could just duplicate the test to be extra safe.

> A question: Do you have a copyright assignment yet?
>

Yes, I have already done that.

Best regards,
José Rui



[PATCH] c++: Fix bogus -Wparentheses warning with fold-expression [PR94505]

2020-04-19 Thread Marek Polacek via Gcc-patches
We issue bogus -Wparentheses warnings (3 of them!) for this fold expression:

  ((B && true) || ...)

Firstly, issuing a warning for a compiler-generated expression is wrong
and secondly, B && true must be wrapped in ( ) otherwise you'll get
error: binary expression in operand of fold-expression.

Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?

PR c++/94505 - bogus -Wparentheses warning with fold-expression.
* pt.c (fold_expression): Add warning_sentinel for -Wparentheses
before calling build_x_binary_op.

* g++.dg/cpp1z/fold11.C: New test.
---
 gcc/cp/pt.c |  1 +
 gcc/testsuite/g++.dg/cpp1z/fold11.C | 12 
 2 files changed, 13 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/cpp1z/fold11.C

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 9e39f46a090..5d5941eddb7 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -12356,6 +12356,7 @@ fold_expression (tree t, tree left, tree right, 
tsubst_flags_t complain)
   if (FOLD_EXPR_MODIFY_P (t))
 return build_x_modify_expr (input_location, left, code, right, complain);
 
+  warning_sentinel s(warn_parentheses);
   switch (code)
 {
 case COMPOUND_EXPR:
diff --git a/gcc/testsuite/g++.dg/cpp1z/fold11.C 
b/gcc/testsuite/g++.dg/cpp1z/fold11.C
new file mode 100644
index 000..09a30555eee
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/fold11.C
@@ -0,0 +1,12 @@
+// PR c++/94505 - bogus -Wparentheses warning with fold-expression.
+// { dg-do compile { target c++17 } }
+// { dg-options "-Wparentheses" }
+
+template 
+bool foo () {
+return ((B && true) || ...); // { dg-bogus "suggest parentheses" }
+}
+
+int main () {
+foo ();
+}

base-commit: fc186077486fb6e5453157ad8507c66d0a34017c
-- 
Marek Polacek • Red Hat, Inc. • 300 A St, Boston, MA



[PATCH] c++: Recursive unification with packs and explicit targs [PR94628]

2020-04-19 Thread Patrick Palka via Gcc-patches
This PR seems to be similar to PR c++/43382, except that the recursive call to
the variadic function with trailing return type in this testcase is additionally
given some explicit template arguments.

In the first testcase below, when resolving the recursive call to 'select',
fn_type_unification first substitutes in the call's explicit template arguments
before doing unification, and so during this substitution the template argument
pack for Args is incomplete.

Since the pack is incomplete, the substitution of 'args...' in the trailing
return type decltype(f(args...)) is handled by the unsubstituted_packs case of
tsubst_pack_expansion.  But the handling of this case happens _before_ we reset
local_specializations, and so the substitution ends up reusing the old binding
for 'args' from local_specializations rather than building a new one.

This patch fixes this issue by setting up local_specializations sooner in
tsubst_pack_expansion, before the handling of the unsubstituted_packs case.
It also adds a new policy to local_specialization_stack so that we could use the
class here to conditionally replace local_specializations.

Passes 'make check-c++', does this look OK to commit after bootstrap/regtesting?

gcc/cp/ChangeLog:

PR c++/94628
* cp-tree.h (lss_policy::lss_inherit): New enumerator.
* pt.c (local_specialization_stack::local_specialization_stack): Handle
an lss_inherit policy.
(local_specialization_stack::~local_specialization_stack): Likewise.
(tsubst_pack_expansion): Use a local_specialization_stack instead of
manually saving and restoring local_specializations.  Conditionally
replace local_specializations sooner, before the handling of the
unsubstituted_packs case.

gcc/testsuite/ChangeLog:

PR c++/94628
* g++.dg/cpp0x/variadic179.C: New test.
* g++.dg/cpp0x/variadic180.C: New test.
---
 gcc/cp/cp-tree.h |  2 +-
 gcc/cp/pt.c  | 38 +++-
 gcc/testsuite/g++.dg/cpp0x/variadic179.C | 16 ++
 gcc/testsuite/g++.dg/cpp0x/variadic180.C | 25 
 4 files changed, 59 insertions(+), 22 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/variadic179.C
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/variadic180.C

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 000badc21ac..5b3b9507474 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5424,7 +5424,7 @@ enum unification_kind_t {
 // An RAII class used to create a new pointer map for local
 // specializations. When the stack goes out of scope, the
 // previous pointer map is restored.
-enum lss_policy { lss_blank, lss_copy };
+enum lss_policy { lss_blank, lss_copy, lss_inherit };
 class local_specialization_stack
 {
 public:
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 9e39f46a090..9cea663514d 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -83,7 +83,9 @@ static tree cur_stmt_expr;
 local_specialization_stack::local_specialization_stack (lss_policy policy)
   : saved (local_specializations)
 {
-  if (policy == lss_blank || !saved)
+  if (policy == lss_inherit)
+;
+  else if (policy == lss_blank || !saved)
 local_specializations = new hash_map;
   else
 local_specializations = new hash_map(*saved);
@@ -91,8 +93,11 @@ local_specialization_stack::local_specialization_stack 
(lss_policy policy)
 
 local_specialization_stack::~local_specialization_stack ()
 {
-  delete local_specializations;
-  local_specializations = saved;
+  if (local_specializations != saved)
+{
+  delete local_specializations;
+  local_specializations = saved;
+}
 }
 
 /* True if we've recursed into fn_type_unification too many times.  */
@@ -12694,7 +12699,6 @@ tsubst_pack_expansion (tree t, tree args, 
tsubst_flags_t complain,
   bool unsubstituted_fn_pack = false;
   int i, len = -1;
   tree result;
-  hash_map *saved_local_specializations = NULL;
   bool need_local_specializations = false;
   int levels;
 
@@ -12893,7 +12897,15 @@ tsubst_pack_expansion (tree t, tree args, 
tsubst_flags_t complain,
= build_extra_args (pattern, args, complain);
   return t;
 }
-  else if (unsubstituted_packs)
+
+  /* If NEED_LOCAL_SPECIALIZATIONS then we're in a late-specified return
+ type, so create our own local specializations map; the current map is
+ either NULL or (in the case of recursive unification) might have
+ bindings that we don't want to use or alter.  */
+  local_specialization_stack lss (need_local_specializations
+ ? lss_blank : lss_inherit);
+
+  if (unsubstituted_packs)
 {
   /* There were no real arguments, we're just replacing a parameter
 pack with another version of itself. Substitute into the
@@ -12910,16 +12922,6 @@ tsubst_pack_expansion (tree t, tree args, 
tsubst_flags_t complain,
 
   gcc_assert (len >= 0);
 
-  if (need_local_specializations)
-{
-  /* We're in a late-

Re: [Patch, fortran] PR fortran/90350 - ubound ICE on assumed size array even though explicit bound is specified

2020-04-19 Thread Thomas Koenig via Gcc-patches

Hi Jose,

first, thanks for coming on board!

A question: Do you have a copyright assignment yet?  This patch is
probably short enough that it can be accepted without it, but if
you're planning to contribute more (which I certainly hope) then
it would make sense to do this.

Regarding your patch, I have one question: What will happen
with the test case

program artificial
implicit none
integer :: arr(-10:10)
   call asub(arr,size(arr))
end program artificial
subroutine asub(arr,n)
integer,intent(in) :: arr(*)
integer,intent(in) :: n
   write(*,*)'UPPER=',ubound(arr(3:))
   write(*,*)'LOWER=',lbound(arr(3:))
   write(*,*)'SIZE=',size(arr(3:))
end subroutine asub

? In other words, maybe a check on the upper bound
of the last dimension would be better?

Regards

Thomas


[Patch, fortran] PR fortran/90350 - ubound ICE on assumed size array even though explicit bound is specified

2020-04-19 Thread José Rui Faustino de Sousa via Gcc-patches

Hi all!

Proposed patch to Bug 90350 - ubound ICE on assumed size array even 
though explicit bound is specified


Patch tested only on x86_64-pc-linux-gnu.

Bumped into the same problem.

Probably a better fix would be to add an extra step to the reference 
chain reflecting that array-section are explicit-shape arrays not 
whatever that was sectioned. But, although this pattern of problem shows 
up in the code in other places, it may be more trouble than it is worth...


Thank you very much.

Best regards,
José Rui

2020-4-19  José Rui Faustino de Sousa  

 PR fortran/90350
 * simplify.c (simplify_bound): In the case of assumed-size arrays check
 if the reference is to a full array.

2020-4-19  José Rui Faustino de Sousa  

 PR fortran/90350
 * PR90350.f90: New test.


diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c
index d5703e3..4818368 100644
--- a/gcc/fortran/simplify.c
+++ b/gcc/fortran/simplify.c
@@ -4157,6 +4157,7 @@ simplify_bound (gfc_expr *array, gfc_expr *dim, 
gfc_expr *kind, int upper)

 {
   gfc_ref *ref;
   gfc_array_spec *as;
+  ar_type type = AR_UNKNOWN;
   int d;

   if (array->ts.type == BT_CLASS)
@@ -4180,6 +4181,7 @@ simplify_bound (gfc_expr *array, gfc_expr *dim, 
gfc_expr *kind, int upper)

   switch (ref->type)
{
case REF_ARRAY:
+ type = ref->u.ar.type;
  switch (ref->u.ar.type)
{
case AR_ELEMENT:
@@ -4233,7 +4235,10 @@ simplify_bound (gfc_expr *array, gfc_expr *dim, 
gfc_expr *kind, int upper)

   int k;

   /* UBOUND(ARRAY) is not valid for an assumed-size array.  */
-  if (upper && as && as->type == AS_ASSUMED_SIZE)
+  if (upper
+ && type == AR_FULL
+ && as
+ && as->type == AS_ASSUMED_SIZE)
{
  /* An error message will be emitted in
 check_assumed_size_reference (resolve.c).  */
diff --git a/gcc/testsuite/gfortran.dg/PR90350.f90 
b/gcc/testsuite/gfortran.dg/PR90350.f90

new file mode 100644
index 000..2e2cf10
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/PR90350.f90
@@ -0,0 +1,19 @@
+! { dg-do compile }
+!
+! Test the fix for PR90350
+!
+! Contributed by  
+!
+
+program artificial
+implicit none
+integer :: arr(-10:10)
+   call asub(arr,size(arr))
+end program artificial
+subroutine asub(arr,n)
+integer,intent(in) :: arr(*)
+integer,intent(in) :: n
+   write(*,*)'UPPER=',ubound(arr(:n))
+   write(*,*)'LOWER=',lbound(arr(:n))
+   write(*,*)'SIZE=',size(arr(:n))
+end subroutine asub


[committed] libphobos: Merge upstream phobos 99003a75a

2020-04-19 Thread Iain Buclaw via Gcc-patches
Hi,

This patch merges libphobos with upstream phobos 99003a75a.

Fixes hasLength unittest to pass on X32.

Bootstrapped and regression tested on x86_64-linux-gnu with target_board
configurations {-m64,-m32,-mx32}.  Committed to mainline.

Regards
Iain.

---
 libphobos/src/MERGE  | 2 +-
 libphobos/src/std/range/primitives.d | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE
index 7570cd9b9fd..31a053ca2bb 100644
--- a/libphobos/src/MERGE
+++ b/libphobos/src/MERGE
@@ -1,4 +1,4 @@
-fb4f6a713f5b78742f93e072cff6a6c4ecf9323d
+99003a75a883d4ae28b276763f4d1f2a360cf1dd
 
 The first line of this file holds the git revision number of the last
 merge done from the dlang/phobos repository.
diff --git a/libphobos/src/std/range/primitives.d 
b/libphobos/src/std/range/primitives.d
index 1a4e6fb2b91..193ee952cf3 100644
--- a/libphobos/src/std/range/primitives.d
+++ b/libphobos/src/std/range/primitives.d
@@ -1416,12 +1416,12 @@ unittest
 struct A { ulong length; }
 struct B { @property uint length() { return 0; } }
 
-version (X86)
+static if (is(size_t == uint))
 {
 static assert(!hasLength!(A));
 static assert(hasLength!(B));
 }
-else version(X86_64)
+else static if (is(size_t == ulong))
 {
 static assert(hasLength!(A));
 static assert(!hasLength!(B));
-- 
2.20.1



[committed 2/2] d/dmd: Merge upstream dmd ba99ee345 (PR94642)

2020-04-19 Thread Iain Buclaw via Gcc-patches
Hi,

This patch merges the D front-end implementation with dmd upstream
ba99ee345.  Initializes the VectorArrayExp::size field with the correct
value, fixing PR94642.

Bootstrapped and regression tested on x86_64-linux-gnu, and committed to
mainline.

Regards
Iain.

---
 gcc/d/dmd/MERGE| 2 +-
 gcc/d/dmd/expression.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index 2922939a2da..cd3d48ded8e 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@
-09be6ee1439ba12211678f3f1b591d1e986b7be0
+ba99ee345694da61eca7b17d540ff3dc0a56
 
 The first line of this file holds the git revision number of the last
 merge done from the dlang/dmd repository.
diff --git a/gcc/d/dmd/expression.c b/gcc/d/dmd/expression.c
index ccfb4b69a29..c639fd10aae 100644
--- a/gcc/d/dmd/expression.c
+++ b/gcc/d/dmd/expression.c
@@ -5775,7 +5775,7 @@ Expression *VectorExp::syntaxCopy()
 //
 
 VectorArrayExp::VectorArrayExp(Loc loc, Expression *e1)
-: UnaExp(loc, TOKvectorarray, sizeof(VectorExp), e1)
+: UnaExp(loc, TOKvectorarray, sizeof(VectorArrayExp), e1)
 {
 }
 
-- 
2.20.1



[committed 1/2] d/dmd: Merge upstream dmd 09be6ee14 (PR94653)

2020-04-19 Thread Iain Buclaw via Gcc-patches
Hi,

This patch merges the D front-end implementation with dmd upstream
09be6ee14.  Initializes ncost before use, which was caught by valgrind,
fixing PR94653.

Bootstrapped and regression tested on x86_64-linux-gnu, and committed to
mainline.

Regards
Iain.

---
 gcc/d/dmd/MERGE  | 2 +-
 gcc/d/dmd/root/speller.c | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index dc9fb1b8d97..2922939a2da 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@
-799066f498aebcfa420df284cac1f204b1f953a8
+09be6ee1439ba12211678f3f1b591d1e986b7be0
 
 The first line of this file holds the git revision number of the last
 merge done from the dlang/dmd repository.
diff --git a/gcc/d/dmd/root/speller.c b/gcc/d/dmd/root/speller.c
index 2a2e6c015c1..e04ffb38067 100644
--- a/gcc/d/dmd/root/speller.c
+++ b/gcc/d/dmd/root/speller.c
@@ -58,7 +58,7 @@ void *spellerY(const char *seed, size_t seedlen, fp_speller_t 
fp, void *fparg,
 memcpy(buf, seed, index);
 *cost = INT_MAX;
 void* p = NULL;
-int ncost;
+int ncost = 0;
 
 /* Delete at seed[index] */
 if (index < seedlen)
@@ -122,7 +122,7 @@ void *spellerX(const char *seed, size_t seedlen, 
fp_speller_t fp, void *fparg,
 if (!buf)
 return NULL;  // no matches
 }
-int cost = INT_MAX, ncost;
+int cost = INT_MAX, ncost = 0;
 void *p = NULL, *np;
 
 /* Deletions */
-- 
2.20.1



[committed] coroutines, testsuite: Require C++17 for two tests.

2020-04-19 Thread Iain Sandoe
Hi,

While the coroutines implementation, and most of the coroutines
tests, will operate with C++14 or newer, these tests require
facilities introduced in C++17.  Add the target requirement.

Tested on x86_64-darwin16,
applied to master,
thanks
Iain

gcc/testsuite/

2020-04-19  Iain Sandoe  

* g++.dg/coroutines/torture/co-await-17-capture-comp-ref.C: Require
C++17.
* g++.dg/coroutines/torture/co-ret-15-default-return_void.C: Likewise.


diff --git 
a/gcc/testsuite/g++.dg/coroutines/torture/co-await-17-capture-comp-ref.C 
b/gcc/testsuite/g++.dg/coroutines/torture/co-await-17-capture-comp-ref.C
index 93a43fbd298..c5829c455a5 100644
--- a/gcc/testsuite/g++.dg/coroutines/torture/co-await-17-capture-comp-ref.C
+++ b/gcc/testsuite/g++.dg/coroutines/torture/co-await-17-capture-comp-ref.C
@@ -1,4 +1,4 @@
-//  { dg-do run }
+//  { dg-do run { target c++17 } }
 
 #include "../coro.h"
 
diff --git 
a/gcc/testsuite/g++.dg/coroutines/torture/co-ret-15-default-return_void.C 
b/gcc/testsuite/g++.dg/coroutines/torture/co-ret-15-default-return_void.C
index e600feae129..99910f33f53 100644
--- a/gcc/testsuite/g++.dg/coroutines/torture/co-ret-15-default-return_void.C
+++ b/gcc/testsuite/g++.dg/coroutines/torture/co-ret-15-default-return_void.C
@@ -1,4 +1,4 @@
-// { dg-do run }
+// { dg-do run { target c++17 } }
 //
 // Check if default return_void is insert at correct position.
 #include 



[committed] i386: Remove unneeded assignments when triggering SSE exceptions

2020-04-19 Thread Uros Bizjak via Gcc-patches
According to "Intel 64 and IA32 Arch SDM, Vol. 3:

"Because SIMD floating-point exceptions are precise and occur immediately,
the situation does not arise where an x87 FPU instruction, a WAIT/FWAIT
instruction, or another SSE/SSE2/SSE3 instruction will catch a pending
unmasked SIMD floating-point exception."

This is also confirmed by the following testcase:

--cut here--

#define _GNU_SOURCE
#include 
#include 
#include 
#include 

static int counter;

void
__attribute__((noinline))
__divbyzero_ex (void)
{
  float f = 1.0f, g = 0.0f;
#ifdef __SSE_MATH__
  asm volatile ("%vdivss\t{%1, %d0|%d0, %1}" : "+x" (f) : "xm" (g));
#else
  asm volatile ("fdivp\t%1" : "+t" (f) : "u" (g) : "st(1)");
  /* No need for fwait, exception is triggered by emitted fstp.  */
#endif
}

void handler (int i)
{
  exit (0);
}

int
main ()
{
  struct sigaction s;
  sigemptyset (&s.sa_mask);
  s.sa_handler = handler;
  s.sa_flags = 0;
  sigaction (SIGFPE, &s, NULL);

  feenableexcept (FE_DIVBYZERO);

  __divbyzero_ex ();

  abort ();
}
--cut here--

libgcc/ChangeLog:

2020-04-19  Uroš Bizjak  

* config/i386/sfp-exceptions.c (__sfp_handle_exceptions) [__SSE_MATH__]:
Remove unneeded assignments to volatile memory.

libatomic/ChangeLog:

2020-04-19  Uroš Bizjak  

* config/x86/fenv.c (__atomic_feraiseexcept) [__SSE_MATH__]:
Remove unneeded assignments to volatile memory.

libgfortran/ChangeLog:

2020-04-19  Uroš Bizjak  

* config/fpu-387.h (local_feraiseexcept) [__SSE_MATH__]:
Remove unneeded assignments to volatile memory.

Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.

Committed to mainline.

Uros.
diff --git a/libatomic/config/x86/fenv.c b/libatomic/config/x86/fenv.c
index 7828162c68b..d7b1bbe5ea1 100644
--- a/libatomic/config/x86/fenv.c
+++ b/libatomic/config/x86/fenv.c
@@ -57,9 +57,7 @@ __atomic_feraiseexcept (int excepts)
 {
   float f = 0.0f;
 #ifdef __SSE_MATH__
-  volatile float r __attribute__ ((unused));
   asm volatile ("%vdivss\t{%0, %d0|%d0, %0}" : "+x" (f));
-  r = f; /* Needed to trigger exception.   */
 #else
   asm volatile ("fdiv\t{%y0, %0|%0, %y0}" : "+t" (f));
   /* No need for fwait, exception is triggered by emitted fstp.  */
@@ -77,9 +75,7 @@ __atomic_feraiseexcept (int excepts)
 {
   float f = 1.0f, g = 0.0f;
 #ifdef __SSE_MATH__
-  volatile float r __attribute__ ((unused));
   asm volatile ("%vdivss\t{%1, %d0|%d0, %1}" : "+x" (f) : "xm" (g));
-  r = f; /* Needed to trigger exception.   */
 #else
   asm volatile ("fdivs\t%1" : "+t" (f) : "m" (g));
   /* No need for fwait, exception is triggered by emitted fstp.  */
@@ -105,9 +101,7 @@ __atomic_feraiseexcept (int excepts)
 {
   float f = 1.0f, g = 3.0f;
 #ifdef __SSE_MATH__
-  volatile float r __attribute__ ((unused));
   asm volatile ("%vdivss\t{%1, %d0|%d0, %1}" : "+x" (f) : "xm" (g));
-  r = f; /* Needed to trigger exception.   */
 #else
   asm volatile ("fdivs\t%1" : "+t" (f) : "m" (g));
   /* No need for fwait, exception is triggered by emitted fstp.  */
diff --git a/libgcc/config/i386/sfp-exceptions.c 
b/libgcc/config/i386/sfp-exceptions.c
index c994491c650..31a24ced704 100644
--- a/libgcc/config/i386/sfp-exceptions.c
+++ b/libgcc/config/i386/sfp-exceptions.c
@@ -48,9 +48,7 @@ __sfp_handle_exceptions (int _fex)
 {
   float f = 0.0f;
 #ifdef __SSE_MATH__
-  volatile float r __attribute__ ((unused));
   asm volatile ("%vdivss\t{%0, %d0|%d0, %0}" : "+x" (f));
-  r = f; /* Needed to trigger exception.   */
 #else
   asm volatile ("fdiv\t{%y0, %0|%0, %y0}" : "+t" (f));
   /* No need for fwait, exception is triggered by emitted fstp.  */
@@ -68,9 +66,7 @@ __sfp_handle_exceptions (int _fex)
 {
   float f = 1.0f, g = 0.0f;
 #ifdef __SSE_MATH__
-  volatile float r __attribute__ ((unused));
   asm volatile ("%vdivss\t{%1, %d0|%d0, %1}" : "+x" (f) : "xm" (g));
-  r = f; /* Needed to trigger exception.   */
 #else
   asm volatile ("fdivs\t%1" : "+t" (f) : "m" (g));
   /* No need for fwait, exception is triggered by emitted fstp.  */
@@ -96,9 +92,7 @@ __sfp_handle_exceptions (int _fex)
 {
   float f = 1.0f, g = 3.0f;
 #ifdef __SSE_MATH__
-  volatile float r __attribute__ ((unused));
   asm volatile ("%vdivss\t{%1, %d0|%d0, %1}" : "+x" (f) : "xm" (g));
-  r = f; /* Needed to trigger exception.   */
 #else
   asm volatile ("fdivs\t%1" : "+t" (f) : "m" (g));
   /* No need for fwait, exception is triggered by emitted fstp.  */
diff --git a/libgfortran/config/fpu-387.h b/libgfortran/config/fpu-387.h
index 623e878b482..13be2045b72 100644
--- a/libgfortran/config/fpu-387.h
+++ b/libgfortran/config/fpu-387.h
@@ -103,9 +103,7 @@ local_feraiseexcept (int excepts)
 {
   float f = 0.0f;
 #ifdef __SSE_MATH__
-  volatile float r __attribute__ ((unused));
   __asm__ __volatile__ ("%vdivss\t{%0, %d0|%d0, %0}" : "+x" (f));
-  r = f; /* Needed to trigger excep

Re: [PATCH] c, objc: Fix up c_parser_objc_selector_arg after CPP_SCOPE changes [PR94637]

2020-04-19 Thread Iain Sandoe

Hi Jakub,

thanks for looking at this.

Jakub Jelinek  wrote:


Similarly to inline asm, :: (or any other number of consecutive colons) can
appear in ObjC @selector argument and with the introduction of CPP_SCOPE
into the C FE, we need to trat CPP_SCOPE as two CPP_COLON tokens.
The C++ FE does that already that way.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?


OK from Objective-C point of view,
thanks
Iain



2020-04-19  Jakub Jelinek  

PR objc/94637
* c-parser.c (c_parser_objc_selector_arg): Handle CPP_SCOPE like
two CPP_COLON tokens.

* objc.dg/pr94637.m: New test.

--- gcc/c/c-parser.c.jj 2020-04-17 16:59:28.727193750 +0200
+++ gcc/c/c-parser.c2020-04-18 23:27:04.623963647 +0200
@@ -11782,15 +11782,28 @@ c_parser_objc_selector_arg (c_parser *pa
{
  tree sel = c_parser_objc_selector (parser);
  tree list = NULL_TREE;
-  if (sel && c_parser_next_token_is_not (parser, CPP_COLON))
+  if (sel
+  && c_parser_next_token_is_not (parser, CPP_COLON)
+  && c_parser_next_token_is_not (parser, CPP_SCOPE))
return sel;
  while (true)
{
-  if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
-   return list;
-  list = chainon (list, build_tree_list (sel, NULL_TREE));
+  if (c_parser_next_token_is (parser, CPP_SCOPE))
+   {
+ c_parser_consume_token (parser);
+ list = chainon (list, build_tree_list (sel, NULL_TREE));
+ list = chainon (list, build_tree_list (NULL_TREE, NULL_TREE));
+   }
+  else
+   {
+ if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
+   return list;
+ list = chainon (list, build_tree_list (sel, NULL_TREE));
+   }
  sel = c_parser_objc_selector (parser);
-  if (!sel && c_parser_next_token_is_not (parser, CPP_COLON))
+  if (!sel
+ && c_parser_next_token_is_not (parser, CPP_COLON)
+ && c_parser_next_token_is_not (parser, CPP_SCOPE))
break;
}
  return list;
--- gcc/testsuite/objc.dg/pr94637.m.jj  2020-04-18 23:26:01.925898608 +0200
+++ gcc/testsuite/objc.dg/pr94637.m 2020-04-18 23:25:57.197969111 +0200
@@ -0,0 +1,10 @@
+/* PR objc/94637 */
+/* { dg-do compile } */
+
+#include 
+
+SEL
+foo ()
+{
+  return @selector(example::);
+}

Jakub





[committed] d: Fix FAIL in gdc.dg/runnable.d on X32 targets (PR94609)

2020-04-19 Thread Iain Buclaw via Gcc-patches
Hi,

Patch fixes test failure seen on X32 where a nested struct was passed in
registers, rather than via invisible reference.  Now, all non-POD
structs are passed by invisible reference, not just those with a
user-defined copy constructor/destructor.

Bootstrapped and regression tested on x86_64-linux-gnu with
--target_board=unix\{,-m32,-mx32\}.  Committed to mainline.

Regards
Iain

---
gcc/d/ChangeLog:

PR d/94609
* d-codegen.cc (argument_reference_p): Don't check TREE_ADDRESSABLE.
(type_passed_as): Build reference type if TREE_ADDRESSABLE.
* d-convert.cc (convert_for_argument): Build explicit TARGET_EXPR if
needed for arguments passed by invisible reference.
* types.cc (TypeVisitor::visit (TypeStruct *)): Mark all structs that
are not POD as TREE_ADDRESSABLE.
---
 gcc/d/d-codegen.cc |  6 +-
 gcc/d/d-convert.cc | 15 +++
 gcc/d/types.cc |  2 +-
 3 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc
index 66af2b4da30..8dc1ab264f8 100644
--- a/gcc/d/d-codegen.cc
+++ b/gcc/d/d-codegen.cc
@@ -180,10 +180,6 @@ argument_reference_p (Parameter *arg)
   if (tb->ty == Treference || arg->storageClass & (STCout | STCref))
 return true;
 
-  tree type = build_ctype (arg->type);
-  if (TREE_ADDRESSABLE (type))
-return true;
-
   return false;
 }
 
@@ -211,7 +207,7 @@ type_passed_as (Parameter *arg)
   tree type = build_ctype (arg->type);
 
   /* Parameter is passed by reference.  */
-  if (argument_reference_p (arg))
+  if (TREE_ADDRESSABLE (type) || argument_reference_p (arg))
 return build_reference_type (type);
 
   return type;
diff --git a/gcc/d/d-convert.cc b/gcc/d/d-convert.cc
index 533bbabd168..9ee149b8386 100644
--- a/gcc/d/d-convert.cc
+++ b/gcc/d/d-convert.cc
@@ -677,6 +677,21 @@ convert_for_argument (tree expr, Parameter *arg)
   /* Front-end shouldn't automatically take the address.  */
   return convert (type_passed_as (arg), build_address (expr));
 }
+  else if (TREE_ADDRESSABLE (TREE_TYPE (expr)))
+{
+  /* Type is a struct passed by invisible reference.  */
+  Type *t = arg->type->toBasetype ();
+  gcc_assert (t->ty == Tstruct);
+  StructDeclaration *sd = ((TypeStruct *) t)->sym;
+
+  /* Nested structs also have ADDRESSABLE set, but if the type has
+neither a copy constructor nor a destructor available, then we
+need to take care of copying its value before passing it.  */
+  if (!sd->postblit && !sd->dtor)
+   expr = force_target_expr (expr);
+
+  return convert (type_passed_as (arg), build_address (expr));
+}
 
   return expr;
 }
diff --git a/gcc/d/types.cc b/gcc/d/types.cc
index e0e770af325..f6ae5740f01 100644
--- a/gcc/d/types.cc
+++ b/gcc/d/types.cc
@@ -915,7 +915,7 @@ public:
 /* For structs with a user defined postblit or a destructor,
also set TREE_ADDRESSABLE on the type and all variants.
This will make the struct be passed around by reference.  */
-if (t->sym->postblit || t->sym->dtor)
+if (!t->sym->isPOD ())
   {
for (tree tv = t->ctype; tv != NULL_TREE; tv = TYPE_NEXT_VARIANT (tv))
  TREE_ADDRESSABLE (tv) = 1;
-- 
2.20.1