[PATCH] c++: C++20 DR 2237, disallow simple-template-id in cdtor.

2020-04-04 Thread Marek Polacek via Gcc-patches
This patch implements DR 2237 which says that a simple-template-id is
no longer valid as the declarator-id of a constructor or destructor;
see .  It is not explicitly
stated but out-of-line destructors with a simple-template-id are also
meant to be ill-formed now.  (Out-of-line constructors like that are
invalid since DR1435 I think.)  This change only applies to C++20; it
is not a DR against C++17.

I'm not crazy about the diagnostic in constructors but ISTM that
cp_parser_constructor_declarator_p shouldn't print errors.

Does it seem reasonable to apply this now or should I defer to GCC 11?

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

2020-04-04  Marek Polacek  

DR 2237
* parser.c (cp_parser_unqualified_id): Reject simple-template-id as
the declarator-id of a destructor.
(cp_parser_constructor_declarator_p): Reject simple-template-id as
the declarator-id of a constructor.

* g++.dg/DRs/dr2237.C: New test.
* g++.dg/parse/constructor2.C: Add dg-error for C++20.
* g++.dg/parse/dtor12.C: Likewise.
* g++.dg/parse/dtor4.C: Likewise.
* g++.dg/template/dtor4.C: Adjust dg-error.
* g++.dg/template/error34.C: Likewise.
* g++.old-deja/g++.other/inline15.C: Only run for C++17 and lesses.
* g++.old-deja/g++.pt/ctor2.C: Add dg-error for C++20.
---
 gcc/cp/parser.c| 16 
 gcc/testsuite/g++.dg/DRs/dr2237.C  | 18 ++
 gcc/testsuite/g++.dg/parse/constructor2.C  |  4 ++--
 gcc/testsuite/g++.dg/parse/dtor12.C|  2 +-
 gcc/testsuite/g++.dg/parse/dtor4.C |  2 +-
 gcc/testsuite/g++.dg/template/dtor4.C  |  2 +-
 gcc/testsuite/g++.dg/template/error34.C| 10 +-
 .../g++.old-deja/g++.other/inline15.C  |  2 +-
 gcc/testsuite/g++.old-deja/g++.pt/ctor2.C  |  2 +-
 9 files changed, 46 insertions(+), 12 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/DRs/dr2237.C

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 7e5921e039f..810edfa87a9 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -6114,6 +6114,16 @@ cp_parser_unqualified_id (cp_parser* parser,
return build_min_nt_loc (loc, BIT_NOT_EXPR, make_auto ());
  }
 
+   /* DR 2237 (C++20 only): A simple-template-id is no longer valid as the
+  declarator-id of a constructor or destructor.  */
+   if (token->type == CPP_TEMPLATE_ID && cxx_dialect >= cxx2a)
+ {
+   if (!cp_parser_uncommitted_to_tentative_parse_p (parser))
+ error_at (tilde_loc, "template-id not allowed for destructor");
+   cp_parser_simulate_error (parser);
+   return error_mark_node;
+ }
+
/* If there was an explicit qualification (S::~T), first look
   in the scope given by the qualification (i.e., S).
 
@@ -28675,6 +28685,12 @@ cp_parser_constructor_declarator_p (cp_parser *parser, 
cp_parser_flags flags,
   if (!constructor_name_p (id, nested_name_specifier))
constructor_p = false;
 }
+  /* DR 2237 (C++20 only): A simple-template-id is no longer valid as the
+ declarator-id of a constructor or destructor.  */
+  else if (constructor_p
+  && cxx_dialect >= cxx2a
+  && cp_lexer_next_token_is (parser->lexer, CPP_TEMPLATE_ID))
+constructor_p = false;
   /* If we still think that this might be a constructor-declarator,
  look for a class-name.  */
   else if (constructor_p)
diff --git a/gcc/testsuite/g++.dg/DRs/dr2237.C 
b/gcc/testsuite/g++.dg/DRs/dr2237.C
new file mode 100644
index 000..17abdf179c1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/DRs/dr2237.C
@@ -0,0 +1,18 @@
+// DR 2237 - Can a template-id name a constructor?
+
+template
+struct X {
+  X(); // { dg-error "expected" "" { target c++2a } }
+  X(int); // OK, injected-class-name used
+  ~X(); // { dg-error "template-id not allowed for destructor" "" { target 
c++2a } }
+};
+
+// ill-formed since DR1435
+template X::X() {} // { dg-error "names the constructor|as 
no template constructors" }
+template X::~X() {} // { dg-error "template-id not allowed 
for destructor" "" { target c++2a } }
+
+struct Q {
+  // ill-formed since DR1435
+  template friend X::X(); // { dg-error "names the 
constructor|as no template constructors" }
+  template friend X::~X(); // { dg-error "template-id not 
allowed for destructor" "" { target c++2a } }
+};
diff --git a/gcc/testsuite/g++.dg/parse/constructor2.C 
b/gcc/testsuite/g++.dg/parse/constructor2.C
index e514e9397e9..87007e9c715 100644
--- a/gcc/testsuite/g++.dg/parse/constructor2.C
+++ b/gcc/testsuite/g++.dg/parse/constructor2.C
@@ -5,7 +5,7 @@ class T
 { 
 public: 
   T(short,short f=0) {} 
-  T(int f) {} 
-  T(int f=0,const char* b=0) {} 
+  T(int f) {} // { dg-error "expected" "" { target c++2a } }
+  T(int f=0,const char* b=0) {} // { dg-error "expected" "" { target 

Re: [PATCH] i386: Simplify {, v}ph{add, sub{, s}{w, d} insn patterns [PR94460]

2020-04-04 Thread Uros Bizjak via Gcc-patches
On Sat, Apr 4, 2020 at 12:41 AM Jakub Jelinek  wrote:
>
> Hi!
>
> As mentioned in the previous PR94460 patch, the RTL patterns look too
> large/complicated, we can simplify them by just performing two 2 arg
> permutations to move the arguments into the right spots and then just
> doing the plus/minus (or signed saturation version thereof).
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for stage1?
>
> 2020-04-04  Jakub Jelinek  
>
> PR target/94460
> * config/i386/sse.md (avx2_phwv16hi3,
> ssse3_phwv8hi3, 
> ssse3_phwv4hi3,
> avx2_phdv8si3, ssse3_phdv4si3,
> ssse3_phdv2si3): Simplify RTL patterns.

OK.

Thanks,
Uros.

> --- gcc/config/i386/sse.md.jj   2020-04-03 10:21:51.110564277 +0200
> +++ gcc/config/i386/sse.md  2020-04-03 11:55:04.455963720 +0200
> @@ -16038,73 +16038,23 @@ (define_code_iterator ssse3_plusminus [p
>
>  (define_insn "avx2_phwv16hi3"
>[(set (match_operand:V16HI 0 "register_operand" "=x")
> -   (vec_concat:V16HI
> - (vec_concat:V8HI
> -   (vec_concat:V4HI
> - (vec_concat:V2HI
> -   (ssse3_plusminus:HI
> - (vec_select:HI
> -   (match_operand:V16HI 1 "register_operand" "x")
> -   (parallel [(const_int 0)]))
> - (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
> -   (ssse3_plusminus:HI
> - (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
> - (vec_select:HI (match_dup 1) (parallel [(const_int 3)]
> - (vec_concat:V2HI
> -   (ssse3_plusminus:HI
> - (vec_select:HI (match_dup 1) (parallel [(const_int 4)]))
> - (vec_select:HI (match_dup 1) (parallel [(const_int 5)])))
> -   (ssse3_plusminus:HI
> - (vec_select:HI (match_dup 1) (parallel [(const_int 6)]))
> - (vec_select:HI (match_dup 1) (parallel [(const_int 7)])
> -   (vec_concat:V4HI
> - (vec_concat:V2HI
> -   (ssse3_plusminus:HI
> - (vec_select:HI
> -   (match_operand:V16HI 2 "nonimmediate_operand" "xm")
> -   (parallel [(const_int 0)]))
> - (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
> -   (ssse3_plusminus:HI
> - (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
> - (vec_select:HI (match_dup 2) (parallel [(const_int 3)]
> - (vec_concat:V2HI
> -   (ssse3_plusminus:HI
> - (vec_select:HI (match_dup 2) (parallel [(const_int 4)]))
> - (vec_select:HI (match_dup 2) (parallel [(const_int 5)])))
> -   (ssse3_plusminus:HI
> - (vec_select:HI (match_dup 2) (parallel [(const_int 6)]))
> - (vec_select:HI (match_dup 2) (parallel [(const_int 7)]))
> - (vec_concat:V8HI
> -   (vec_concat:V4HI
> - (vec_concat:V2HI
> -   (ssse3_plusminus:HI
> - (vec_select:HI (match_dup 1) (parallel [(const_int 8)]))
> - (vec_select:HI (match_dup 1) (parallel [(const_int 9)])))
> -   (ssse3_plusminus:HI
> - (vec_select:HI (match_dup 1) (parallel [(const_int 10)]))
> - (vec_select:HI (match_dup 1) (parallel [(const_int 11)]
> - (vec_concat:V2HI
> -   (ssse3_plusminus:HI
> - (vec_select:HI (match_dup 1) (parallel [(const_int 12)]))
> - (vec_select:HI (match_dup 1) (parallel [(const_int 13)])))
> -   (ssse3_plusminus:HI
> - (vec_select:HI (match_dup 1) (parallel [(const_int 14)]))
> - (vec_select:HI (match_dup 1) (parallel [(const_int 15)])
> -   (vec_concat:V4HI
> - (vec_concat:V2HI
> -   (ssse3_plusminus:HI
> - (vec_select:HI (match_dup 2) (parallel [(const_int 8)]))
> - (vec_select:HI (match_dup 2) (parallel [(const_int 9)])))
> -   (ssse3_plusminus:HI
> - (vec_select:HI (match_dup 2) (parallel [(const_int 10)]))
> - (vec_select:HI (match_dup 2) (parallel [(const_int 11)]
> - (vec_concat:V2HI
> -   (ssse3_plusminus:HI
> - (vec_select:HI (match_dup 2) (parallel [(const_int 12)]))
> - (vec_select:HI (match_dup 2) (parallel [(const_int 13)])))
> -   (ssse3_plusminus:HI
> - (vec_select:HI (match_dup 2) (parallel [(const_int 14)]))
> - (vec_select:HI (match_dup 2) (parallel [(const_int 
> 15)]]
> +   (ssse3_plusminus:V16HI
> + (vec_select:V16HI
> +   (vec_concat:V32HI
> + (match_operand:V16HI 1 "register_operand" "x")
> + (match_operand:V16HI 2 "nonimmediate_operand" "xm"))
> +   (parallel
> +

Re: libgcc patch committed: Avoid hooks in split-stack code

2020-04-04 Thread Eric Botcazou
> I committed this patch.

Works for me, thanks for the quick fix!

-- 
Eric Botcazou


Re: libgcc patch committed: Avoid hooks in split-stack code

2020-04-04 Thread Ian Lance Taylor via Gcc-patches
On Sat, Apr 4, 2020 at 1:35 PM H.J. Lu  wrote:
>
> On Sat, Apr 4, 2020 at 1:28 PM Eric Botcazou  wrote:
> >
> > > Hmmm, sorry about that.  Which target?  x86_64?  It does seem that
> > > glibc consolidated mmap implementations in 2.26, but even in 2.22 I
> > > see definitions for __mmap.
> >
>
> commit fa872e1b6210e81e60d6029429f0a083b8eab26e
> Author: Adhemerval Zanella 
> Date:   Fri Dec 2 16:32:28 2016 -0200
>
> Clean pthread functions namespaces for C11 threads
> ...
> * misc/Versions (libc): Export __mmap, __munmap, __mprotect,
> __sched_get_priority_min, and __sched_get_priority_max under
> GLIBC_PRIVATE.
>
> was checked into glibc 2.26.

Thanks.

I committed this patch.

Ian
diff --git a/libgcc/generic-morestack.c b/libgcc/generic-morestack.c
index bb9f67a7366..fa2062e2bb3 100644
--- a/libgcc/generic-morestack.c
+++ b/libgcc/generic-morestack.c
@@ -60,7 +60,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If 
not, see
glibc on GNU/Linux we can avoid the problem by calling __mmap and
__munmap.  */
 
-#ifdef __gnu_linux__
+#if defined(__gnu_linux__) && (__GLIBC__ > 2 || (__GLIBC__ == 2 && 
__GLIBC_MINOR__ >= 26))
 
 extern void *__mmap (void *, size_t, int, int, int, off_t);
 extern int __munmap (void *, size_t);


Re: libgcc patch committed: Avoid hooks in split-stack code

2020-04-04 Thread H.J. Lu via Gcc-patches
On Sat, Apr 4, 2020 at 1:28 PM Eric Botcazou  wrote:
>
> > Hmmm, sorry about that.  Which target?  x86_64?  It does seem that
> > glibc consolidated mmap implementations in 2.26, but even in 2.22 I
> > see definitions for __mmap.
>

commit fa872e1b6210e81e60d6029429f0a083b8eab26e
Author: Adhemerval Zanella 
Date:   Fri Dec 2 16:32:28 2016 -0200

Clean pthread functions namespaces for C11 threads
...
* misc/Versions (libc): Export __mmap, __munmap, __mprotect,
__sched_get_priority_min, and __sched_get_priority_max under
GLIBC_PRIVATE.

was checked into glibc 2.26.

-- 
H.J.


Re: libgcc patch committed: Avoid hooks in split-stack code

2020-04-04 Thread Eric Botcazou
> Hmmm, sorry about that.  Which target?  x86_64?  It does seem that
> glibc consolidated mmap implementations in 2.26, but even in 2.22 I
> see definitions for __mmap.

GNU C Library (GNU libc) stable release version 2.22 (git bbab82c25da9), by 
Roland McGrath et al.
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Configured for x86_64-suse-linux.
Compiled by GNU CC version 4.8.5.
Available extensions:
crypt add-on version 2.1 by Michael Glad and others
GNU Libidn by Simon Josefsson
Native POSIX Threads Library by Ulrich Drepper et al
BIND-8.2.3-T5B
libc ABIs: UNIQUE IFUNC
For bug reporting instructions, please see:
.

eric@polaris:~/build/gcc/native> readelf -s /lib64/libc.so.6 | grep mmap
   317: 000e8ac036 FUNCWEAK   DEFAULT   13 mmap64@@GLIBC_2.2.5
   657: 000e8ac036 FUNCWEAK   DEFAULT   13 mmap@@GLIBC_2.2.5
   332: 00070f00   320 FUNCLOCAL  DEFAULT   13 
_IO_wfile_underflow_mmap
   364: 00075310   453 FUNCLOCAL  DEFAULT   13 mmap_remap_check
   365: 000754f090 FUNCLOCAL  DEFAULT   13 _IO_file_sync_mmap
   366: 00075550   306 FUNCLOCAL  DEFAULT   13 decide_maybe_mmap
   368: 000757a0   238 FUNCLOCAL  DEFAULT   13 
_IO_file_xsgetn_mmap
  1727: 0039e5c0   168 OBJECT  LOCAL  DEFAULT   28 _IO_file_jumps_mmap
  2012: 000e8ac036 FUNCLOCAL  DEFAULT   13 __GI_mmap
  2065: 00075a80   224 FUNCLOCAL  DEFAULT   13 
_IO_file_seekoff_mmap
  2449: 000752c074 FUNCLOCAL  DEFAULT   13 _IO_file_close_mmap
  2476: 000e8ac036 FUNCLOCAL  DEFAULT   13 __GI_mmap64
  2520: 0006b04063 FUNCLOCAL  DEFAULT   13 __fopen_maybe_mmap
  2605: 000e8ac036 FUNCLOCAL  DEFAULT   13 __GI___mmap64
  2742: 000e8ac036 FUNCLOCAL  DEFAULT   13 __GI___mmap
  2993: 000e8ac036 FUNCLOCAL  DEFAULT   13 __mmap64
  3161: 000e8ac036 FUNCLOCAL  DEFAULT   13 __mmap
  3304: 00074d1093 FUNCLOCAL  DEFAULT   13 
_IO_file_setbuf_mmap
  3351: 00075b6081 FUNCLOCAL  DEFAULT   13 
_IO_file_underflow_mmap
  3365: 0039e500   168 OBJECT  LOCAL  DEFAULT   28 
_IO_file_jumps_maybe_mmap
  3483: 0039e140   168 OBJECT  LOCAL  DEFAULT   28 
_IO_wfile_jumps_mmap
  5919: 000e8ac036 FUNCWEAK   DEFAULT   13 mmap64
  6128: 000e8ac036 FUNCWEAK   DEFAULT   13 mmap

-- 
Eric Botcazou


Re: libgcc patch committed: Avoid hooks in split-stack code

2020-04-04 Thread Ian Lance Taylor via Gcc-patches
On Sat, Apr 4, 2020 at 10:10 AM Eric Botcazou  wrote:
>
> > 2020-04-03  Ian Lance Taylor  
> >
> > * generic-morestack.c: On GNU/Linux use __mmap/__munmap rather
> > than mmap/munmap, to avoid hooks.
>
> This breaks the build of gotools for me with undefined references to __mmap
> and __munmap from libgcc/generic-morestack.c (it is with glibc 2.22).

Hmmm, sorry about that.  Which target?  x86_64?  It does seem that
glibc consolidated mmap implementations in 2.26, but even in 2.22 I
see definitions for __mmap.

Ian


[pushed] c++: Mangling of dependent conversions [PR91377]

2020-04-04 Thread Jason Merrill via Gcc-patches
We skip over other conversion codes when mangling expressions, we should do
the same with IMPLICIT_CONV_EXPR.

Tested x86_64-pc-linux-gnu, applying to trunk/9/8.

gcc/cp/ChangeLog
2020-04-04  Jason Merrill  

PR c++/91377
* mangle.c (write_expression): Skip IMPLICIT_CONV_EXPR.
---
 gcc/cp/mangle.c |  1 +
 gcc/testsuite/g++.dg/abi/mangle75.C | 13 +
 2 files changed, 14 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/abi/mangle75.C

diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index 1fc78bfa753..9e39cfd8dba 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -2875,6 +2875,7 @@ write_expression (tree expr)
   /* Skip NOP_EXPR and CONVERT_EXPR.  They can occur when (say) a pointer
  argument is converted (via qualification conversions) to another type.  */
   while (CONVERT_EXPR_CODE_P (code)
+|| code == IMPLICIT_CONV_EXPR
 || location_wrapper_p (expr)
 /* Parentheses aren't mangled.  */
 || code == PAREN_EXPR
diff --git a/gcc/testsuite/g++.dg/abi/mangle75.C 
b/gcc/testsuite/g++.dg/abi/mangle75.C
new file mode 100644
index 000..f2661997a33
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/mangle75.C
@@ -0,0 +1,13 @@
+// PR c++/91377
+// { dg-do compile { target c++11 } }
+
+struct f {
+  static constexpr int d = 3;
+  typedef int e;
+};
+template  struct x { };
+template  using n = x;
+template  auto v() -> n;
+void af() { v(); }
+
+// { dg-final { scan-assembler "_Z1vI1fE1xIXplLi0EsrT_1dEEv" } }

base-commit: 21e28527130a89491f848dfb5019afa01b252479
-- 
2.18.1



Re: [PATCH]Microblaze: Fixed missing save of r18 in fast_interrupt.

2020-04-04 Thread Michael Eager

OK to apply.

On 4/4/20 2:18 AM, Nagaraju Mekala wrote:

Hello All,

Fixed missing save of r18 in fast_interrupt.
Register 18 is used as a clobber register, and must be stored when entering a 
fast_interrupt. Before this fix, register 18 was only saved if it was used 
directly in the interrupt function.
 
However, if the fast_interrupt function called a function that used r18, the register would not be saved, and thus be mangled upon returning from the interrupt.
 
Changelog

 2020-04-04  Klaus Petersen 
  * gcc/config/microblaze/microblaze.c: Check for fast_interrupt in
 microblaze_must_save_register.

 Signed-off-by: Klaus Petersen 
 Signed-off-by :Nagaraju Mekala 

diff --git a/gcc/config/microblaze/microblaze.c 
b/gcc/config/microblaze/microblaze.c
index b4754b1..67e393d 100644
--- a/gcc/config/microblaze/microblaze.c
+++ b/gcc/config/microblaze/microblaze.c
@@ -2035,7 +2035,7 @@ microblaze_must_save_register (int regno)
  {
if (df_regs_ever_live_p (regno)
   || regno == MB_ABI_MSR_SAVE_REG
- || (interrupt_handler
+ || ((interrupt_handler || fast_interrupt)
&& (regno == MB_ABI_ASM_TEMP_REGNUM
   || regno == MB_ABI_EXCEPTION_RETURN_ADDR_REGNUM)))
 return 1;

Attached is the patch.

Thanks
Nagaraju



--
Michael Eagerea...@eagercon.com
1960 Park Blvd., Palo Alto, CA 94306


Re: [PATCH]Microblaze: Modified trap instruction

2020-04-04 Thread Michael Eager

OK to apply.

On 4/4/20 1:59 AM, Nagaraju Mekala wrote:

Hello All,

 There is a bug in trap instruction generation.
 Instead of "bri 0" instruction "brki r0, -1" was used, corrected it now.
 
 ChangeLog:

 2020-04-04 Nagaraju Mekala 
 
 * gcc/config/microblaze/microblaze.md

 (trap): update in the pattern
 * gcc/testsuite/gcc.target/microblaze/others/builtin-trap.c
 (dg-final): update in the scan-assembler instruction
 
 Signed-off-by :Nagaraju Mekala 


diff --git a/gcc/config/microblaze/microblaze.md 
b/gcc/config/microblaze/microblaze.md
index 1970cc6..7049acd 100644
--- a/gcc/config/microblaze/microblaze.md
+++ b/gcc/config/microblaze/microblaze.md
@@ -2303,7 +2303,7 @@
  (define_insn "trap"
[(trap_if (const_int 1) (const_int 0))]
""
-  "brki\tr0,-1"
+  "bri\t0"
   [(set_attr "type" "trap")]
  )
  
diff --git a/gcc/testsuite/gcc.target/microblaze/others/builtin-trap.c b/gcc/testsuite/gcc.target/microblaze/others/builtin-trap.c

index fdcde1f..580b4db 100644
--- a/gcc/testsuite/gcc.target/microblaze/others/builtin-trap.c
+++ b/gcc/testsuite/gcc.target/microblaze/others/builtin-trap.c
@@ -5,4 +5,4 @@ void trap ()
__builtin_trap ();
  }
  
-/* { dg-final { scan-assembler "brki\tr0,-1" } } */

\ No newline at end of file
+/* { dg-final { scan-assembler "bri\t0" } } */

Attached is the patch.

Thanks
Nagaraju



--
Michael Eagerea...@eagercon.com
1960 Park Blvd., Palo Alto, CA 94306


Re: [PATCH v2] c++: Fix crash in gimplifier with paren init of aggregates [PR94155]

2020-04-04 Thread Marek Polacek via Gcc-patches
On Fri, Apr 03, 2020 at 10:39:49PM -0400, Jason Merrill via Gcc-patches wrote:
> On 4/3/20 9:08 PM, Marek Polacek wrote:
> > On Fri, Apr 03, 2020 at 03:01:37PM -0400, Jason Merrill via Gcc-patches 
> > wrote:
> > > On 3/30/20 4:28 PM, Marek Polacek wrote:
> > > > Here we crash in the gimplifier because gimplify_init_ctor_eval doesn't
> > > > expect null indexes for a constructor:
> > > > 
> > > > /* ??? Here's to hoping the front end fills in all of the 
> > > > indices,
> > > >so we don't have to figure out what's missing ourselves.  */
> > > > gcc_assert (purpose);
> > > > 
> > > > The indexes weren't filled because we never called reshape_init: for
> > > > a constructor that represents parenthesized initialization of an
> > > > aggregate we don't allow brace elision or designated initializers.  So
> > > > fill in the indexes manually, here we have an array, and we can simply
> > > > assign indexes starting from 0.
> > > > 
> > > > Bootstrapped/regtested on x86_64-linux, ok for trunk?
> > > 
> > > Shouldn't digest_init fill in the indexes?  In
> > > process_init_constructor_array I see
> > > 
> > >if (!ce->index)
> > >  ce->index = size_int (i);
> > 
> > Yes, that works too.  Thus:
> > 
> > Bootstrapped/regtested on x86_64-linux, ok for trunk?
> > 
> > -- >8 --
> > Here we crash in the gimplifier because gimplify_init_ctor_eval doesn't
> > expect null indexes for a constructor:
> > 
> >/* ??? Here's to hoping the front end fills in all of the indices,
> >   so we don't have to figure out what's missing ourselves.  */
> >gcc_assert (purpose);
> > 
> > The indexes weren't filled because we never called reshape_init: for
> > a constructor that represents parenthesized initialization of an
> > aggregate we don't allow brace elision or designated initializers.  So
> > call digest_init to fill in the indexes.
> > 
> > Bootstrapped/regtested on x86_64-linux, ok for trunk?
> > 
> > PR c++/94155 - crash in gimplifier with paren init of aggregates.
> > * decl.c (check_initializer): Call digest_init.
> > 
> > * g++.dg/cpp2a/paren-init22.C: New test.
> > ---
> >   gcc/cp/decl.c |  5 +
> >   gcc/testsuite/g++.dg/cpp2a/paren-init22.C | 15 +++
> >   2 files changed, 20 insertions(+)
> >   create mode 100644 gcc/testsuite/g++.dg/cpp2a/paren-init22.C
> > 
> > diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
> > index 69a238997b4..63e7bda09f5 100644
> > --- a/gcc/cp/decl.c
> > +++ b/gcc/cp/decl.c
> > @@ -6754,6 +6754,11 @@ check_initializer (tree decl, tree init, int flags, 
> > vec **cleanups)
> >   init = build_constructor_from_list (init_list_type_node, init);
> >   CONSTRUCTOR_IS_DIRECT_INIT (init) = true;
> >   CONSTRUCTOR_IS_PAREN_INIT (init) = true;
> > + /* The gimplifier expects that the front end fills in all of the
> > +indices.  Normally, reshape_init_array fills these in, but we
> > +don't call reshape_init because that does nothing when it gets
> > +CONSTRUCTOR_IS_PAREN_INIT.  */
> > + init = digest_init (type, init, tf_warning_or_error);
> 
> But why weren't we already calling digest_init in store_init_value?  Was the
> CONSTRUCTOR making it all the way to gimplification still having
> init_list_type_node?

It's because we set LOOKUP_ALREADY_DIGESTED a few lines below:
 6813   /* Don't call digest_init; it's unnecessary and will 
complain
 6814  about aggregate initialization of non-aggregate classes. 
 */
 6815   flags |= LOOKUP_ALREADY_DIGESTED;
and so store_init_value doesn't digest.  Given the comment I'd be nervous about
not setting that flag here.

Marek



Re: libgcc patch committed: Avoid hooks in split-stack code

2020-04-04 Thread Eric Botcazou
> 2020-04-03  Ian Lance Taylor  
> 
> * generic-morestack.c: On GNU/Linux use __mmap/__munmap rather
> than mmap/munmap, to avoid hooks.

This breaks the build of gotools for me with undefined references to __mmap 
and __munmap from libgcc/generic-morestack.c (it is with glibc 2.22).

-- 
Eric Botcazou


Re: ipa: Fix wrong code with failed propagation to builtin_constant_p [PR93940]

2020-04-04 Thread Eric Botcazou
> sorry for that. Git is still not my friend. I managed to stash and
> unstash multiple changes and mix them up.

Git was clearly designed *not* to have friends if you ask me, so I cannot 
really blame you here.

> I comitted the following fix.

Thanks!

-- 
Eric Botcazou


Re: [PATCH] c++: Refrain from using replace_placeholders in constexpr evaluation [PR94205]

2020-04-04 Thread Patrick Palka via Gcc-patches
On Sat, 4 Apr 2020, Jason Merrill wrote:

> On 4/3/20 4:07 PM, Patrick Palka wrote:
> > On Fri, 3 Apr 2020, Jason Merrill wrote:
> > 
> > > On 4/2/20 7:40 PM, Patrick Palka wrote:
> > > > +  /* Prefer the outermost matching object, but don't cross
> > > > + CONSTRUCTOR_PLACEHOLDER_BOUNDARY constructors.  */
> > > > +  if (ctx->ctor && !CONSTRUCTOR_PLACEHOLDER_BOUNDARY (ctx->ctor))
> > > > +if (tree parent_ob = lookup_placeholder (ctx->parent, lval, type))
> > > > +  return parent_ob;
> > > 
> > > Instead of recursing here, would it work to replace the loop at the end
> > > with
> > > tail recursion?
> > 
> > Do you mean something like the following?
> > 
> >static tree
> >lookup_placeholder (const constexpr_ctx *ctx, bool lval, tree type)
> >{
> >  if (!ctx)
> >return NULL_TREE;
> > 
> >  tree ob = ctx->object;
> >  if (ob && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (ob),
> > type))
> >return obj;
> >  else if (ctx->ctor && !CONSTRUCTOR_PLACEHOLDER_BOUNDARY (ctx->ctor))
> >return lookup_placeholder (ctx->parent, lval, type);
> >  else
> >return NULL_TREE;
> >}
> > 
> > I think we would need to set ctx->parent in more places in order for this to
> > work, so that each node in the path to the innermost suboject is represented
> > by
> > a constexpr_ctx.
> 
> Hmm, true.  But given how it's currently set, the comment
> 
> > +  /* The constexpr expansion context inside which this one is nested.
> 
> seems overly general; perhaps "the aggregate initialization context..."?

Oops, fixed.  A preliminary version of the patch set new_ctx->parent to
point to the old constexpr_ctx whenever we would create a
sub-constexpr_ctx, consistent with the comment, but later I ended up
just setting it in that one place since it was sufficient and seemed
easier to reason about.

> 
> OK with that change.

Thanks, patch committed just now with the comment adjusted.

> 
> > Besides that, using tail recursion would, IIUC, mean that we would return
> > the
> > innermost matching object, but I think we want to return the outermost
> > matching
> > object (without crossing CONSTRUCTOR_PLACEHOLDER_BOUNDARY constructors) when
> > there might be more than one matching object.  For if a PLACEHOLDER_EXPR
> > really
> > was meant to refer to an object other than this outermost object, then
> > presumably the CONSTRUCTOR_PLACEHOLDER_BOUNDARY flag would have already been
> > set on some suboject constructor and so we wouldn't have recursed to
> > this outermost object in the first place, if I'm understanding the flag
> > correctly.
> 
> Good point.
> 
> Jason
> 
> 



Re: [PATCH v2] debug: Improve debug info of c++14 deduced return type [PR94459]

2020-04-04 Thread Jason Merrill via Gcc-patches

On 4/4/20 3:54 AM, Jakub Jelinek wrote:

On Sat, Apr 04, 2020 at 12:08:38AM -0400, Jason Merrill wrote:

http://eel.is/c++draft/dcl.spec.auto#3 says it has to appear as a
decl-specifier.

http://eel.is/c++draft/temp.deduct.type#8 lists the forms where a template
argument can be deduced.

Looks like you are missing arrays, pointers to members, and function return
types.


I have added that to dwarf2out.c but have a hard time figuring out how to
write the array case (added just the pointer, pointer-to-member (both data
and function) and pointer to function cases to the testcase so far).
Tried
   auto ( ())[2] { return w; }
but that is rejected with:
pr94459.C:40:10: error: ‘m22’ declared as array of ‘auto’
40 |   auto ( ())[2] { return w; }
   |  ^~~


Hmm, that is in fact prohibited by http://eel.is/c++draft/dcl.array#4

"U is called the array element type; this type shall not be a 
placeholder type"


That restriction seems misplaced, but clearly interferes with testing 
that pattern.  Let's keep the handling in dwarf2out, though.  The patch 
is OK as is.



2020-04-04  Hannes Domani  
Jakub Jelinek  

PR debug/94459
* dwarf2out.c (gen_subprogram_die): Look through references, pointers,
arrays, pointer-to-members, function types and qualifiers when
checking if in-class DIE had an 'auto' or 'decltype(auto)' return type
to emit type again on definition.

* g++.dg/debug/pr94459.C: New test.

--- gcc/dwarf2out.c.jj  2020-04-04 00:35:03.450199722 +0200
+++ gcc/dwarf2out.c 2020-04-04 09:45:27.821396824 +0200
@@ -22905,11 +22905,22 @@ gen_subprogram_die (tree decl, dw_die_re
  != (unsigned) s.column))
add_AT_unsigned (subr_die, DW_AT_decl_column, s.column);
  
-	  /* If the prototype had an 'auto' or 'decltype(auto)' return type,

-emit the real type on the definition die.  */
+ /* If the prototype had an 'auto' or 'decltype(auto)' in
+the return type, emit the real type on the definition die.  */
  if (is_cxx () && debug_info_level > DINFO_LEVEL_TERSE)
{
  dw_die_ref die = get_AT_ref (old_die, DW_AT_type);
+ while (die
+&& (die->die_tag == DW_TAG_reference_type
+|| die->die_tag == DW_TAG_rvalue_reference_type
+|| die->die_tag == DW_TAG_pointer_type
+|| die->die_tag == DW_TAG_const_type
+|| die->die_tag == DW_TAG_volatile_type
+|| die->die_tag == DW_TAG_restrict_type
+|| die->die_tag == DW_TAG_array_type
+|| die->die_tag == DW_TAG_ptr_to_member_type
+|| die->die_tag == DW_TAG_subroutine_type))
+   die = get_AT_ref (die, DW_AT_type);
  if (die == auto_die || die == decltype_auto_die)
add_type_attribute (subr_die, TREE_TYPE (TREE_TYPE (decl)),
TYPE_UNQUALIFIED, false, context_die);
--- gcc/testsuite/g++.dg/debug/pr94459.C.jj 2020-04-04 09:24:19.655238506 
+0200
+++ gcc/testsuite/g++.dg/debug/pr94459.C2020-04-04 09:44:07.572588212 
+0200
@@ -0,0 +1,63 @@
+// PR debug/94459
+// { dg-do compile { target c++14 } }
+// { dg-options "-g -dA" }
+
+auto
+baz ()
+{
+  return 0L;
+}
+
+template 
+struct S
+{
+  T v;
+  T w[2];
+  S () : v (0), w { 0, 0 } {}
+  auto m1 () { return v; }
+  auto  () { return v; }
+  auto & () { return (T&&)v; }
+  const auto m4 () { return v; }
+  const auto  () { return v; }
+  const auto & () { return (T&&)v; }
+  volatile auto m7 () { return v; }
+  volatile auto  () { return v; }
+  volatile auto & () { return (T&&)v; }
+  volatile const auto m10 () { return v; }
+  volatile const auto  () { return v; }
+  volatile const auto & () { return (T&&)v; }
+  const volatile auto m13 () { return v; }
+  const volatile auto  () { return v; }
+  const volatile auto & () { return (T&&)v; }
+#ifndef __STRICT_ANSI__
+  __restrict const volatile auto & () { return (T&&)v; }
+  const __restrict auto  () { return v; }
+#endif
+  auto *m18 () { return  }
+  auto (S::* (m19 ())) () { return ::m1; }
+  auto (S::* (m20 ())) { return ::v; }
+  auto (*m21 ()) () { return baz; }
+};
+
+S s, u, v;
+
+long
+foo ()
+{
+  auto x = s.m19 ();
+  auto y = s.m20 ();
+  auto z = s.m21 ();
+  return s.m1 () + s.m2 () + s.m3 () + s.m4 () + s.m5 ()
++ s.m6 () + s.m7 () + s.m8 () + s.m9 () + s.m10 ()
++ s.m11 () + s.m12 () + s.m13 () + s.m14 () + s.m15 ()
+#ifndef __STRICT_ANSI__
++ u.m16 () + v.m17 ()
+#endif
++ *s.m18 () + (s.*x) () + s.*y + z ();
+}
+
+int
+main ()
+{
+  return foo ();
+}

Jakub





[pushed] c++: Fix invalid pointer-to-member in requires [PR67825]

2020-04-04 Thread Jason Merrill via Gcc-patches
A recent change to cmcstl2 led to two tests failing due to this bug: our
valid expression checking in the context of a requires-expression wasn't
catching that an expression of member function type can only appear as the
function operand of a call expression.  Fixed by using convert_to_void to do
the same checking as a discarded-value expression.

This patch also fixes 67825, which already had a testcase, but the testcase
was testing for the wrong behavior.

Tested x86_64-pc-linux-gnu, applying to trunk.

gcc/cp/ChangeLog
2020-04-04  Jason Merrill  

PR c++/67825
* constraint.cc (tsubst_valid_expression_requirement): Call
convert_to_void.
---
 gcc/cp/constraint.cc  |  5 -
 gcc/testsuite/g++.dg/cpp2a/concepts-pmf1.C| 22 +++
 gcc/testsuite/g++.dg/cpp2a/concepts-pr67825.C |  2 +-
 3 files changed, 27 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-pmf1.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 9c21ce80256..e5308414879 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -1864,7 +1864,10 @@ hash_placeholder_constraint (tree c)
 static tree
 tsubst_valid_expression_requirement (tree t, tree args, subst_info info)
 {
-  return tsubst_expr (t, args, info.complain, info.in_decl, false);
+  tree r = tsubst_expr (t, args, info.complain, info.in_decl, false);
+  if (convert_to_void (r, ICV_STATEMENT, info.complain) == error_mark_node)
+return error_mark_node;
+  return r;
 }
 
 
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pmf1.C 
b/gcc/testsuite/g++.dg/cpp2a/concepts-pmf1.C
new file mode 100644
index 000..30d2b2d4a48
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pmf1.C
@@ -0,0 +1,22 @@
+// Make sure that the requirement fails because a .* expression of function
+// type can only be used in a call.
+
+// { dg-do compile { target concepts } }
+
+template
+constexpr decltype(auto) invoke(D (T::*pmd), T&& t)
+  noexcept(noexcept(t.*pmd))
+  requires requires { t.*pmd; }
+ { return t.*pmd; }
+
+char invoke(...);
+
+struct A
+{
+  int f();
+};
+
+int main()
+{
+  static_assert(sizeof(invoke (::f, A())) == 1);
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67825.C 
b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67825.C
index 95698e99978..fff414b8eb2 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67825.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67825.C
@@ -15,6 +15,6 @@ template  concept bool C() {
 }
 
 int main() {
-  static_assert(C());
+  static_assert(!C());
   return 0;
 }

base-commit: bab8d9625f4cdeaf9bb45e28ab62abe47c3827f9
-- 
2.18.1



[pushed] c++: Fix reuse of class constants [PR94453]

2020-04-04 Thread Jason Merrill via Gcc-patches
The testcase hit an ICE trying to expand a TARGET_EXPR temporary cached from
the other lambda-expression.  This patch fixes this in two ways:

1) Avoid reusing a TARGET_EXPR from another function.
2) Avoid ending up with a TARGET_EXPR at all; the use of 'p' had become
 >>, which doesn't make any
sense.

Tested x86_64-pc-linux-gnu, applying to trunk.

gcc/cp/ChangeLog
2020-04-04  Jason Merrill  

PR c++/94453
* constexpr.c (maybe_constant_value): Use break_out_target_exprs.
* expr.c (mark_use) [VIEW_CONVERT_EXPR]: Don't wrap a TARGET_EXPR in
NON_LVALUE_EXPR.
---
 gcc/cp/constexpr.c|  2 +-
 gcc/cp/expr.c | 22 +++
 .../g++.dg/cpp0x/lambda/lambda-constexpr1.C   | 28 +++
 3 files changed, 46 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-constexpr1.C

diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 91f0c3ba269..8c693ea89ef 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -6793,7 +6793,7 @@ maybe_constant_value (tree t, tree decl, bool 
manifestly_const_eval,
   r = *cached;
   if (r != t)
{
- r = unshare_expr_without_location (r);
+ r = break_out_target_exprs (r, /*clear_loc*/true);
  protected_set_expr_location (r, EXPR_LOCATION (t));
}
   return r;
diff --git a/gcc/cp/expr.c b/gcc/cp/expr.c
index 04e4418c671..9b535708c57 100644
--- a/gcc/cp/expr.c
+++ b/gcc/cp/expr.c
@@ -195,11 +195,23 @@ mark_use (tree expr, bool rvalue_p, bool read_p,
  tree nop = RECUR (op);
  if (nop == error_mark_node)
return error_mark_node;
- TREE_OPERAND (expr, 0) = nop;
- /* If we're replacing a DECL with a constant, we also need to change
-the TREE_CODE of the location wrapper.  */
- if (op != nop && rvalue_p)
-   TREE_SET_CODE (expr, NON_LVALUE_EXPR);
+ else if (op == nop)
+   /* No change.  */;
+ else if (DECL_P (nop) || CONSTANT_CLASS_P (nop))
+   {
+ /* Reuse the location wrapper.  */
+ TREE_OPERAND (expr, 0) = nop;
+ /* If we're replacing a DECL with a constant, we also need to
+change the TREE_CODE of the location wrapper.  */
+ if (rvalue_p)
+   TREE_SET_CODE (expr, NON_LVALUE_EXPR);
+   }
+ else
+   {
+ /* Drop the location wrapper.  */
+ expr = nop;
+ protected_set_expr_location (expr, loc);
+   }
  return expr;
}
   gcc_fallthrough();
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-constexpr1.C 
b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-constexpr1.C
new file mode 100644
index 000..7cb1e239ebb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-constexpr1.C
@@ -0,0 +1,28 @@
+// PR c++/94453
+// { dg-do compile { target c++11 } }
+
+void *ay();
+template  f ay() { return *static_cast(ay()); }
+template 
+void bf() {
+  ay()();
+}
+struct az {
+  template 
+  az(h);
+  using bk = void (*)();
+  bk bl;
+};
+template 
+az::az(h) { bl = bf; }
+struct A {};
+void da(az);
+void di(A, int);
+void dk(A, az, az);
+void b() {
+  int data = 0;
+  auto n = [] {};
+  constexpr auto p = A{};
+  auto q = [=] { di(p, data); };
+  da([=] { dk(p, n, q); });
+}

base-commit: bab8d9625f4cdeaf9bb45e28ab62abe47c3827f9
-- 
2.18.1



Re: ipa: Fix wrong code with failed propagation to builtin_constant_p [PR93940]

2020-04-04 Thread Jan Hubicka
> 
> The change 1) breaks bootstrap and 2) fails to update the ChangeLog files.
Hi,
sorry for that. Git is still not my friend. I managed to stash and
unstash multiple changes and mix them up.

I comitted the following fix.

Honza


diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0221945fe6c..75e3a4f3993 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2020-04-04  Jan Hubicka  
+
+   PR ipa/93940
+   * ipa-fnsummary.c (vrp_will_run_p): New function.
+   (fre_will_run_p): New function.
+   (evaluate_properties_for_edge): Use it.
+   * ipa-inline.c (can_inline_edge_by_limits_p): Do not inline
+   !optimize_debug to optimize_debug.
+
 2020-04-04  Jakub Jelinek  
 
PR rtl-optimization/94468
diff --git a/gcc/ipa-fnsummary.c b/gcc/ipa-fnsummary.c
index d96c8e9b03c..045a0ecf766 100644
--- a/gcc/ipa-fnsummary.c
+++ b/gcc/ipa-fnsummary.c
@@ -636,7 +636,7 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool 
inline_p,
  }
 
/* Determine known aggregate values.  */
-   if (vrp_will_run_p (caller))
+   if (fre_will_run_p (caller))
  {
ipa_agg_value_set agg
= ipa_agg_value_set_from_jfunc (caller_parms_info,
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 427266a877f..36eb4ba108d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2020-04-04  Jan Hubicka  
+
+   PR ipa/93940
+   * g++.dg/tree-ssa/pr93940.C: New test.
+
 2020-04-04  Jakub Jelinek  
 
PR rtl-optimization/94468


Re: ipa: Fix wrong code with failed propagation to builtin_constant_p [PR93940]

2020-04-04 Thread H.J. Lu via Gcc-patches
On Sat, Apr 4, 2020 at 5:40 AM Eric Botcazou  wrote:
>
> > gcc/ChangeLog:
> >
> > 2020-04-04  Jan Hubicka  
> >
> >   PR ipa/93940
> >   * ipa-fnsummary.c (vrp_will_run_p): New function.
> >   (fre_will_run_p): New function.
> >   (evaluate_properties_for_edge): Use it.
> >   * ipa-inline.c (can_inline_edge_by_limits_p): Do not inline
> >   !optimize_debug to optimize_debug.
>
> The change 1) breaks bootstrap and 2) fails to update the ChangeLog files.
>

Bootstrap failure:

https://gcc.gnu.org/pipermail/gcc-regression/2020-April/072521.html

-- 
H.J.


Contents of PO file 'cpplib-10.1-b20200209.eo.po'

2020-04-04 Thread Translation Project Robot


cpplib-10.1-b20200209.eo.po.gz
Description: Binary data
The Translation Project robot, in the
name of your translation coordinator.



New Esperanto PO file for 'cpplib' (version 10.1-b20200209)

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

This is a message from the Translation Project robot.

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

https://translationproject.org/latest/cpplib/eo.po

(This file, 'cpplib-10.1-b20200209.eo.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/cpplib/

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/cpplib.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.




Re: ipa: Fix wrong code with failed propagation to builtin_constant_p [PR93940]

2020-04-04 Thread Eric Botcazou
> gcc/ChangeLog:
> 
> 2020-04-04  Jan Hubicka  
> 
>   PR ipa/93940
>   * ipa-fnsummary.c (vrp_will_run_p): New function.
>   (fre_will_run_p): New function.
>   (evaluate_properties_for_edge): Use it.
>   * ipa-inline.c (can_inline_edge_by_limits_p): Do not inline
>   !optimize_debug to optimize_debug.

The change 1) breaks bootstrap and 2) fails to update the ChangeLog files.

-- 
Eric Botcazou


Re: [PATCH] Check DECL_CONTEXT of new/delete operators.

2020-04-04 Thread Jan Hubicka
Hi,
thinking a bit of the problem, I guess we could match in addition to
DECL_CONTEXT the whole inline stack of both statements and see if there
are inlined new/delete operators and if so if they are always in
matching pairs.

The inline stack is available as
for (tree block = gimple_block (call); block && TREE_CODE (block) == BLOCK; 
block = BLOCK_SUPERCONTEXT (block))
  {
tree fn = block_ultimate_origin (block);
if (fn != NULL && TREE_CODE (fn) == FUNCTION_DECL)
  do the checking htere.
  }

But I do not understand what C++ promises here and in what conditions
the new/delete pair can be removed.
Honza


[PATCH] libiberty: Update D symbol demangling for latest ABI spec.

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

Some small improvements and clarifications have been done in the D ABI
specification to remove all ambiguities found in the current grammar,
this implementation now more closely resembles the spec, whilst
maintaining compatibility with the old ABI.

Three new rules have been added to the ABI.

1. Back references using 'Q', analogous to C++ substitutions, compresses
   repeated identifiers, types, and template symbol and value parameters.

2. Template aliases to externally mangled symbols are prefixed with 'X'.
   This includes any symbol that isn't extern(D), or has its name
   overriden with pragma(mangle).  This fixes an ambiguity where it was
   not clear whether 'V' was an encoded calling convention, or the next
   template value parameter.

3. Alias parameters, templates, and tuple symbols no longer encode the
   symbol length of its subpart.  Tuples are now terminated with 'Z'.
   This fixes another ambiguity where the first character of the mangled
   name can be a digit as well, so the demangler had to figure out where
   to split the two adjacent numbers by trying out each combination.

This patch was originally written by Rainer Schuetze, with clean-ups and
backwards compatibility added by myself.

Bootstrapped and regression tested on x86_linux-gnu, OK for mainline?

Regards
Iain.

---

libiberty/ChangeLog:

2019-04-04  Rainer Schuetze  
Iain Buclaw  

* d-demangle.c (enum dlang_symbol_kinds): Remove enum.
(struct dlang_info): New struct
(dlang_decode_backref): New function.
(dlang_backref): New function.
(dlang_symbol_backref): New function.
(dlang_type_backref): New function.
(dlang_symbol_name_p): New function.
(dlang_function_type_noreturn): New function.
(dlang_function_type): Add 'info' parameter.  Decode function type
with dlang_function_type_noreturn.
(dlang_function_args): Add 'info' parameter.
(dlang_type): Add 'info' parameter.  Handle back referenced types.
(dlang_identifier): Replace 'kind' parameter with 'info'.  Handle back
referenced symbols.  Split off decoding of plain identifiers to...
(dlang_lname): ...here.
(dlang_parse_mangle): Replace 'kind' parameter with 'info'.  Decode
function type and return with dlang_type.
(dlang_parse_qualified): Replace 'kind' parameter with 'info', add
'suffix_modifier' parameter.  Decode function type with
dlang_function_type_noreturn.
(dlang_parse_tuple): Add 'info' parameter.
(dlang_template_symbol_param): New function.
(dlang_template_args): Add 'info' parameter.  Decode symbol parameter
with dlang_template_symbol_param.  Handle back referenced values, and
externally mangled parameters.
(dlang_parse_template): Add 'info' parameter.
(dlang_demangle_init_info): New function.
(dlang_demangle): Initialize and pass 'info' parameter.
* testsuite/d-demangle-expected: Add new tests.

---
 libiberty/d-demangle.c  | 769 
 libiberty/testsuite/d-demangle-expected |  72 +++
 2 files changed, 580 insertions(+), 261 deletions(-)

diff --git a/libiberty/d-demangle.c b/libiberty/d-demangle.c
index a9702858a6e..5856bc2930f 100644
--- a/libiberty/d-demangle.c
+++ b/libiberty/d-demangle.c
@@ -160,37 +160,42 @@ string_prepend (string *p, const char *s)
 }
 }
 
-/* What kinds of symbol we could be parsing.  */
-enum dlang_symbol_kinds
+/* Demangle information structure we pass around.  */
+struct dlang_info
 {
-  /* Top-level symbol, needs it's type checked.  */
-  dlang_top_level,
-  /* Function symbol, needs it's type checked.   */
-  dlang_function,
-  /* Strongly typed name, such as for classes, structs and enums.  */
-  dlang_type_name,
-  /* Template identifier.  */
-  dlang_template_ident,
-  /* Template symbol parameter.  */
-  dlang_template_param
+  /* The string we are demangling.  */
+  const char *s;
+  /* The index of the last back reference.  */
+  int last_backref;
 };
 
+/* Pass as the LEN to dlang_parse_template if symbol length is not known.  */
+enum { TEMPLATE_LENGTH_UNKNOWN = -1 };
+
 /* Prototypes for forward referenced functions */
-static const char *dlang_function_args (string *, const char *);
+static const char *dlang_function_type (string *, const char *,
+   struct dlang_info *);
 
-static const char *dlang_type (string *, const char *);
+static const char *dlang_function_args (string *, const char *,
+   struct dlang_info *);
+
+static const char *dlang_type (string *, const char *, struct dlang_info *);
 
 static const char *dlang_value (string *, const char *, const char *, char);
 
 static const char *dlang_parse_qualified (string *, const char *,
- enum dlang_symbol_kinds);
+ struct 

Disable aggregate walking in ipa code for optimize_debug

2020-04-04 Thread Jan Hubicka
Martin,
with optimize_debug or when FRE is disabled propagating aggregates is
useless since we are not going to use them.  I think we should also
avoid working hard on the jump functions.
This patch disables it in ipa_load_from_param_agg, but I am not sure if
there are other ways ipa-prop can do the memory walk?

Bootstrapped/regtested x86_64. Makes sense?

Honza

* ipa-fnsummary.c (vrp_will_run_p): Export.
* ipa-fnsummary.h (vrp_will_run_p): Declare.
* ipa-prop.c (ipa_load_from_parm_agg): Use it.
diff --git a/gcc/ipa-fnsummary.c b/gcc/ipa-fnsummary.c
index d96c8e9b03c..e5f43078c27 100644
--- a/gcc/ipa-fnsummary.c
+++ b/gcc/ipa-fnsummary.c
@@ -522,7 +522,7 @@ vrp_will_run_p (struct cgraph_node *node)
 
 /* Similarly about FRE.  */
 
-static bool
+bool
 fre_will_run_p (struct cgraph_node *node)
 {
   return (opt_for_fn (node->decl, optimize)
diff --git a/gcc/ipa-fnsummary.h b/gcc/ipa-fnsummary.h
index c6ddc9f3199..f4e1fd0cc86 100644
--- a/gcc/ipa-fnsummary.h
+++ b/gcc/ipa-fnsummary.h
@@ -371,6 +371,7 @@ void evaluate_properties_for_edge (struct cgraph_edge *e,
 void ipa_fnsummary_c_finalize (void);
 HOST_WIDE_INT ipa_get_stack_frame_offset (struct cgraph_node *node);
 void ipa_remove_from_growth_caches (struct cgraph_edge *edge);
+bool fre_will_run_p (struct cgraph_node *);
 
 /* Return true if EDGE is a cross module call.  */
 
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index 71ac0e104d2..7f654f3aea3 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -1091,6 +1091,12 @@ ipa_load_from_parm_agg (struct ipa_func_body_info *fbi,
   int index;
   HOST_WIDE_INT size;
   bool reverse;
+
+  /* Do not bother to do analysis when we are not doing propagation of
+ aggregates anyway.  */
+  if (!fre_will_run_p (cgraph_node::get (current_function_decl)))
+return false;
+
   tree base = get_ref_base_and_extent_hwi (op, offset_p, , );
 
   if (!base)


ipa: Fix wrong code with failed propagation to builtin_constant_p [PR93940]

2020-04-04 Thread Jan Hubicka
Hi,
this patch fixes wrong code on a testcase where inline predicts
builtin_constant_p to be true but we fail to optimize its parameter to constant
becuase FRE is not run and the value is passed by an aggregate.

This patch makes the inline predicates to disable aggregate tracking
when FRE is not going to be run and similarly value range when VRP is not
going to be run.

This is just partial fix.  Even with it we can arrange FRE/VRP to fail and
produce wrong code, unforutnately.

I think for GCC11 I will need to implement transformation in ipa-inline
but this is bit hard to do: predicates only tracks that value will be constant
and do not track what constant to be.

Optimizing builtin_constant_p in a conditional is not going to do good job
when the value is used later in a place that expects it to be constant.
This is pre-existing problem that is not limited to inline tracking. For 
example,
FRE may do the transofrm at one place but not in another due to alias oracle
walking limits.

So I am not sure what full fix would be :(

gcc/ChangeLog:

2020-04-04  Jan Hubicka  

PR ipa/93940
* ipa-fnsummary.c (vrp_will_run_p): New function.
(fre_will_run_p): New function.
(evaluate_properties_for_edge): Use it.
* ipa-inline.c (can_inline_edge_by_limits_p): Do not inline
!optimize_debug to optimize_debug.

gcc/testsuite/ChangeLog:

2020-04-04  Jan Hubicka  

* g++.dg/tree-ssa/pr93940.C: New test.

diff --git a/gcc/ipa-fnsummary.c b/gcc/ipa-fnsummary.c
index b411bc4d660..279ac8f7cc9 100644
--- a/gcc/ipa-fnsummary.c
+++ b/gcc/ipa-fnsummary.c
@@ -503,6 +503,32 @@ evaluate_conditions_for_known_args (struct cgraph_node 
*node,
 *ret_nonspec_clause = nonspec_clause;
 }
 
+/* Return true if VRP will be exectued on the function.
+   We do not want to anticipate optimizations that will not happen.
+
+   FIXME: This can be confused with -fdisable and debug counters and thus
+   it should not be used for correctness (only to make heuristics work).
+   This means that inliner should do its own optimizations of expressions
+   that it predicts to be constant so wrong code can not be triggered by
+   builtin_constant_p.  */
+
+static bool
+vrp_will_run_p (struct cgraph_node *node)
+{
+  return (opt_for_fn (node->decl, optimize)
+ && !opt_for_fn (node->decl, optimize_debug)
+ && opt_for_fn (node->decl, flag_tree_vrp));
+}
+
+/* Similarly about FRE.  */
+
+static bool
+fre_will_run_p (struct cgraph_node *node)
+{
+  return (opt_for_fn (node->decl, optimize)
+ && !opt_for_fn (node->decl, optimize_debug)
+ && opt_for_fn (node->decl, flag_tree_fre));
+}
 
 /* Work out what conditions might be true at invocation of E.
Compute costs for inlined edge if INLINE_P is true.
@@ -594,6 +620,7 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool 
inline_p,
 
/* If we failed to get simple constant, try value range.  */
if ((!cst || TREE_CODE (cst) != INTEGER_CST)
+   && vrp_will_run_p (caller)
&& ipa_is_param_used_by_ipa_predicates (callee_pi, i))
  {
value_range vr 
@@ -609,14 +636,17 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool 
inline_p,
  }
 
/* Determine known aggregate values.  */
-   ipa_agg_value_set agg
-   = ipa_agg_value_set_from_jfunc (caller_parms_info,
-   caller, >agg);
-   if (agg.items.length ())
+   if (vrp_will_run_p (caller))
  {
-   if (!known_aggs_ptr->length ())
- vec_safe_grow_cleared (known_aggs_ptr, count);
-   (*known_aggs_ptr)[i] = agg;
+   ipa_agg_value_set agg
+   = ipa_agg_value_set_from_jfunc (caller_parms_info,
+   caller, >agg);
+   if (agg.items.length ())
+ {
+   if (!known_aggs_ptr->length ())
+ vec_safe_grow_cleared (known_aggs_ptr, count);
+   (*known_aggs_ptr)[i] = agg;
+ }
  }
  }
 
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index 302ce16a646..f71443feff7 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -485,6 +485,7 @@ can_inline_edge_by_limits_p (struct cgraph_edge *e, bool 
report,
  else if (check_match (flag_wrapv)
  || check_match (flag_trapv)
  || check_match (flag_pcc_struct_return)
+ || check_maybe_down (optimize_debug)
  /* When caller or callee does FP math, be sure FP codegen flags
 compatible.  */
  || ((caller_info->fp_expressions && callee_info->fp_expressions)
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr93940.C 

[PATCH]Microblaze: Fixed missing save of r18 in fast_interrupt.

2020-04-04 Thread Nagaraju Mekala
Hello All,

Fixed missing save of r18 in fast_interrupt.
Register 18 is used as a clobber register, and must be stored when entering a 
fast_interrupt. Before this fix, register 18 was only saved if it was used 
directly in the interrupt function.

However, if the fast_interrupt function called a function that used r18, the 
register would not be saved, and thus be mangled upon returning from the 
interrupt.

Changelog
2020-04-04  Klaus Petersen 
 * gcc/config/microblaze/microblaze.c: Check for fast_interrupt in
microblaze_must_save_register.

Signed-off-by: Klaus Petersen 
Signed-off-by :Nagaraju Mekala 

diff --git a/gcc/config/microblaze/microblaze.c 
b/gcc/config/microblaze/microblaze.c
index b4754b1..67e393d 100644
--- a/gcc/config/microblaze/microblaze.c
+++ b/gcc/config/microblaze/microblaze.c
@@ -2035,7 +2035,7 @@ microblaze_must_save_register (int regno)
 {
   if (df_regs_ever_live_p (regno) 
  || regno == MB_ABI_MSR_SAVE_REG
- || (interrupt_handler
+ || ((interrupt_handler || fast_interrupt)   
   && (regno == MB_ABI_ASM_TEMP_REGNUM
  || regno == MB_ABI_EXCEPTION_RETURN_ADDR_REGNUM)))
return 1;

Attached is the patch.

Thanks
Nagaraju


0001-Patch-microblaze-Fixed-missing-save-of-r18-in-fast_i.patch
Description: 0001-Patch-microblaze-Fixed-missing-save-of-r18-in-fast_i.patch


[PATCH]Microblaze: Modified trap instruction

2020-04-04 Thread Nagaraju Mekala
Hello All,

There is a bug in trap instruction generation.
Instead of "bri 0" instruction "brki r0, -1" was used, corrected it now.

ChangeLog:
2020-04-04 Nagaraju Mekala 

* gcc/config/microblaze/microblaze.md
(trap): update in the pattern
* gcc/testsuite/gcc.target/microblaze/others/builtin-trap.c
(dg-final): update in the scan-assembler instruction

Signed-off-by :Nagaraju Mekala 

diff --git a/gcc/config/microblaze/microblaze.md 
b/gcc/config/microblaze/microblaze.md
index 1970cc6..7049acd 100644
--- a/gcc/config/microblaze/microblaze.md
+++ b/gcc/config/microblaze/microblaze.md
@@ -2303,7 +2303,7 @@
 (define_insn "trap"
   [(trap_if (const_int 1) (const_int 0))]
   ""
-  "brki\tr0,-1"
+  "bri\t0"
  [(set_attr "type" "trap")]
 )
 
diff --git a/gcc/testsuite/gcc.target/microblaze/others/builtin-trap.c 
b/gcc/testsuite/gcc.target/microblaze/others/builtin-trap.c
index fdcde1f..580b4db 100644
--- a/gcc/testsuite/gcc.target/microblaze/others/builtin-trap.c
+++ b/gcc/testsuite/gcc.target/microblaze/others/builtin-trap.c
@@ -5,4 +5,4 @@ void trap ()
   __builtin_trap ();
 }
 
-/* { dg-final { scan-assembler "brki\tr0,-1" } } */
\ No newline at end of file
+/* { dg-final { scan-assembler "bri\t0" } } */

Attached is the patch.

Thanks
Nagaraju


0001-Patch-Microblaze-Modified-trap-instruction.patch
Description: 0001-Patch-Microblaze-Modified-trap-instruction.patch


Re: [PATCH] cselib: Don't consider SP_DERIVED_VALUE_P values as useless [PR94468]

2020-04-04 Thread Richard Biener
On April 4, 2020 12:42:33 AM GMT+02:00, Jakub Jelinek  wrote:
>On Fri, Apr 03, 2020 at 07:42:10PM +0200, Jakub Jelinek via Gcc-patches
>wrote:
>> Or, to avoid the repetitive code, should I introduce
>> static bool
>> cselib_useless_value_p (cselib_val *v)
>> {
>>   return (v->locs == 0
>>&& !PRESERVED_VALUE_P (v->val_rtx)
>>&& !SP_DERIVED_VALUE_P (v->val_rtx)));
>> }
>> predicate and use it in those 6 spots?
>
>Here is the patch variant with the above helper.
>Also bootstrapped/regtested on x86_64-linux and i686-linux.

OK. 

Richard. 

>2020-04-04  Jakub Jelinek  
>
>   PR rtl-optimization/94468
>   * cselib.c (references_value_p): Formatting fix.
>   (cselib_useless_value_p): New function.
>   (discard_useless_locs, discard_useless_values,
>   cselib_invalidate_regno_val, cselib_invalidate_mem,
>   cselib_record_set): Use it instead of
>   v->locs == 0 && !PRESERVED_VALUE_P (v->val_rtx).
>
>   * g++.dg/opt/pr94468.C: New test.
>
>--- gcc/cselib.c.jj2020-04-02 14:28:02.620577679 +0200
>+++ gcc/cselib.c   2020-04-03 17:08:54.295282018 +0200
>@@ -629,8 +629,8 @@ references_value_p (const_rtx x, int onl
>   int i, j;
> 
>   if (GET_CODE (x) == VALUE
>-  && (! only_useless ||
>-(CSELIB_VAL_PTR (x)->locs == 0 && !PRESERVED_VALUE_P (x
>+  && (! only_useless
>+|| (CSELIB_VAL_PTR (x)->locs == 0 && !PRESERVED_VALUE_P (x
> return 1;
> 
>   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
>@@ -646,6 +646,16 @@ references_value_p (const_rtx x, int onl
>   return 0;
> }
> 
>+/* Return true if V is a useless VALUE and can be discarded as such. 
>*/
>+
>+static bool
>+cselib_useless_value_p (cselib_val *v)
>+{
>+  return (v->locs == 0
>+&& !PRESERVED_VALUE_P (v->val_rtx)
>+&& !SP_DERIVED_VALUE_P (v->val_rtx));
>+}
>+
>/* For all locations found in X, delete locations that reference
>useless
>values (i.e. values without any location).  Called through
>htab_traverse.  */
>@@ -666,7 +676,7 @@ discard_useless_locs (cselib_val **x, vo
>   p = &(*p)->next;
> }
> 
>-  if (had_locs && v->locs == 0 && !PRESERVED_VALUE_P (v->val_rtx))
>+  if (had_locs && cselib_useless_value_p (v))
> {
>   if (setting_insn && DEBUG_INSN_P (setting_insn))
>   n_useless_debug_values++;
>@@ -684,7 +694,7 @@ discard_useless_values (cselib_val **x,
> {
>   cselib_val *v = *x;
> 
>-  if (v->locs == 0 && !PRESERVED_VALUE_P (v->val_rtx))
>+  if (v->locs == 0 && cselib_useless_value_p (v))
> {
>   if (cselib_discard_hook)
>   cselib_discard_hook (v);
>@@ -2370,7 +2380,7 @@ cselib_invalidate_regno_val (unsigned in
>   }
> }
> 
>-  if (had_locs && v->locs == 0 && !PRESERVED_VALUE_P (v->val_rtx))
>+  if (had_locs && cselib_useless_value_p (v))
> {
>   if (setting_insn && DEBUG_INSN_P (setting_insn))
>   n_useless_debug_values++;
>@@ -2515,7 +2525,7 @@ cselib_invalidate_mem (rtx mem_rtx)
> unchain_one_elt_loc_list (p);
>   }
> 
>-  if (had_locs && v->locs == 0 && !PRESERVED_VALUE_P (v->val_rtx))
>+  if (had_locs && cselib_useless_value_p (v))
>   {
> if (setting_insn && DEBUG_INSN_P (setting_insn))
>   n_useless_debug_values++;
>@@ -2593,14 +2603,14 @@ cselib_record_set (rtx dest, cselib_val
> REG_VALUES (dreg)->elt = src_elt;
>   }
> 
>-  if (src_elt->locs == 0 && !PRESERVED_VALUE_P (src_elt->val_rtx))
>+  if (cselib_useless_value_p (src_elt))
>   n_useless_values--;
>   new_elt_loc_list (src_elt, dest);
> }
>   else if (MEM_P (dest) && dest_addr_elt != 0
>  && cselib_record_memory)
> {
>-  if (src_elt->locs == 0 && !PRESERVED_VALUE_P (src_elt->val_rtx))
>+  if (cselib_useless_value_p (src_elt))
>   n_useless_values--;
>   add_mem_for_addr (dest_addr_elt, src_elt, dest);
> }
>--- gcc/testsuite/g++.dg/opt/pr94468.C.jj  2020-04-03 17:16:38.804457422
>+0200
>+++ gcc/testsuite/g++.dg/opt/pr94468.C 2020-04-03 17:16:18.450756522
>+0200
>@@ -0,0 +1,57 @@
>+// PR rtl-optimization/94468
>+// { dg-do compile { target c++11 } }
>+// { dg-options "-O2" }
>+// { dg-additional-options "-fPIC" { target fpic } }
>+
>+bool a();
>+enum b {};
>+class c;
>+template  struct d;
>+template  struct d
>{
>+  typedef e i;
>+};
>+struct j { j(void(int, j *, c *, void **, bool *)) {} };
>+template  struct m : public j {
>+  l ab;
>+  static void ac(int, j *, c *, void **, bool *);
>+  m(l f) : j(ac), ab(f) {}
>+};
>+b ad;
>+struct c {
>+  template 
>+  void ae(typename d::i *p, n af, typename d::i *ag, o ah) {
>+ai(p, , ag, , new m(ah), ad, ::i::aj);
>+  }
>+  void ai(c *, void *, c *, void *, j *, b, int *);
>+};
>+struct r : public c { static int aj; void t(); };
>+struct al : public c {
>+  static int aj;
>+  void am();
>+  void ao();
>+  void ap();
>+};
>+struct aq { aq(const int &, const int & = int()); };
>+struct ar : public c { ~ar(); };
>+struct as : public ar {
>+  as();
>+  void at();
>+  void au();

[PATCH v2] debug: Improve debug info of c++14 deduced return type [PR94459]

2020-04-04 Thread Jakub Jelinek via Gcc-patches
On Sat, Apr 04, 2020 at 12:08:38AM -0400, Jason Merrill wrote:
> http://eel.is/c++draft/dcl.spec.auto#3 says it has to appear as a
> decl-specifier.
> 
> http://eel.is/c++draft/temp.deduct.type#8 lists the forms where a template
> argument can be deduced.
> 
> Looks like you are missing arrays, pointers to members, and function return
> types.

I have added that to dwarf2out.c but have a hard time figuring out how to
write the array case (added just the pointer, pointer-to-member (both data
and function) and pointer to function cases to the testcase so far).
Tried
  auto ( ())[2] { return w; }
but that is rejected with:
pr94459.C:40:10: error: ‘m22’ declared as array of ‘auto’
   40 |   auto ( ())[2] { return w; }
  |  ^~~

2020-04-04  Hannes Domani  
Jakub Jelinek  

PR debug/94459
* dwarf2out.c (gen_subprogram_die): Look through references, pointers,
arrays, pointer-to-members, function types and qualifiers when
checking if in-class DIE had an 'auto' or 'decltype(auto)' return type
to emit type again on definition.

* g++.dg/debug/pr94459.C: New test.

--- gcc/dwarf2out.c.jj  2020-04-04 00:35:03.450199722 +0200
+++ gcc/dwarf2out.c 2020-04-04 09:45:27.821396824 +0200
@@ -22905,11 +22905,22 @@ gen_subprogram_die (tree decl, dw_die_re
  != (unsigned) s.column))
add_AT_unsigned (subr_die, DW_AT_decl_column, s.column);
 
- /* If the prototype had an 'auto' or 'decltype(auto)' return type,
-emit the real type on the definition die.  */
+ /* If the prototype had an 'auto' or 'decltype(auto)' in
+the return type, emit the real type on the definition die.  */
  if (is_cxx () && debug_info_level > DINFO_LEVEL_TERSE)
{
  dw_die_ref die = get_AT_ref (old_die, DW_AT_type);
+ while (die
+&& (die->die_tag == DW_TAG_reference_type
+|| die->die_tag == DW_TAG_rvalue_reference_type
+|| die->die_tag == DW_TAG_pointer_type
+|| die->die_tag == DW_TAG_const_type
+|| die->die_tag == DW_TAG_volatile_type
+|| die->die_tag == DW_TAG_restrict_type
+|| die->die_tag == DW_TAG_array_type
+|| die->die_tag == DW_TAG_ptr_to_member_type
+|| die->die_tag == DW_TAG_subroutine_type))
+   die = get_AT_ref (die, DW_AT_type);
  if (die == auto_die || die == decltype_auto_die)
add_type_attribute (subr_die, TREE_TYPE (TREE_TYPE (decl)),
TYPE_UNQUALIFIED, false, context_die);
--- gcc/testsuite/g++.dg/debug/pr94459.C.jj 2020-04-04 09:24:19.655238506 
+0200
+++ gcc/testsuite/g++.dg/debug/pr94459.C2020-04-04 09:44:07.572588212 
+0200
@@ -0,0 +1,63 @@
+// PR debug/94459
+// { dg-do compile { target c++14 } }
+// { dg-options "-g -dA" }
+
+auto
+baz ()
+{
+  return 0L;
+}
+
+template 
+struct S
+{
+  T v;
+  T w[2];
+  S () : v (0), w { 0, 0 } {}
+  auto m1 () { return v; }
+  auto  () { return v; }
+  auto & () { return (T&&)v; }
+  const auto m4 () { return v; }
+  const auto  () { return v; }
+  const auto & () { return (T&&)v; }
+  volatile auto m7 () { return v; }
+  volatile auto  () { return v; }
+  volatile auto & () { return (T&&)v; }
+  volatile const auto m10 () { return v; }
+  volatile const auto  () { return v; }
+  volatile const auto & () { return (T&&)v; }
+  const volatile auto m13 () { return v; }
+  const volatile auto  () { return v; }
+  const volatile auto & () { return (T&&)v; }
+#ifndef __STRICT_ANSI__
+  __restrict const volatile auto & () { return (T&&)v; }
+  const __restrict auto  () { return v; }
+#endif
+  auto *m18 () { return  }
+  auto (S::* (m19 ())) () { return ::m1; }
+  auto (S::* (m20 ())) { return ::v; }
+  auto (*m21 ()) () { return baz; }
+};
+
+S s, u, v;
+
+long
+foo ()
+{
+  auto x = s.m19 ();
+  auto y = s.m20 ();
+  auto z = s.m21 ();
+  return s.m1 () + s.m2 () + s.m3 () + s.m4 () + s.m5 ()
++ s.m6 () + s.m7 () + s.m8 () + s.m9 () + s.m10 ()
++ s.m11 () + s.m12 () + s.m13 () + s.m14 () + s.m15 ()
+#ifndef __STRICT_ANSI__
++ u.m16 () + v.m17 ()
+#endif
++ *s.m18 () + (s.*x) () + s.*y + z ();
+}
+
+int
+main ()
+{
+  return foo ();
+}

Jakub