Re: [PATCH] lto-plugin: Add path to libatomic for riscv64

2022-07-05 Thread Richard Biener via Gcc-patches
On Mon, Jul 4, 2022 at 3:09 PM Martin Liška  wrote:
>
> On 7/4/22 14:28, Richard Biener wrote:
> > ... but ... is libatomic properly built for the host?  libgo is a
> > target library.
>
> You're correct.
>
> Well, so the host library should be taken, which works for stage1 lto-plugin:
>
> [  668s] libtool: link: gcc -shared  -fPIC -DPIC  .libs/lto-plugin.o
> -pthread -static-libgcc -Wl,--version-script=../../lto-plugin/lto-plugin.map 
> -static-libstdc++ -static-libgcc ../libiberty/pic/libiberty.a   -pthread 
> -Wl,-soname -Wl,liblto_plugin.so -o .libs/liblto_p
>
> while it fails in stage2:
>
> [ 7129s] libtool: link:  
> /home/abuild/rpmbuild/BUILD/gcc-13.0.0+git194120/obj-riscv64-suse-linux/./prev-gcc/xgcc
>  
> -B/home/abuild/rpmbuild/BUILD/gcc-13.0.0+git194120/obj-riscv64-suse-linux/./prev-gcc/
>  -B/usr/riscv64-suse-linux/bin/ -B/usr/riscv64-suse-linux/bin/ 
> -B/usr/riscv64-suse-linux/lib/ -isystem /usr/riscv64-suse-linux/include 
> -isystem /usr/riscv64-suse-linux/sys-include   -fno-checking -shared  -fPIC 
> -DPIC  .libs/lto-plugin.o-pthread -static-libgcc 
> -Wl,--version-script=../../lto-plugin/lto-plugin.map -static-libstdc++ 
> -static-libgcc ../libiberty/pic/libiberty.a   -pthread -Wl,-soname 
> -Wl,liblto_plugin.so -o .libs/liblto_plugin.so
>
> Where the system compiler takes the library from:
> /usr/lib/gcc/riscv64-linux-gnu/11/libatomic.so
>
> that points to system library location:
> ls -l /usr/lib/gcc/riscv64-linux-gnu/11/libatomic.so
> lrwxrwxrwx 1 root root 41 Mar 24 14:22 
> /usr/lib/gcc/riscv64-linux-gnu/11/libatomic.so -> 
> ../../../riscv64-linux-gnu/libatomic.so.1
>
> So the question is how to fix that?

We'd need to add libatomic as host_module in Makefile.def and also
bootstrap that (since lto-plugin is bootstrapped), plus adding
the required dependency.  At least for the targets that need this.

Or give up and use better means of serialization or use a whitelist
for now (via lto-plugin configury) and leave
all not covered targets not thread-safe (see also the mingw bugreport).

Richard.

>
> Martin
>


Re: [PATCH] tree-sra: Fix union handling in build_reconstructed_reference (PR 105860)

2022-07-05 Thread Richard Biener via Gcc-patches
On Mon, 4 Jul 2022, Martin Jambor wrote:

> Hi,
> 
> On Mon, Jul 04 2022, Richard Biener wrote:
> > On Fri, 1 Jul 2022, Martin Jambor wrote:
> >
> >> Hi,
> >> 
> >> As the testcase in PR 105860 shows, the code that tries to re-use the
> >> handled_component chains in SRA can be horribly confused by unions,
> >> where it thinks it has found a compatible structure under which it can
> >> chain the references, but in fact it found the type it was looking
> >> for elsewhere in a union and generated a write to a completely wrong
> >> part of an aggregate.
> >> 
> >> I don't remember whether the plan was to support unions at all in
> >> build_reconstructed_reference but it can work, to an extent, if we
> >> make sure that we start the search only outside the outermost union,
> >> which is what the patch does (and the extra testcase verifies).
> >> 
> >> Bootstrapped and tested on x86_64-linux.  OK for trunk and then for
> >> release branches?
> >
> > OK, but I'm wondering if the same problem can arise when the
> > handled_component_p includes VIEW_CONVERTs or BIT_FIELD_REFs
> > both of which may pun to a type already seen in a more inner
> > referece.
> 
> SRA already refuses to operate at all on any anything that is accessed
> with a reference where a V_C_E is not the outermost handled_component.
> Outermost V_C_Es are skipped and the pass works with the underlying
> expr.  BIT_FIELD_REFs have to be outermost and they are treated
> similarly.  So that should be safe.

OK.

> > Thus, is the actual problem that build_reconstructed_reference
> > searches for the outermost match of the type rather than the
> > innermost match?  So should it search inner-to-outer instead
> > (or for the last match in the current way of searching?)
> 
> I don't think so.  In the testcase it found a match where there should
> have been none (meaning a crude MEM_REF should be created), any
> certainly correct match must be outside of a union COMPONENT_REF and
> there should never be more than one.

OK, not having looked at the testcase I suspected there would be
two matches.  I couldn't come up with a case where a single union
can confuse things enough ..

The patch is OK.

Richard.

> Thanks,
> 
> Martin
> 
> >
> > Thanks,
> > Richard.
> >
> >> Thanks,
> >> 
> >> Martin
> >> 
> >> 
> >> gcc/ChangeLog:
> >> 
> >> 2022-07-01  Martin Jambor  
> >> 
> >>PR tree-optimization/105860
> >>* tree-sra.cc (build_reconstructed_reference): Start expr
> >>traversal only just below the outermost union.
> >> 
> >> gcc/testsuite/ChangeLog:
> >> 
> >> 2022-07-01  Martin Jambor  
> >> 
> >>PR tree-optimization/105860
> >>* gcc.dg/tree-ssa/alias-access-path-13.c: New test.
> >>* gcc.dg/tree-ssa/pr105860.c: Likewise.
> >> ---
> >>  .../gcc.dg/tree-ssa/alias-access-path-13.c| 31 +
> >>  gcc/testsuite/gcc.dg/tree-ssa/pr105860.c  | 63 +++
> >>  gcc/tree-sra.cc   | 13 +++-
> >>  3 files changed, 106 insertions(+), 1 deletion(-)
> >>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-13.c
> >>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr105860.c
> >> 
> >> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-13.c 
> >> b/gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-13.c
> >> new file mode 100644
> >> index 000..e502a97bc75
> >> --- /dev/null
> >> +++ b/gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-13.c
> >> @@ -0,0 +1,31 @@
> >> +/* { dg-do compile } */
> >> +/* { dg-options "-O2 -fdump-tree-fre1" } */
> >> +
> >> +struct inn
> >> +{
> >> +  int val;
> >> +};
> >> +
> >> +union foo
> >> +{
> >> +  struct inn inn;
> >> +  long int baz;
> >> +} *fooptr;
> >> +
> >> +struct bar
> >> +{
> >> +  union foo foo;
> >> +  int val2;
> >> +} *barptr;
> >> +
> >> +int
> >> +test ()
> >> +{
> >> +  union foo foo;
> >> +  foo.inn.val = 0;
> >> +  barptr->val2 = 123;
> >> +  *fooptr = foo;
> >> +  return barptr->val2;
> >> +}
> >> +
> >> +/* { dg-final { scan-tree-dump-times "return 123" 1 "fre1"} } */
> >> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr105860.c 
> >> b/gcc/testsuite/gcc.dg/tree-ssa/pr105860.c
> >> new file mode 100644
> >> index 000..77bcb4a6739
> >> --- /dev/null
> >> +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr105860.c
> >> @@ -0,0 +1,63 @@
> >> +/* { dg-do run } */
> >> +/* { dg-options "-O1" } */
> >> +
> >> +struct S1  {
> >> +unsigned int _0;
> >> +unsigned int _1;
> >> +} ;
> >> +struct S2  {
> >> +struct S1 _s1;
> >> +unsigned long _x2;
> >> +} ;
> >> +
> >> +struct ufld_type1  {
> >> +unsigned int _u1t;
> >> +struct S2 _s2;
> >> +} ;
> >> +
> >> +struct ufld_type2  {
> >> +unsigned int _u2t;
> >> +struct S1 _s1;
> >> +} ;
> >> +struct parm_type {
> >> +union {
> >> +struct ufld_type1 var_1;
> >> +struct ufld_type2 var_2;
> >> +} U;
> >> +};
> >> +
> >> +struct parm_type  bad_function( struct parm_type arg0 )
> 

Re: [PATCH 1/2]AArch64 Add fallback case using sdot for usdot

2022-07-05 Thread Richard Biener via Gcc-patches
On Tue, Jul 5, 2022 at 8:08 AM Richard Sandiford
 wrote:
>
> Richard Biener  writes:
> > On Wed, Jun 29, 2022 at 4:35 PM Richard Sandiford
> >  wrote:
> >>
> >> Richard Biener  writes:
> >> > On Tue, Jun 28, 2022 at 5:54 PM Tamar Christina 
> >> >  wrote:
> >> >>
> >> >> > -Original Message-
> >> >> > From: Richard Biener 
> >> >> > Sent: Monday, June 27, 2022 7:10 AM
> >> >> > To: Tamar Christina 
> >> >> > Cc: Richard Sandiford ; Richard Earnshaw
> >> >> > ; nd ; gcc-
> >> >> > patc...@gcc.gnu.org; Marcus Shawcroft 
> >> >> > Subject: Re: [PATCH 1/2]AArch64 Add fallback case using sdot for usdot
> >> >> >
> >> >> > On Mon, Jun 27, 2022 at 7:25 AM Tamar Christina via Gcc-patches  >> >> > patc...@gcc.gnu.org> wrote:
> >> >> > >
> >> >> > > > -Original Message-
> >> >> > > > From: Richard Sandiford 
> >> >> > > > Sent: Thursday, June 16, 2022 7:54 PM
> >> >> > > > To: Tamar Christina 
> >> >> > > > Cc: gcc-patches@gcc.gnu.org; nd ; Richard Earnshaw
> >> >> > > > ; Marcus Shawcroft
> >> >> > > > ; Kyrylo Tkachov
> >> >> > 
> >> >> > > > Subject: Re: [PATCH 1/2]AArch64 Add fallback case using sdot for
> >> >> > > > usdot
> >> >> > > >
> >> >> > > > Richard Sandiford via Gcc-patches  
> >> >> > > > writes:
> >> >> > > > > Tamar Christina  writes:
> >> >> > > > >> Hi All,
> >> >> > > > >>
> >> >> > > > >> The usdot operation is common in video encoder and decoders
> >> >> > > > >> including some of the most widely used ones.
> >> >> > > > >>
> >> >> > > > >> This patch adds a +dotprod version of the optab as a fallback 
> >> >> > > > >> for
> >> >> > > > >> when you do have sdot but not usdot available.
> >> >> > > > >>
> >> >> > > > >> The fallback works by adding a bias to the unsigned argument to
> >> >> > > > >> convert it to a signed value and then correcting for the bias 
> >> >> > > > >> later on.
> >> >> > > > >>
> >> >> > > > >> Essentially it relies on (x - 128)y + 128y == xy where x is
> >> >> > > > >> unsigned and y is signed (assuming both are 8-bit values).
> >> >> > > > >> Because the range of a signed byte is only to 127 we split the 
> >> >> > > > >> bias
> >> >> > correction into:
> >> >> > > > >>
> >> >> > > > >>(x - 128)y + 127y + y
> >> >> > > > >
> >> >> > > > > I bet you knew this question was coming, but: this technique 
> >> >> > > > > isn't
> >> >> > > > > target-specific, so wouldn't it be better to handle it in
> >> >> > > > > tree-vect-patterns.cc instead?
> >> >> > >
> >> >> > > Ok, so after many hours of trying I don't know how to make this 
> >> >> > > work.
> >> >> > > DOT_PROD_EXPR is a reduction, but emitting them as additional 
> >> >> > > pattern
> >> >> > > statement doesn't work because they'll be marked as internal_def
> >> >> > > rather than reduction_def.  I tried marking the new vec_stmt_info 
> >> >> > > that
> >> >> > > I create explicitly as reduction_def but this gets overwritten 
> >> >> > > during analysis.
> >> >> > >
> >> >> > > I then looked into getting it as a vectorizable_operation but has 
> >> >> > > this
> >> >> > > obvious problems In that it no longer treats it as a reduction and 
> >> >> > > so tries to
> >> >> > decompose into hi/lo.
> >> >> > >
> >> >> > > I then looked into treating additional patterns from  a reduction as
> >> >> > > reductions themselves but this is obviously wrong as non-reduction
> >> >> > statements also get marked as reductions.
> >> >> > >
> >> >> > > The conclusion is that I don't think the vectorizer allows 
> >> >> > > additional
> >> >> > > reductions to be emitted from patterns.
> >> >> >
> >> >> > Indeed.  DOT_PROD is a weird beast and it doesn't define which lanes 
> >> >> > are
> >> >> > reduced to which so it's only usable when the result is reduced to a 
> >> >> > single
> >> >> > lane.
> >> >> >
> >> >> > An SLP pattern might work if you use reduc-plus for the reduced lanes 
> >> >> > and
> >> >> > keep the multiply separate?
> >> >>
> >> >> Unfortunately I can't seem to get it to handle the reduction in SLP.  
> >> >> It seems to always
> >> >> use the non-SLP aware loop vectorizer here.  The suggested unroll 
> >> >> factor is always 1 and
> >> >> even trying to force it gets it to bail out later, presumable because 
> >> >> it's reducing into a
> >> >> scalar that's used outside the loop?
> >> >
> >> > Yes, it possibly needs 1-lane SLP support.
> >>
> >> As I mentioned to Tamar off-list, I feel like I've been wasting
> >> people's time recently by spewing out ideas that might or might not work
> >> (usually "not work"), so I wanted to get some confidence that the next
> >> suggestion made sense.  In the end I needed most of an implementation
> >> to do that, so it seemed easiest just to finish it off rather than post
> >> it in a half-complete state.  Sorry for the duplication. :-(
> >>
> >> The patch certainly isn't pretty, but I think it's the best we can
> >> do under the current infrastructure, and it should at least make
> >> the costs reasonably accurate.  (Actually, that said, we prob

Re: [x86 PATCH take #2] Doubleword version of and; cmp to not; test optimization.

2022-07-05 Thread Uros Bizjak via Gcc-patches
On Mon, Jul 4, 2022 at 9:11 PM Roger Sayle  wrote:
>
>
> This patch is the latest revision of the patch originally posted at:
> https://gcc.gnu.org/pipermail/gcc-patches/2022-June/596201.html
>
> This patch extends the earlier and;cmp to not;test optimization to also
> perform this transformation for TImode on TARGET_64BIT and DImode on -m32,
> One motivation for this is that it's a step to fixing the current failure
> of gcc.target/i386/pr65105-5.c on -m32.
>
> A more direct benefit for x86_64 is that the following code:
>
> int foo(__int128 x, __int128 y)
> {
>   return (x & y) == y;
> }
>
> improves with -O2 from 15 instructions:
>
> movq%rdi, %r8
> movq%rsi, %rax
> movq%rax, %rdi
> movq%r8, %rsi
> movq%rdx, %r8
> andq%rdx, %rsi
> andq%rcx, %rdi
> movq%rsi, %rax
> movq%rdi, %rdx
> xorq%r8, %rax
> xorq%rcx, %rdx
> orq %rdx, %rax
> sete%al
> movzbl  %al, %eax
> ret
>
> to the slightly better 13 instructions:
>
> movq%rdi, %r8
> movq%rsi, %rax
> movq%r8, %rsi
> movq%rax, %rdi
> notq%rsi
> notq%rdi
> andq%rdx, %rsi
> andq%rcx, %rdi
> movq%rsi, %rax
> orq %rdi, %rax
> sete%al
> movzbl  %al, %eax
> ret
>
> Now that all of the doubleword pieces are already in the tree, this
> patch is now much shorter (an rtx_costs improvement and a single new
> define_insn_and_split), however I couldn't resist including two very
> minor pattern naming tweaks/clean-ups to fix nits.
>
> This revised patch has been tested on x86_64-pc-linux-gnu with
> make bootstrap and make -k check, where on TARGET_64BIT there are
> no new failures, and on --target_board=unix{-m32} with a single new
> failure; the other dg-final in gcc.target/i386/pr65105-5.c now also
> fails (as that code diverges further from the expected vectorized
> output).  This is progress as both FAILs in pr65105-5.c may now be
> fixed by changes localized to the STV pass.  OK for mainline?
>
>
> 2022-07-04  Roger Sayle  
>
> gcc/ChangeLog
> * config/i386/i386.cc (ix86_rtx_costs) : Provide costs
> for double word comparisons and tests (comparisons against zero).
> * config/i386/i386.md (*test_not_doubleword): Split DWI
> and;cmp into andn;cmp $0 as a pre-reload splitter.
> (*andn3_doubleword_bmi): Use  instead of  in name.
> (*3_doubleword): Likewise.
>
> gcc/testsuite/ChangeLog
> * gcc.target/i386/testnot-3.c: New test case.
>


+;; Split and;cmp (as optimized by combine) into andn;cmp $0
+(define_insn_and_split "*test_not_doubleword"
+  [(set (reg:CCZ FLAGS_REG)
+ (compare:CCZ
+  (and:DWI
+(not:DWI (match_operand:DWI 0 "nonimmediate_operand"))
+(match_operand:DWI 1 "nonimmediate_operand"))
+  (const_int 0)))]
+  "ix86_pre_reload_split ()"
+  "#"
+  "&& 1"
+  [(parallel
+  [(set (match_dup 2) (and:DWI (not:DWI (match_dup 0)) (match_dup 1)))
+   (clobber (reg:CC FLAGS_REG))])
+   (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 2) (const_int 0)))]
 {
+  operands[0] = force_reg (mode, operands[0]);
   operands[2] = gen_reg_rtx (mode);
 })

I don't think we can count on a follow-up split to lower ANDN for
!TARGET_BMI case, it is also a pre-reload splitter.

Please emit ANDN only for TARGET_BMI and NOT/AND for !TARGET_BMI instead.

Uros.

> Thanks in advance,
> Roger
> --
>


Re: [pushed] c++: Include -Woverloaded-virtual in -Wall [PR87729]

2022-07-05 Thread Stephan Bergmann via Gcc-patches

On 01/07/2022 22:30, Stephan Bergmann wrote:

On 6/25/22 00:26, Jason Merrill via Gcc-patches wrote:

This seems like a good warning to have in -Wall, as requested.  But as
pointed out in PR20423, some users want a warning only when a derived
function doesn't override any base function.  So let's put that lesser
version in -Wall (and -Woverloaded-virtual=1) while leaving the semantics
for the existing option the same.


This now causes

[...]

moved that to a comment at 
 "Please include 
-Woverloaded-virtual in -Wall" now




Re: [x86 PATCH take #2] Doubleword version of and; cmp to not; test optimization.

2022-07-05 Thread Uros Bizjak via Gcc-patches
On Tue, Jul 5, 2022 at 9:56 AM Uros Bizjak  wrote:
>
> On Mon, Jul 4, 2022 at 9:11 PM Roger Sayle  wrote:
> >
> >
> > This patch is the latest revision of the patch originally posted at:
> > https://gcc.gnu.org/pipermail/gcc-patches/2022-June/596201.html
> >
> > This patch extends the earlier and;cmp to not;test optimization to also
> > perform this transformation for TImode on TARGET_64BIT and DImode on -m32,
> > One motivation for this is that it's a step to fixing the current failure
> > of gcc.target/i386/pr65105-5.c on -m32.
> >
> > A more direct benefit for x86_64 is that the following code:
> >
> > int foo(__int128 x, __int128 y)
> > {
> >   return (x & y) == y;
> > }
> >
> > improves with -O2 from 15 instructions:
> >
> > movq%rdi, %r8
> > movq%rsi, %rax
> > movq%rax, %rdi
> > movq%r8, %rsi
> > movq%rdx, %r8
> > andq%rdx, %rsi
> > andq%rcx, %rdi
> > movq%rsi, %rax
> > movq%rdi, %rdx
> > xorq%r8, %rax
> > xorq%rcx, %rdx
> > orq %rdx, %rax
> > sete%al
> > movzbl  %al, %eax
> > ret
> >
> > to the slightly better 13 instructions:
> >
> > movq%rdi, %r8
> > movq%rsi, %rax
> > movq%r8, %rsi
> > movq%rax, %rdi
> > notq%rsi
> > notq%rdi
> > andq%rdx, %rsi
> > andq%rcx, %rdi
> > movq%rsi, %rax
> > orq %rdi, %rax
> > sete%al
> > movzbl  %al, %eax
> > ret
> >
> > Now that all of the doubleword pieces are already in the tree, this
> > patch is now much shorter (an rtx_costs improvement and a single new
> > define_insn_and_split), however I couldn't resist including two very
> > minor pattern naming tweaks/clean-ups to fix nits.
> >
> > This revised patch has been tested on x86_64-pc-linux-gnu with
> > make bootstrap and make -k check, where on TARGET_64BIT there are
> > no new failures, and on --target_board=unix{-m32} with a single new
> > failure; the other dg-final in gcc.target/i386/pr65105-5.c now also
> > fails (as that code diverges further from the expected vectorized
> > output).  This is progress as both FAILs in pr65105-5.c may now be
> > fixed by changes localized to the STV pass.  OK for mainline?
> >
> >
> > 2022-07-04  Roger Sayle  
> >
> > gcc/ChangeLog
> > * config/i386/i386.cc (ix86_rtx_costs) : Provide costs
> > for double word comparisons and tests (comparisons against zero).
> > * config/i386/i386.md (*test_not_doubleword): Split DWI
> > and;cmp into andn;cmp $0 as a pre-reload splitter.
> > (*andn3_doubleword_bmi): Use  instead of  in name.
> > (*3_doubleword): Likewise.
> >
> > gcc/testsuite/ChangeLog
> > * gcc.target/i386/testnot-3.c: New test case.
> >
>
>
> +;; Split and;cmp (as optimized by combine) into andn;cmp $0
> +(define_insn_and_split "*test_not_doubleword"
> +  [(set (reg:CCZ FLAGS_REG)
> + (compare:CCZ
> +  (and:DWI
> +(not:DWI (match_operand:DWI 0 "nonimmediate_operand"))
> +(match_operand:DWI 1 "nonimmediate_operand"))
> +  (const_int 0)))]
> +  "ix86_pre_reload_split ()"
> +  "#"
> +  "&& 1"
> +  [(parallel
> +  [(set (match_dup 2) (and:DWI (not:DWI (match_dup 0)) (match_dup 1)))
> +   (clobber (reg:CC FLAGS_REG))])
> +   (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 2) (const_int 0)))]
>  {
> +  operands[0] = force_reg (mode, operands[0]);
>operands[2] = gen_reg_rtx (mode);
>  })
>
> I don't think we can count on a follow-up split to lower ANDN for
> !TARGET_BMI case, it is also a pre-reload splitter.

Actually, splitters *CAN* be chained:


Splitting with gen_split_231 (i386.md:10408)
scanning new insn with uid = 30.
scanning new insn with uid = 31.
deleting insn with uid = 12.
Splitting with gen_split_235 (i386.md:10444)
scanning new insn with uid = 32.
scanning new insn with uid = 33.
deleting insn with uid = 30.
Splitting with gen_split_2 (i386.md:1510)
scanning new insn with uid = 34.
scanning new insn with uid = 35.
scanning new insn with uid = 36.
scanning new insn with uid = 37.
deleting insn with uid = 31.
deleting insn with uid = 12.

INSNs are recognized after they are split.

The patch is OK as is.

Thanks,
Uros.


[Ada] Remove old vxworks6 from Makefile.rtl

2022-07-05 Thread Pierre-Marie de Rodat via Gcc-patches
Pre vxworks7 code excepting legacy vxworks6 code is removed from
Makefile.rtl and unused files are deleted.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* Makefile.rtl (*vxworks*): Remove most pre-vxworks7 code.
* vxworks-arm-link.spec: Remove.
* vxworks-e500-link.spec: Likewise.
* vxworks-smp-arm-link.spec: Likewise.
* vxworks-smp-e500-link.spec: Likewise.
* vxworks-smp-x86-link.spec: Likewise.
* libgnat/system-vxworks-arm-rtp-smp.ads: Likewise.
* libgnat/system-vxworks-arm-rtp.ads: Likewise.
* libgnat/system-vxworks-arm.ads: Likewise.
* libgnat/system-vxworks-e500-kernel.ads: Likewise.
* libgnat/system-vxworks-e500-rtp-smp.ads: Likewise.
* libgnat/system-vxworks-e500-rtp.ads: Likewise.
* libgnat/system-vxworks-x86-kernel.ads: Likewise.
* libgnat/system-vxworks-x86-rtp-smp.ads: Likewise.
* libgnat/system-vxworks-x86-rtp.ads: Likewise.

patch.diff.gz
Description: application/gzip


[Ada] Remove unimplemented convert_addresses declaration

2022-07-05 Thread Pierre-Marie de Rodat via Gcc-patches
convert_addresses is declared in adaint.h but is never referenced, so
remove it.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* adaint.h (convert_addresses): Remove function declaration.diff --git a/gcc/ada/adaint.h b/gcc/ada/adaint.h
--- a/gcc/ada/adaint.h
+++ b/gcc/ada/adaint.h
@@ -254,8 +254,6 @@ extern char  *__gnat_to_host_dir_spec  (char *, int);
 extern char  *__gnat_to_host_file_spec (char *);
 extern char  *__gnat_to_canonical_path_spec	   (char *);
 extern void   __gnat_adjust_os_resource_limits	   (void);
-extern void   convert_addresses			   (const char *, void *, int,
-		void *, int *);
 extern int__gnat_copy_attribs		   (char *, char *, int);
 extern int__gnat_feof		  	   (FILE *);
 extern int__gnat_ferror(FILE *);




[Ada] Fix clearly unintentional dead analysis of attribute Code_Address

2022-07-05 Thread Pierre-Marie de Rodat via Gcc-patches
A new warning about unreachable code that follows calls to procedures
with No_Return would flag a clearly unintentional dead call to
Set_Address_Taken in analysis of Code_Address attribute.

This patch resurrects the dead code, which is worth fixing regardless of
the new warning.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* sem_attr.adb (Analyze_Attribute): Move call to
Set_Address_Taken so that it is executed when the prefix
attribute is legal.diff --git a/gcc/ada/sem_attr.adb b/gcc/ada/sem_attr.adb
--- a/gcc/ada/sem_attr.adb
+++ b/gcc/ada/sem_attr.adb
@@ -3746,11 +3746,11 @@ package body Sem_Attr is
 Ekind (Entity (P)) /= E_Procedure)
  then
 Error_Attr ("invalid prefix for % attribute", P);
-Set_Address_Taken (Entity (P));
 
  --  Issue an error if the prefix denotes an eliminated subprogram
 
  else
+Set_Address_Taken (Entity (P));
 Check_For_Eliminated_Subprogram (P, Entity (P));
  end if;
 




[Ada] Remove redundant guards in detection of unreachable code

2022-07-05 Thread Pierre-Marie de Rodat via Gcc-patches
Routine Check_Unreachable_Code is only called on nodes belonging to a
list of statements (and it wouldn't make sense to call it on anything
else).

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* sem_ch5.adb (Check_Unreachable_Code): Remove redundant guard;
the call to Present wasn't needed either.diff --git a/gcc/ada/sem_ch5.adb b/gcc/ada/sem_ch5.adb
--- a/gcc/ada/sem_ch5.adb
+++ b/gcc/ada/sem_ch5.adb
@@ -4398,7 +4398,7 @@ package body Sem_Ch5 is
   P  : Node_Id;
 
begin
-  if Is_List_Member (N) and then Comes_From_Source (N) then
+  if Comes_From_Source (N) then
  Nxt := Original_Node (Next (N));
 
  --  Skip past pragmas
@@ -4415,8 +4415,7 @@ package body Sem_Ch5 is
 
  --  Otherwise see if we have a real statement following us
 
- elsif Present (Nxt)
-   and then Comes_From_Source (Nxt)
+ elsif Comes_From_Source (Nxt)
and then Is_Statement (Nxt)
  then
 --  Special very annoying exception. If we have a return that




[Ada] Remove comment about a long gone formal verification mode

2022-07-05 Thread Pierre-Marie de Rodat via Gcc-patches
Remove outdated a comment about the very first SPARK experiments
in GNAT.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* sem_ch6.adb (Check_Missing_Return): Remove outdated comment.diff --git a/gcc/ada/sem_ch6.adb b/gcc/ada/sem_ch6.adb
--- a/gcc/ada/sem_ch6.adb
+++ b/gcc/ada/sem_ch6.adb
@@ -2987,9 +2987,7 @@ package body Sem_Ch6 is
 
   procedure Check_Missing_Return;
   --  Checks for a function with a no return statements, and also performs
-  --  the warning checks implemented by Check_Returns. In formal mode, also
-  --  verify that a function ends with a RETURN and that a procedure does
-  --  not contain any RETURN.
+  --  the warning checks implemented by Check_Returns.
 
   function Disambiguate_Spec return Entity_Id;
   --  When a primitive is declared between the private view and the full




[Ada] Add RM reference to check for functions without a return statement

2022-07-05 Thread Pierre-Marie de Rodat via Gcc-patches
Add comment to explain why we have an error and not just a warning.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* sem_ch6.adb (Check_Missing_Return): Add reference to an RM rule.diff --git a/gcc/ada/sem_ch6.adb b/gcc/ada/sem_ch6.adb
--- a/gcc/ada/sem_ch6.adb
+++ b/gcc/ada/sem_ch6.adb
@@ -3568,6 +3568,10 @@ package body Sem_Ch6 is
Id := Body_Id;
 end if;
 
+--  A function body shall contain at least one return statement
+--  that applies to the function body, unless the function contains
+--  code_statements; RM 6.5(5).
+
 if Return_Present (Id) then
Check_Returns (HSS, 'F', Missing_Ret);
 




[Ada] Combine system.ads files - vxworks6 constants.

2022-07-05 Thread Pierre-Marie de Rodat via Gcc-patches
Systemitize Word_Size and Memory_Size declarations rather than hard code
with numerical values or OS specific Long_Integer size.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* libgnat/system-vxworks-ppc-kernel.ads (Word_Size): Compute
based on Standard'Word_Size.
(Memory_Size): Compute based on Word_Size.
* libgnat/system-vxworks-ppc-rtp-smp.ads: Likewise.
* libgnat/system-vxworks-ppc-rtp.ads: Likewise.diff --git a/gcc/ada/libgnat/system-vxworks-ppc-kernel.ads b/gcc/ada/libgnat/system-vxworks-ppc-kernel.ads
--- a/gcc/ada/libgnat/system-vxworks-ppc-kernel.ads
+++ b/gcc/ada/libgnat/system-vxworks-ppc-kernel.ads
@@ -69,8 +69,8 @@ package System is
Null_Address : constant Address;
 
Storage_Unit : constant := 8;
-   Word_Size: constant := 32;
-   Memory_Size  : constant := 2 ** 32;
+   Word_Size: constant := Standard'Word_Size;
+   Memory_Size  : constant := 2 ** Word_Size;
 
--  Address comparison
 


diff --git a/gcc/ada/libgnat/system-vxworks-ppc-rtp-smp.ads b/gcc/ada/libgnat/system-vxworks-ppc-rtp-smp.ads
--- a/gcc/ada/libgnat/system-vxworks-ppc-rtp-smp.ads
+++ b/gcc/ada/libgnat/system-vxworks-ppc-rtp-smp.ads
@@ -71,8 +71,8 @@ package System is
Null_Address : constant Address;
 
Storage_Unit : constant := 8;
-   Word_Size: constant := 32;
-   Memory_Size  : constant := 2 ** 32;
+   Word_Size: constant := Standard'Word_Size;
+   Memory_Size  : constant := 2 ** Word_Size;
 
--  Address comparison
 


diff --git a/gcc/ada/libgnat/system-vxworks-ppc-rtp.ads b/gcc/ada/libgnat/system-vxworks-ppc-rtp.ads
--- a/gcc/ada/libgnat/system-vxworks-ppc-rtp.ads
+++ b/gcc/ada/libgnat/system-vxworks-ppc-rtp.ads
@@ -71,8 +71,8 @@ package System is
Null_Address : constant Address;
 
Storage_Unit : constant := 8;
-   Word_Size: constant := 32;
-   Memory_Size  : constant := 2 ** 32;
+   Word_Size: constant := Standard'Word_Size;
+   Memory_Size  : constant := 2 ** Word_Size;
 
--  Address comparison
 




[Ada] Perform object rewriting as renaming only in the expander

2022-07-05 Thread Pierre-Marie de Rodat via Gcc-patches
The rewriting as renaming optimization for object declarations is done
partly during analysis, guarded with Expander_Active, and partly during
expansion, so it makes sense to do it entirely during expansion.

This merges the two cases and removes obsolete or unnecessary conditions
guarding the transformation in the process.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* exp_ch3.adb (Expand_N_Object_Declaration): Rewrite as a renaming
for any nonaliased local object with nominal unconstrained subtype
originally initialized with the result of a function call that has
been rewritten as the dereference of a reference to the result.
* sem_ch3.adb (Analyze_Object_Declaration): Do not do it herediff --git a/gcc/ada/exp_ch3.adb b/gcc/ada/exp_ch3.adb
--- a/gcc/ada/exp_ch3.adb
+++ b/gcc/ada/exp_ch3.adb
@@ -7675,59 +7675,54 @@ package body Exp_Ch3 is
 
 Rewrite_As_Renaming :=
 
-  --  If the object declaration appears in the form
+  --  The declaration cannot be rewritten if it has got constraints
+  --  in other words the nominal subtype must be unconstrained.
 
-  --Obj : Typ := Func (...);
+  Is_Entity_Name (Original_Node (Obj_Def))
 
-  --  where Typ needs finalization and is returned on the secondary
-  --  stack, the declaration can be rewritten into a dereference of
-  --  the reference to the result built on the secondary stack (see
-  --  Expand_Ctrl_Function_Call for this expansion of the call):
+--  The aliased case has to be excluded because the expression
+--  will not be aliased in the general case.
 
-  --type Axx is access all Typ;
-  --Rxx : constant Axx := Func (...)'reference;
-  --Obj : Typ renames Rxx.all;
+and then not Aliased_Present (N)
 
-  --  This avoids an extra copy and a pair of Adjust/Finalize calls
+--  If the object declaration originally appears in the form
 
-  ((not Is_Library_Level_Entity (Def_Id)
- and then Nkind (Expr_Q) = N_Explicit_Dereference
- and then not Comes_From_Source (Expr_Q)
- and then Nkind (Original_Node (Expr_Q)) = N_Function_Call
- and then Needs_Finalization (Typ)
- and then not Is_Class_Wide_Type (Typ))
+--Obj : Typ := Func (...);
 
---  If the initializing expression is for a variable with flag
---  OK_To_Rename set, then transform:
+--  and has been rewritten as the dereference of a reference
+--  to the function result built either on the primary or the
+--  secondary stack, then the declaration can be rewritten as
+--  the renaming of this dereference:
 
--- Obj : Typ := Expr;
+--type Axx is access all Typ;
+--Rxx : constant Axx := Func (...)'reference;
+--Obj : Typ renames Rxx.all;
 
---  into
+--  This avoids an extra copy and, in the case where Typ needs
+--  finalization, a pair of Adjust/Finalize calls (see below).
 
--- Obj : Typ renames Expr;
+and then
+  ((not Is_Library_Level_Entity (Def_Id)
+ and then Nkind (Expr_Q) = N_Explicit_Dereference
+ and then not Comes_From_Source (Expr_Q)
+ and then Nkind (Original_Node (Expr_Q)) = N_Function_Call
+ and then not Is_Class_Wide_Type (Typ))
 
---  provided that Obj is not aliased. The aliased case has to
---  be excluded because Expr will not be aliased in general.
+   --  If the initializing expression is a variable with the
+   --  flag OK_To_Rename set, then transform:
 
-   or else (not Aliased_Present (N)
- and then (OK_To_Rename_Ref (Expr_Q)
-or else
-   (Nkind (Expr_Q) = N_Slice
- and then
-OK_To_Rename_Ref (Prefix (Expr_Q))
+   -- Obj : Typ := Expr;
 
-  --  The declaration cannot be rewritten if it has got constraints
-  --  in other words the nominal subtype must be unconstrained.
+   --  into
+
+   -- Obj : Typ renames Expr;
 
-  and then Is_Entity_Name (Original_Node (Obj_Def))
+   or else OK_To_Rename_Ref (Expr_Q)
 
-  --  ??? Likewise if there are any aspect specifications, because
-  --  otherwise we duplicate that corresponding implicit attribute
-  -- 

[Ada] Remove redundant guard for call to List_Length with a No_List

2022-07-05 Thread Pierre-Marie de Rodat via Gcc-patches
Code cleanup related to a new detection of uninitialised local scalar
objects; semantics is unaffected.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* sem_ch5.adb (Analyze_Block_Statement): Call to List_Length with
No_List is safe and will return zero.diff --git a/gcc/ada/sem_ch5.adb b/gcc/ada/sem_ch5.adb
--- a/gcc/ada/sem_ch5.adb
+++ b/gcc/ada/sem_ch5.adb
@@ -1376,11 +1376,7 @@ package body Sem_Ch5 is
  --  Initialize unblocked exit count for statements of begin block
  --  plus one for each exception handler that is present.
 
- Unblocked_Exit_Count := 1;
-
- if Present (EH) then
-Unblocked_Exit_Count := Unblocked_Exit_Count + List_Length (EH);
- end if;
+ Unblocked_Exit_Count := 1 + List_Length (EH);
 
  --  If a label is present analyze it and mark it as referenced
 




[Ada] Cleanup in error about unreachable code

2022-07-05 Thread Pierre-Marie de Rodat via Gcc-patches
Cleanup only; behaviour is unaffected.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* sem_ch5.adb (Check_Unreachable_Code): Avoid explicit use of
Sloc; this should also help when we finally use Source_Span for
prettier error messages.diff --git a/gcc/ada/sem_ch5.adb b/gcc/ada/sem_ch5.adb
--- a/gcc/ada/sem_ch5.adb
+++ b/gcc/ada/sem_ch5.adb
@@ -4468,8 +4468,7 @@ package body Sem_Ch5 is
   end loop;
end if;
 
-   Error_Msg
- ("??unreachable code!", Sloc (Error_Node), Error_Node);
+   Error_Msg_N ("??unreachable code!", Error_Node);
 end if;
 
  --  If the unconditional transfer of control instruction is the




[Ada] Spurious error on qualified prefix in Pack.Func'Result

2022-07-05 Thread Pierre-Marie de Rodat via Gcc-patches
When using a qualified name such as Pack.Func as the prefix of a 'Result
attribute reference, the prefix is not fully resolved and may contain a
chain of homonyms. Look for the expected function in the homonym chain
instead of issuing an error if the first one is not the expected one.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* sem_attr.adb (Analyze_Attribute): Take into account the
possibility of homonyms.diff --git a/gcc/ada/sem_attr.adb b/gcc/ada/sem_attr.adb
--- a/gcc/ada/sem_attr.adb
+++ b/gcc/ada/sem_attr.adb
@@ -5835,6 +5835,12 @@ package body Sem_Attr is
 
 elsif Present (Over_Id) and then Pref_Id = Over_Id then
return True;
+
+--  When a qualified name is used for the prefix, homonyms may come
+--  before the current function in the homonym chain.
+
+elsif Has_Homonym (Pref_Id) then
+   return Denote_Same_Function (Homonym (Pref_Id), Spec_Id);
 end if;
 
 --  Otherwise the prefix does not denote the related subprogram




[Ada] Cleanup repeated code for aggregate constraints checks

2022-07-05 Thread Pierre-Marie de Rodat via Gcc-patches
Code cleanup related to examining uses of Check_Unset_Reference for
improved detection of uninitialised scalar objects. Semantics is
unaffected.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* sem_util.adb (Aggregate_Constraint_Checks): Fix whitespace;
refactor repeated code; replace a ??? comment with an
explanation based on the comment for the routine spec.diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb
--- a/gcc/ada/sem_util.adb
+++ b/gcc/ada/sem_util.adb
@@ -1153,7 +1153,7 @@ package body Sem_Util is
  (Exp   : Node_Id;
   Check_Typ : Entity_Id)
is
-  Exp_Typ : constant Entity_Id  := Etype (Exp);
+  Exp_Typ : constant Entity_Id := Etype (Exp);
 
begin
   if Raises_Constraint_Error (Exp) then
@@ -1236,12 +1236,12 @@ package body Sem_Util is
 and then Is_Scalar_Type (Check_Typ)
 and then Exp_Typ /= Check_Typ
   then
+ --  If expression is a constant, it is worthwhile checking whether it
+ --  is a bound of the type.
+
  if Is_Entity_Name (Exp)
and then Ekind (Entity (Exp)) = E_Constant
  then
---  If expression is a constant, it is worthwhile checking whether
---  it is a bound of the type.
-
 if (Is_Entity_Name (Type_Low_Bound (Check_Typ))
  and then Entity (Exp) = Entity (Type_Low_Bound (Check_Typ)))
   or else
@@ -1249,20 +1249,15 @@ package body Sem_Util is
  and then Entity (Exp) = Entity (Type_High_Bound (Check_Typ)))
 then
return;
-
-else
-   Rewrite (Exp, Convert_To (Check_Typ, Relocate_Node (Exp)));
-   Analyze_And_Resolve (Exp, Check_Typ);
-   Check_Unset_Reference (Exp);
 end if;
+ end if;
 
- --  Could use a comment on this case ???
+ --  Change Exp into Check_Typ'(Exp) to ensure that range checks are
+ --  performed at run time.
 
- else
-Rewrite (Exp, Convert_To (Check_Typ, Relocate_Node (Exp)));
-Analyze_And_Resolve (Exp, Check_Typ);
-Check_Unset_Reference (Exp);
- end if;
+ Rewrite (Exp, Convert_To (Check_Typ, Relocate_Node (Exp)));
+ Analyze_And_Resolve (Exp, Check_Typ);
+ Check_Unset_Reference (Exp);
 
   end if;
end Aggregate_Constraint_Checks;




[Ada] Remove exception propagation during bootstrap

2022-07-05 Thread Pierre-Marie de Rodat via Gcc-patches
To help the bootstrap path, we want to keep the compiler free from any
exception propagation during bootstrap. This has been broken recently in
various places.

Also introduce a way to more easily detect such breakage via the
-DNO_EXCEPTION_PROPAGATION which can now be used as part of BOOT_CFLAGS.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* exp_imgv.adb (Build_Enumeration_Image_Tables): Also disable
perfect hash in GNAT_Mode.
* raise-gcc.c (__gnat_Unwind_RaiseException): Add support for
disabling exception propagation.
* sem_eval.adb (Compile_Time_Known_Value): Update comment and
remove wrong call to Check_Error_Detected.
* sem_prag.adb (Check_Loop_Pragma_Grouping, Analyze_Pragma):
Remove exception propagation during bootstrap.diff --git a/gcc/ada/exp_imgv.adb b/gcc/ada/exp_imgv.adb
--- a/gcc/ada/exp_imgv.adb
+++ b/gcc/ada/exp_imgv.adb
@@ -289,12 +289,14 @@ package body Exp_Imgv is
  --  If the unit where the type is declared is the main unit, and the
  --  number of literals is greater than Threshold_For_Size when we are
  --  optimizing for size, and the restriction No_Implicit_Loops is not
- --  active, and -gnatd_h is not specified, generate the hash function.
+ --  active, and -gnatd_h is not specified, and not GNAT_Mode, generate
+ --  the hash function.
 
  if In_Main_Unit
and then (Optimize_Size = 0 or else Nlit > Threshold_For_Size)
and then not Restriction_Active (No_Implicit_Loops)
and then not Debug_Flag_Underscore_H
+   and then not GNAT_Mode
  then
 declare
LB : constant Positive := 2 * Positive (Nlit) + 1;


diff --git a/gcc/ada/raise-gcc.c b/gcc/ada/raise-gcc.c
--- a/gcc/ada/raise-gcc.c
+++ b/gcc/ada/raise-gcc.c
@@ -1377,6 +1377,10 @@ __gnat_cleanupunwind_handler (int version ATTRIBUTE_UNUSED,
 _Unwind_Reason_Code
 __gnat_Unwind_RaiseException (_Unwind_Exception *e)
 {
+#ifdef NO_EXCEPTION_PROPAGATION
+  abort();
+#endif
+
 #ifdef __USING_SJLJ_EXCEPTIONS__
   return _Unwind_SjLj_RaiseException (e);
 #else


diff --git a/gcc/ada/sem_eval.adb b/gcc/ada/sem_eval.adb
--- a/gcc/ada/sem_eval.adb
+++ b/gcc/ada/sem_eval.adb
@@ -1816,10 +1816,10 @@ package body Sem_Eval is
 
begin
   --  Never known at compile time if bad type or raises Constraint_Error
-  --  or empty (latter case occurs only as a result of a previous error).
+  --  or empty (which can occur as a result of a previous error or in the
+  --  case of e.g. an imported constant).
 
   if No (Op) then
- Check_Error_Detected;
  return False;
 
   elsif Op = Error


diff --git a/gcc/ada/sem_prag.adb b/gcc/ada/sem_prag.adb
--- a/gcc/ada/sem_prag.adb
+++ b/gcc/ada/sem_prag.adb
@@ -6152,15 +6152,11 @@ package body Sem_Prag is
  
 
  procedure Check_Loop_Pragma_Grouping (Loop_Stmt : Node_Id) is
-Stop_Search : exception;
---  This exception is used to terminate the recursive descent of
---  routine Check_Grouping.
-
-procedure Check_Grouping (L : List_Id);
+function Check_Grouping (L : List_Id) return Boolean;
 --  Find the first group of pragmas in list L and if successful,
 --  ensure that the current pragma is part of that group. The
---  routine raises Stop_Search once such a check is performed to
---  halt the recursive descent.
+--  routine returns True once such a check is performed to
+--  stop the analysis.
 
 procedure Grouping_Error (Prag : Node_Id);
 pragma No_Return (Grouping_Error);
@@ -6171,7 +6167,7 @@ package body Sem_Prag is
 -- Check_Grouping --
 
 
-procedure Check_Grouping (L : List_Id) is
+function Check_Grouping (L : List_Id) return Boolean is
HSS  : Node_Id;
Stmt : Node_Id;
Prag : Node_Id := Empty; -- init to avoid warning
@@ -6219,7 +6215,7 @@ package body Sem_Prag is
--  Stop the search as the placement is legal.
 
if Stmt = N then
-  raise Stop_Search;
+  return True;
 
--  Skip group members, but keep track of the
--  last pragma in the group.
@@ -6266,15 +6262,21 @@ package body Sem_Prag is
   elsif Nkind (Stmt) = N_Block_Statement then
  HSS := Handled_Statement_Sequence (Stmt);
 
- Check_Grouping (Declarations (Stmt));
+ if Check_Grouping (Declarations (Stmt)) then
+return True;
+ end if;
 
  if Present (HSS) then
-

[Ada] Remove unnecessary dead code after calls to nonreturning procedures

2022-07-05 Thread Pierre-Marie de Rodat via Gcc-patches
A new warning about unreachable code that follows calls to procedures
with No_Return would flag some dead defensive code. Comments next to
this code suggest that it was added to please some ancient version of
the compiler, but recent releases of GNAT do not require such a code.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* gnatls.adb (Corresponding_Sdep_Entry): Remove dead return
statement in defensive path; there is another return statement
for a normal execution of this routine, so rule Ada RM 6.5(5),
which requires function to have at least one return statement is
still satisfied.
(Gnatls): Remove dead, call to nonreturning Exit_Program after
Output_License_Information which itself does not return.
* libgnat/a-exstat.adb (Bad_EO): Remove raise statement that was
meant to please some ancient version of GNAT.
* libgnat/g-awk.adb (Raise_With_Info): Likewise.
* sem_attr.adb (Check_Reference): Remove dead return statement;
rule Ada RM 6.5(5), which requires function to have at least one
return statement is still satisfied.
(Analyze_Attribute): Remove dead exit statement.
(Check_Reference): Same as above.
* sem_ch12.adb (Instantiate_Formal_Package): Remove dead raise
statement; it was inconsistent with other calls to
Abandon_Instantiation, which are not followed by a raise
statement.
* sem_prag.adb (Process_Convention): Remove dead defensive
assignment.
(Interrupt_State): Remove dead defensive exit statement.
(Do_SPARK_Mode): Likewise.
* sfn_scan.adb (Scan_String): Remove dead defensive assignment.diff --git a/gcc/ada/gnatls.adb b/gcc/ada/gnatls.adb
--- a/gcc/ada/gnatls.adb
+++ b/gcc/ada/gnatls.adb
@@ -319,7 +319,6 @@ procedure Gnatls is
   Write_Eol;
   Error_Msg ("wrong ALI format, can't find dependency line for $ in {");
   Exit_Program (E_Fatal);
-  return No_Sdep_Id;
end Corresponding_Sdep_Entry;
 
-
@@ -2051,7 +2050,6 @@ begin
if License then
   if Arg_Count = 2 then
  Output_License_Information;
- Exit_Program (E_Success);
 
   else
  Set_Standard_Error;


diff --git a/gcc/ada/libgnat/a-exstat.adb b/gcc/ada/libgnat/a-exstat.adb
--- a/gcc/ada/libgnat/a-exstat.adb
+++ b/gcc/ada/libgnat/a-exstat.adb
@@ -109,13 +109,6 @@ package body Stream_Attributes is
  Raise_Exception
(Program_Error'Identity,
 "bad exception occurrence in stream input");
-
- --  The following junk raise of Program_Error is required because
- --  this is a No_Return procedure, and unfortunately Raise_Exception
- --  can return (this particular call can't, but the back end is not
- --  clever enough to know that).
-
- raise Program_Error;
   end Bad_EO;
 
   procedure Next_String is


diff --git a/gcc/ada/libgnat/g-awk.adb b/gcc/ada/libgnat/g-awk.adb
--- a/gcc/ada/libgnat/g-awk.adb
+++ b/gcc/ada/libgnat/g-awk.adb
@@ -1211,7 +1211,6 @@ package body GNAT.AWK is
   Exceptions.Raise_Exception
 (E,
  '[' & Filename & ':' & Line & "] " & Message);
-  raise Constraint_Error; -- to please GNAT as this is a No_Return proc
end Raise_With_Info;
 
---


diff --git a/gcc/ada/sem_attr.adb b/gcc/ada/sem_attr.adb
--- a/gcc/ada/sem_attr.adb
+++ b/gcc/ada/sem_attr.adb
@@ -4747,7 +4747,6 @@ package body Sem_Attr is
   Error_Attr
 ("prefix of attribute % cannot reference local entities",
  Nod);
-  return Abandon;
else
   return OK;
end if;
@@ -4989,7 +4988,6 @@ package body Sem_Attr is
 else
Error_Attr
  ("attribute % cannot appear in body or accept statement", N);
-   exit;
 end if;
  end loop;
 
@@ -5383,7 +5381,6 @@ package body Sem_Attr is
   Error_Attr
 ("prefix of attribute % cannot reference local entities",
  Nod);
-  return Abandon;
 
--  Otherwise keep inspecting the prefix
 


diff --git a/gcc/ada/sem_ch12.adb b/gcc/ada/sem_ch12.adb
--- a/gcc/ada/sem_ch12.adb
+++ b/gcc/ada/sem_ch12.adb
@@ -10572,7 +10572,6 @@ package body Sem_Ch12 is
  Error_Msg_N
("expect package instance to instantiate formal", Actual);
  Abandon_Instantiation (Actual);
- raise Program_Error;
 
   else
  Actual_Pack := Entity (Actual);


diff --git a/gcc/ada/sem_prag.adb b/gcc/ada/sem_prag.adb
--- a/gcc/ada/sem_prag.adb
+++ b/gcc/ada/sem_prag.adb
@@ -8336,7 +8336,6 @@ package body Sem_Prag is
Error_Pragma_Arg
  ("argument of pragma% must be subprogram or access type",
   Arg2);
-   

[Ada] Remove repeated analysis for pragma Thread_Local_Storage

2022-07-05 Thread Pierre-Marie de Rodat via Gcc-patches
When analysing pragma Thread_Local_Storage its argument is analysed by
the call to Check_Arg_Is_Library_Level_Local_Name. There is no need to
reanalyse it. Code cleanup; behaviour is not affected.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* sem_prag.adb (Analyze_Pragma): Remove unnecessary call to
Analyze.diff --git a/gcc/ada/sem_prag.adb b/gcc/ada/sem_prag.adb
--- a/gcc/ada/sem_prag.adb
+++ b/gcc/ada/sem_prag.adb
@@ -24861,7 +24861,6 @@ package body Sem_Prag is
 Check_Arg_Is_Library_Level_Local_Name (Arg1);
 
 Id := Get_Pragma_Arg (Arg1);
-Analyze (Id);
 
 if not Is_Entity_Name (Id)
   or else Ekind (Entity (Id)) /= E_Variable




[Ada] Annotate GNAT.Sockets with No_Return aspects

2022-07-05 Thread Pierre-Marie de Rodat via Gcc-patches
Opportunity for extra annotations spotted while fixing detection of
unreachable code that follows calls to procedures annotated with
No_Return.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* libgnat/g-socket.adb (Raise_Host_Error): Add No_Return aspect.
(Raise_GAI_Error): Likewise.
* libgnat/g-socket.ads (Raise_Socket_Error): Likewise.diff --git a/gcc/ada/libgnat/g-socket.adb b/gcc/ada/libgnat/g-socket.adb
--- a/gcc/ada/libgnat/g-socket.adb
+++ b/gcc/ada/libgnat/g-socket.adb
@@ -191,12 +191,14 @@ package body GNAT.Sockets is
else Value);
--  Removes dot at the end of error message
 
-   procedure Raise_Host_Error (H_Error : Integer; Name : String);
+   procedure Raise_Host_Error (H_Error : Integer; Name : String)
+   with No_Return;
--  Raise Host_Error exception with message describing error code (note
--  hstrerror seems to be obsolete) from h_errno. Name is the name
--  or address that was being looked up.
 
-   procedure Raise_GAI_Error (RC : C.int; Name : String);
+   procedure Raise_GAI_Error (RC : C.int; Name : String)
+   with No_Return;
--  Raise Host_Error with exception message in case of errors in
--  getaddrinfo and getnameinfo.
 


diff --git a/gcc/ada/libgnat/g-socket.ads b/gcc/ada/libgnat/g-socket.ads
--- a/gcc/ada/libgnat/g-socket.ads
+++ b/gcc/ada/libgnat/g-socket.ads
@@ -1593,7 +1593,7 @@ private
Wait_For_A_Full_Reception : constant Request_Flag_Type := 4;
Send_End_Of_Record: constant Request_Flag_Type := 8;
 
-   procedure Raise_Socket_Error (Error : Integer);
+   procedure Raise_Socket_Error (Error : Integer) with No_Return;
--  Raise Socket_Error with an exception message describing the error code
--  from errno.
 




[Ada] Remove return statements after procedure calls that don't return

2022-07-05 Thread Pierre-Marie de Rodat via Gcc-patches
A new warning about unreachable code that follows calls to procedures
with No_Return would flag many unnecessary return statements. Those
returns statements were applied inconsistently, so this patch is
actually more a style cleanup.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* sem_attr.adb, sem_prag.adb: Remove dead return statements
after calls to Error_Attr, Error_Pragma, Error_Pragma_Arg and
Placement_Error. All these calls raise exceptions that are
handled to gently recover from errors.diff --git a/gcc/ada/sem_attr.adb b/gcc/ada/sem_attr.adb
--- a/gcc/ada/sem_attr.adb
+++ b/gcc/ada/sem_attr.adb
@@ -1090,7 +1090,6 @@ package body Sem_Attr is
 
else
   Error_Attr ("% attribute cannot be applied to type", P);
-  return;
end if;
 end if;
  end if;
@@ -1429,7 +1428,6 @@ package body Sem_Attr is
 
 else
Placement_Error;
-   return;
 end if;
 
  --  'Old attribute reference ok in a _Postconditions procedure
@@ -1445,7 +1443,6 @@ package body Sem_Attr is
 
  else
 Placement_Error;
-return;
  end if;
 
  --  Find the related subprogram subject to the aspect or pragma
@@ -1715,14 +1712,12 @@ package body Sem_Attr is
 
 else
Placement_Error;
-   return;
 end if;
 
  --  Otherwise the placement of the attribute is illegal
 
  else
 Placement_Error;
-return;
  end if;
 
  --  Find the related subprogram subject to the aspect or pragma
@@ -3666,7 +3661,6 @@ package body Sem_Attr is
 
  else
 Error_Attr ("invalid entry name", N);
-return;
  end if;
 
  for J in reverse 0 .. Scope_Stack.Last loop
@@ -3945,7 +3939,6 @@ package body Sem_Attr is
else
   Error_Attr ("invalid entry family name", P);
end if;
-   return;
 
 else
Ent := Entity (Prefix (P));
@@ -3960,7 +3953,6 @@ package body Sem_Attr is
 
  else
 Error_Attr ("invalid entry name", N);
-return;
  end if;
 
  for J in reverse 0 .. Scope_Stack.Last loop
@@ -4479,7 +4471,6 @@ package body Sem_Attr is
 
  if not Legal or else No (Spec_Id) then
 Error_Attr ("attribute % must apply to entry family", P);
-return;
  end if;
 
  --  Legality checks
@@ -5898,7 +5889,6 @@ package body Sem_Attr is
 
  elsif not Legal then
 Error_Attr ("prefix of % attribute must be a function", P);
-return;
  end if;
 
  --  Attribute 'Result is part of a _Postconditions procedure. There is


diff --git a/gcc/ada/sem_prag.adb b/gcc/ada/sem_prag.adb
--- a/gcc/ada/sem_prag.adb
+++ b/gcc/ada/sem_prag.adb
@@ -4585,7 +4585,6 @@ package body Sem_Prag is
 
  else
 Pragma_Misplaced;
-return;
  end if;
 
  --  If we get here, then the pragma is legal
@@ -4600,7 +4599,6 @@ package body Sem_Prag is
and then Ekind (Scope (Spec_Id)) /= E_Protected_Type
  then
 Pragma_Misplaced;
-return;
 
  --  When the related context is an anonymous object created for a
  --  simple concurrent type, the type must be a task
@@ -4610,7 +4608,6 @@ package body Sem_Prag is
and then Ekind (Etype (Spec_Id)) /= E_Task_Type
  then
 Pragma_Misplaced;
-return;
  end if;
 
  --  A pragma that applies to a Ghost entity becomes Ghost for the
@@ -4926,7 +4923,6 @@ package body Sem_Prag is
 
  else
 Pragma_Misplaced;
-return;
  end if;
 
  Subp_Id := Defining_Entity (Subp_Decl);
@@ -4991,7 +4987,6 @@ package body Sem_Prag is
   N_Task_Body  | N_Task_Body_Stub
  then
 Pragma_Misplaced;
-return;
  end if;
 
  Body_Id := Defining_Entity (Body_Decl);
@@ -5002,14 +4997,12 @@ package body Sem_Prag is
 
  if No (Spec_Id) then
 Error_Pragma ("pragma % cannot apply to a stand alone body");
-return;
 
  --  Catch the case where the subprogram body is a subunit and acts as
  --  the third declaration of the subprogram.
 
  elsif Nkind (Parent (Body_Decl)) = N_Subunit then
 Error_Pragma ("pragma % cannot apply to a subunit");
-return;
  end if;
 
  --  A refined pragma can only apply to the body [stub] of a subprogram
@@ -5034,7 +5027,6 @@ package body Sem_Prag is
 Error_Pragma
   (Fix_Msg (Spec_Id, "pragma % must apply to the body of "
& "subprogram declared in a package specification"));
-return;
 

[Ada] Misc cleanup related to finalization

2022-07-05 Thread Pierre-Marie de Rodat via Gcc-patches
This patch cleans up some code issues found while working on
finalization, and adds some debugging aids.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* exp_ch7.adb: Change two constants Is_Protected_Body and
Is_Prot_Body to be Is_Protected_Subp_Body; these are not true
for protected bodies, but for protected subprogram bodies.
(Expand_Cleanup_Actions): No need to search for
Activation_Chain_Entity; just use Activation_Chain_Entity.
* sem_ch8.adb (Find_Direct_Name): Use Entyp constant.
* atree.adb, atree.ads, atree.h, nlists.adb, nlists.ads
(Parent): Provide nonoverloaded versions of Parent, so that they
can be easily found in the debugger.
* debug_a.adb, debug_a.ads: Clarify that we're talking about the
-gnatda switch; switches are case sensitive.  Print out the
Chars field if appropriate, which makes it easier to find things
in the output.
(Debug_Output_Astring): Simplify. Also fix an off-by-one
bug ("for I in Vbars'Length .." should have been "for I in
Vbars'Length + 1 ..").  Before, it was printing Debug_A_Depth +
1 '|' characters if Debug_A_Depth > Vbars'Length.diff --git a/gcc/ada/atree.adb b/gcc/ada/atree.adb
--- a/gcc/ada/atree.adb
+++ b/gcc/ada/atree.adb
@@ -1966,7 +1966,7 @@ package body Atree is
   end if;
end Paren_Count;
 
-   function Parent (N : Node_Or_Entity_Id) return Node_Or_Entity_Id is
+   function Node_Parent (N : Node_Or_Entity_Id) return Node_Or_Entity_Id is
begin
   pragma Assert (Present (N));
 
@@ -1975,7 +1975,7 @@ package body Atree is
   else
  return Node_Or_Entity_Id (Link (N));
   end if;
-   end Parent;
+   end Node_Parent;
 
-
-- Present --
@@ -2292,12 +2292,12 @@ package body Atree is
-- Set_Parent --

 
-   procedure Set_Parent (N : Node_Or_Entity_Id; Val : Node_Or_Entity_Id) is
+   procedure Set_Node_Parent (N : Node_Or_Entity_Id; Val : Node_Or_Entity_Id) is
begin
   pragma Assert (Present (N));
   pragma Assert (not In_List (N));
   Set_Link (N, Union_Id (Val));
-   end Set_Parent;
+   end Set_Node_Parent;
 

-- Set_Reporting_Proc --


diff --git a/gcc/ada/atree.ads b/gcc/ada/atree.ads
--- a/gcc/ada/atree.ads
+++ b/gcc/ada/atree.ads
@@ -446,10 +446,15 @@ package Atree is
--  Tests given Id for equality with the Empty node. This allows notations
--  like "if No (Variant_Part)" as opposed to "if Variant_Part = Empty".
 
-   function Parent (N : Node_Or_Entity_Id) return Node_Or_Entity_Id;
+   function Node_Parent (N : Node_Or_Entity_Id) return Node_Or_Entity_Id;
+   pragma Inline (Node_Parent);
+   function Parent (N : Node_Or_Entity_Id) return Node_Or_Entity_Id
+ renames Node_Parent;
pragma Inline (Parent);
--  Returns the parent of a node if the node is not a list member, or else
--  the parent of the list containing the node if the node is a list member.
+   --  Parent has the same name as the one in Nlists; Node_Parent can be used
+   --  more easily in the debugger.
 
function Paren_Count (N : Node_Id) return Nat;
pragma Inline (Paren_Count);
@@ -465,7 +470,10 @@ package Atree is
--  Note that this routine is used only in very peculiar cases. In normal
--  cases, the Original_Node link is set by calls to Rewrite.
 
-   procedure Set_Parent (N : Node_Or_Entity_Id; Val : Node_Or_Entity_Id);
+   procedure Set_Node_Parent (N : Node_Or_Entity_Id; Val : Node_Or_Entity_Id);
+   pragma Inline (Set_Node_Parent);
+   procedure Set_Parent (N : Node_Or_Entity_Id; Val : Node_Or_Entity_Id)
+ renames Set_Node_Parent;
pragma Inline (Set_Parent);
 
procedure Set_Paren_Count (N : Node_Id; Val : Nat);


diff --git a/gcc/ada/atree.h b/gcc/ada/atree.h
--- a/gcc/ada/atree.h
+++ b/gcc/ada/atree.h
@@ -35,7 +35,7 @@
 extern "C" {
 #endif
 
-#define Parent atree__parent
+#define Parent atree__node_parent
 extern Node_Id Parent (Node_Id);
 
 #define Original_Node atree__original_node


diff --git a/gcc/ada/debug_a.adb b/gcc/ada/debug_a.adb
--- a/gcc/ada/debug_a.adb
+++ b/gcc/ada/debug_a.adb
@@ -25,6 +25,7 @@
 
 with Atree;  use Atree;
 with Debug;  use Debug;
+with Namet;  use Namet;
 with Sinfo;  use Sinfo;
 with Sinfo.Nodes;use Sinfo.Nodes;
 with Sinput; use Sinput;
@@ -33,7 +34,7 @@ with Output; use Output;
 package body Debug_A is
 
Debug_A_Depth : Natural := 0;
-   --  Output for the debug A flag is preceded by a sequence of vertical bar
+   --  Output for the -gnatda switch is preceded by a sequence of vertical bar
--  characters corresponding to the recursion depth of the actions being
--  recorded (analysis, expansion, resolution and evaluation of nodes)
--  This variable records the depth.
@@ -66,7 +67,7 @@ package body Debug_A is
 
procedure Debug_A_Entry (S : String; N : Node_Id) is
b

[Ada] Remove redundant protection against empty lists

2022-07-05 Thread Pierre-Marie de Rodat via Gcc-patches
Calls to First on No_List intentionally return Empty node, so explicit
guards against No_List are unnecessary. Code cleanup; semantics is
unaffected.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* exp_code.adb (Setup_Asm_IO_Args): Remove guard against No_List.
* par_sco.adb (Process_Decisions): Likewise.
* sem_ch13.adb (Check_Component_List): Likewise.
* sem_ch6.adb (FCL): Likewise.diff --git a/gcc/ada/exp_code.adb b/gcc/ada/exp_code.adb
--- a/gcc/ada/exp_code.adb
+++ b/gcc/ada/exp_code.adb
@@ -471,11 +471,7 @@ package body Exp_Code is
   --  Case of list of arguments
 
   elsif Nkind (Arg) = N_Aggregate then
- if Expressions (Arg) = No_List then
-Operand_Var := Empty;
- else
-Operand_Var := First (Expressions (Arg));
- end if;
+ Operand_Var := First (Expressions (Arg));
 
   --  Otherwise must be default (no operands) case
 


diff --git a/gcc/ada/par_sco.adb b/gcc/ada/par_sco.adb
--- a/gcc/ada/par_sco.adb
+++ b/gcc/ada/par_sco.adb
@@ -480,13 +480,11 @@ package body Par_SCO is
   N : Node_Id;
 
begin
-  if L /= No_List then
- N := First (L);
- while Present (N) loop
-Process_Decisions (N, T, Pragma_Sloc);
-Next (N);
- end loop;
-  end if;
+  N := First (L);
+  while Present (N) loop
+ Process_Decisions (N, T, Pragma_Sloc);
+ Next (N);
+  end loop;
end Process_Decisions;
 
--  Version taking a node


diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb
--- a/gcc/ada/sem_ch13.adb
+++ b/gcc/ada/sem_ch13.adb
@@ -12135,24 +12135,22 @@ package body Sem_Ch13 is
 begin
--  Gather discriminants into Comp
 
-   if DS /= No_List then
-  Citem := First (DS);
-  while Present (Citem) loop
- if Nkind (Citem) = N_Discriminant_Specification then
-declare
-   Ent : constant Entity_Id :=
-   Defining_Identifier (Citem);
-begin
-   if Ekind (Ent) = E_Discriminant then
-  Ncomps := Ncomps + 1;
-  Comps (Ncomps) := Ent;
-   end if;
-end;
- end if;
+   Citem := First (DS);
+   while Present (Citem) loop
+  if Nkind (Citem) = N_Discriminant_Specification then
+ declare
+Ent : constant Entity_Id :=
+Defining_Identifier (Citem);
+ begin
+if Ekind (Ent) = E_Discriminant then
+   Ncomps := Ncomps + 1;
+   Comps (Ncomps) := Ent;
+end if;
+ end;
+  end if;
 
- Next (Citem);
-  end loop;
-   end if;
+  Next (Citem);
+   end loop;
 
--  Gather component entities into Comp
 


diff --git a/gcc/ada/sem_ch6.adb b/gcc/ada/sem_ch6.adb
--- a/gcc/ada/sem_ch6.adb
+++ b/gcc/ada/sem_ch6.adb
@@ -9988,17 +9988,8 @@ package body Sem_Ch6 is
  N2 : Node_Id;
 
   begin
- if L1 = No_List then
-N1 := Empty;
- else
-N1 := First (L1);
- end if;
-
- if L2 = No_List then
-N2 := Empty;
- else
-N2 := First (L2);
- end if;
+ N1 := First (L1);
+ N2 := First (L2);
 
  --  Compare two lists, skipping rewrite insertions (we want to compare
  --  the original trees, not the expanded versions).




[Ada] Fix dangling bounds for array result of BIP functions

2022-07-05 Thread Pierre-Marie de Rodat via Gcc-patches
The implementation of the build-in-place return protocol for functions
whose result type is an unconstrained array type generates dangling
references to local bounds built on the stack for the result as soon as
these bounds are not static.  The reason is that the implementation
treats the return object, either explicitly present in the source or
synthesized by the compiler, as a regular constrained object until very
late in the game, although it needs to be ultimately rewritten as the
renaming of the dereference of an allocator with unconstrained designated
type in order for the bounds to be part of the allocation.

Recently a partial fix was implemented for the case where the result is an
aggregate, by preventing the return object from being expanded after it has
been analyzed.  However, it does not work for the general case of extended
return statements, because the statements therein are still analyzed with
the constrained version of the return object so, after it is changed into
the unconstrained renaming, this yields (sub)type mismatches.

Therefore this change goes the other way around: it rolls back the partial
fix and instead performs the transformation of the return object into the
unconstrained renaming during the expansion of its declaration, in other
words before statements referencing it, if any, are analyzed, thus ensuring
that they see the final version of the object.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* exp_aggr.adb (Expand_Array_Aggregate): Remove obsolete code.
Delay the expansion of aggregates initializing return objects of
build-in-place functions.
* exp_ch3.ads (Ensure_Activation_Chain_And_Master): Delete.
* exp_ch3.adb (Ensure_Activation_Chain_And_Master): Fold back to...
(Expand_N_Object_Declaration): ...here.
Perform the expansion of return objects of build-in-place functions
here instead of...
* exp_ch6.ads (Is_Build_In_Place_Return_Object): Declare.
* exp_ch6.adb (Expand_N_Extended_Return_Statement): ...here.
(Is_Build_In_Place_Result_Type): Alphabetize.
(Is_Build_In_Place_Return_Object): New predicate.
* exp_ch7.adb (Enclosing_Function): Delete.
(Process_Object_Declaration): Tidy up handling of return objects.
* sem_ch3.adb (Analyze_Object_Declaration): Do not decorate and
freeze the actual type if it is the same as the nominal type.
* sem_ch6.adb: Remove use and with clauses for Exp_Ch3.
(Analyze_Function_Return): Analyze again all return objects.
(Create_Extra_Formals): Do not force the definition of an Itype
if the subprogram is a compilation unit.

patch.diff.gz
Description: application/gzip


[Ada] qnx-7.1: ACATS cxag001 failure on qnx - realpath

2022-07-05 Thread Pierre-Marie de Rodat via Gcc-patches
The implementation of __gnat_full_name uses the CRTL realpath, however
this function returns a null string so use the default implementation
instead.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* cstreams.c (__gnat_full_name) [QNX]: Remove block.diff --git a/gcc/ada/cstreams.c b/gcc/ada/cstreams.c
--- a/gcc/ada/cstreams.c
+++ b/gcc/ada/cstreams.c
@@ -202,19 +202,6 @@ __gnat_full_name (char *nam, char *buffer)
  getcwd approach instead. */
   realpath (nam, buffer);
 
-#elif defined (__QNX__)
-
-  int length;
-
-  if (__gnat_is_absolute_path (nam, strlen (nam)))
-realpath (nam, buffer);
-  else
-{
-  length = __gnat_max_path_len;
-  __gnat_get_current_dir (buffer, &length);
-  strncat (buffer, nam, __gnat_max_path_len - length - 1);
-}
-
 #elif defined (__vxworks)
 
   /* On VxWorks systems, an absolute path can be represented (depending on




[Ada] Fix comments mentioning ancient flags related to objects references

2022-07-05 Thread Pierre-Marie de Rodat via Gcc-patches
Flag May_Be_Modified under go a series of renamings between 1996 and
2002.  It was changed to Not_Assigned, then to Not_Source_Assigned and
finally to Never_Set_In_Source. Fix remaining references in comments.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* sem_util.ads (Note_Possible_Modification): Fix occurrence of
May_Be_Modified in comment.
* sem_warn.ads (Check_Unset_Reference): Fix occurrence of
Not_Assigned in comment.diff --git a/gcc/ada/sem_util.ads b/gcc/ada/sem_util.ads
--- a/gcc/ada/sem_util.ads
+++ b/gcc/ada/sem_util.ads
@@ -2872,7 +2872,7 @@ package Sem_Util is
--  This routine is called if the sub-expression N maybe the target of
--  an assignment (e.g. it is the left side of an assignment, used as
--  an out parameters, or used as prefixes of access attributes). It
-   --  sets May_Be_Modified in the associated entity if there is one,
+   --  sets Never_Set_In_Source in the associated entity if there is one,
--  taking into account the rule that in the case of renamed objects,
--  it is the flag in the renamed object that must be set.
--


diff --git a/gcc/ada/sem_warn.ads b/gcc/ada/sem_warn.ads
--- a/gcc/ada/sem_warn.ads
+++ b/gcc/ada/sem_warn.ads
@@ -86,15 +86,15 @@ package Sem_Warn is
--  N is the node for an expression which occurs in a reference position,
--  e.g. as the right side of an assignment. This procedure checks to see
--  if the node is a reference to a variable entity where the entity has
-   --  Not_Assigned set. If so, the Unset_Reference field is set if it is not
-   --  the first occurrence. No warning is posted, instead warnings will be
-   --  posted later by Check_References. The reason we do things that
-   --  way is that if there are no assignments anywhere, we prefer to flag
-   --  the entity, rather than a reference to it. Note that for the purposes
-   --  of this routine, a type conversion or qualified expression whose
-   --  expression is an entity is also processed. The reason that we do not
-   --  process these at the point of occurrence is that both these constructs
-   --  can occur in non-reference positions (e.g. as out parameters).
+   --  Never_Set_In_Source set. If so, the Unset_Reference field is set if it
+   --  is not the first occurrence. No warning is posted, instead warnings will
+   --  be posted later by Check_References. The reason we do things that way is
+   --  that if there are no assignments anywhere, we prefer to flag the entity,
+   --  rather than a reference to it. Note that for the purposes of this
+   --  routine, a type conversion or qualified expression whose expression is
+   --  an entity is also processed. The reason that we do not process these
+   --  at the point of occurrence is that both these constructs can occur in
+   --  non-reference positions (e.g. as out parameters).
 
procedure Check_Unused_Withs (Spec_Unit : Unit_Number_Type := No_Unit);
--  This routine performs two kinds of checks. It checks that all with'ed




[Ada] Reorder processing of default expressions to avoid repeated calls

2022-07-05 Thread Pierre-Marie de Rodat via Gcc-patches
Code cleanup related to improved detection of uninitialised objects;
semantics is unaffected.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* sem_ch6.adb (Process_Formals): Avoid repeated calls to
Expression.diff --git a/gcc/ada/sem_ch6.adb b/gcc/ada/sem_ch6.adb
--- a/gcc/ada/sem_ch6.adb
+++ b/gcc/ada/sem_ch6.adb
@@ -12985,10 +12985,10 @@ package body Sem_Ch6 is
  Set_Formal_Mode (Formal);
 
  if Ekind (Formal) = E_In_Parameter then
-Set_Default_Value (Formal, Expression (Param_Spec));
+Default := Expression (Param_Spec);
 
-if Present (Expression (Param_Spec)) then
-   Default := Expression (Param_Spec);
+if Present (Default) then
+   Set_Default_Value (Formal, Default);
 
if Is_Scalar_Type (Etype (Default)) then
   if Nkind (Parameter_Type (Param_Spec)) /=




[Ada] Fix spurious error on object renaming with ghost type

2022-07-05 Thread Pierre-Marie de Rodat via Gcc-patches
Renaming of an object of ghost type leads to a spurious error.  Now
fixed.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* ghost.adb (Is_OK_Ghost_Context): Detect ghost type inside object
renaming.diff --git a/gcc/ada/ghost.adb b/gcc/ada/ghost.adb
--- a/gcc/ada/ghost.adb
+++ b/gcc/ada/ghost.adb
@@ -508,7 +508,16 @@ package body Ghost is
elsif Nkind (Parent (Par)) in N_Generic_Instantiation
| N_Renaming_Declaration
| N_Generic_Renaming_Declaration
-   and then Par = Name (Parent (Par))
+ and then Par = Name (Parent (Par))
+   then
+  return True;
+
+   --  In the case of the renaming of a ghost object, the type
+   --  itself may be ghost.
+
+   elsif Nkind (Parent (Par)) = N_Object_Renaming_Declaration
+ and then (Par = Subtype_Mark (Parent (Par))
+ or else Par = Access_Definition (Parent (Par)))
then
   return True;
 




[Ada] Reuse Get_Pragma_Arg to handle pragma argument associations

2022-07-05 Thread Pierre-Marie de Rodat via Gcc-patches
Code cleanup related to looking at pragma Thread_Local_Storage.
Semantics is unaffected.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* exp_ch3.adb (Build_Init_Statements): Reuse Get_Pragma_Arg.
* exp_prag.adb (Arg_N): Likewise.diff --git a/gcc/ada/exp_ch3.adb b/gcc/ada/exp_ch3.adb
--- a/gcc/ada/exp_ch3.adb
+++ b/gcc/ada/exp_ch3.adb
@@ -3319,11 +3319,9 @@ package body Exp_Ch3 is
 --  Pragma case
 
 if Nkind (Ritem) = N_Pragma then
-   Exp := First (Pragma_Argument_Associations (Ritem));
-
-   if Nkind (Exp) = N_Pragma_Argument_Association then
-  Exp := Expression (Exp);
-   end if;
+   Exp :=
+ Get_Pragma_Arg
+   (First (Pragma_Argument_Associations (Ritem)));
 
--  Conversion for Priority expression
 


diff --git a/gcc/ada/exp_prag.adb b/gcc/ada/exp_prag.adb
--- a/gcc/ada/exp_prag.adb
+++ b/gcc/ada/exp_prag.adb
@@ -105,12 +105,10 @@ package body Exp_Prag is
  end if;
   end loop;
 
-  if Present (Arg)
-and then Nkind (Arg) = N_Pragma_Argument_Association
-  then
- return Expression (Arg);
+  if Present (Arg) then
+ return Get_Pragma_Arg (Arg);
   else
- return Arg;
+ return Empty;
   end if;
end Arg_N;
 




[Ada] Remove use of a global name buffer when locating a file

2022-07-05 Thread Pierre-Marie de Rodat via Gcc-patches
Code cleanup; semantics is unaffected.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* osint.adb (Locate_File): Use Name_Find with a parameter and
not with a global buffer.diff --git a/gcc/ada/osint.adb b/gcc/ada/osint.adb
--- a/gcc/ada/osint.adb
+++ b/gcc/ada/osint.adb
@@ -1904,10 +1904,8 @@ package body Osint is
 if Dir_Name'Length = 0 then
Found := N;
 else
-   Name_Len := Full_Name'Length - 1;
-   Name_Buffer (1 .. Name_Len) :=
- Full_Name (1 .. Full_Name'Last - 1);
-   Found := Name_Find;
+   Found :=
+ Name_Find (Full_Name (Full_Name'First .. Full_Name'Last - 1));
 end if;
  end if;
   end;




[Ada] Remove repeated setting of Never_Set_In_Source

2022-07-05 Thread Pierre-Marie de Rodat via Gcc-patches
Formal parameters have their flag Never_Set_In_Source set at the
beginning of Process_Formals routine (regardless of the parameter mode).
There is no need to set it again when Process_Formals calls
Set_Formal_Mode (for parameters of mode IN OUT and OUT).

Code cleanup related to improved detection of uninitialised objects;
behaviour is unaffected.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* sem_ch6.adb (Set_Formal_Mode): Remove unnecessary setting of
Never_Set_In_Source.diff --git a/gcc/ada/sem_ch6.adb b/gcc/ada/sem_ch6.adb
--- a/gcc/ada/sem_ch6.adb
+++ b/gcc/ada/sem_ch6.adb
@@ -13298,10 +13298,9 @@ package body Sem_Ch6 is
 Mutate_Ekind (Formal_Id, E_In_Out_Parameter);
 
  else
-Mutate_Ekind(Formal_Id, E_Out_Parameter);
-Set_Never_Set_In_Source (Formal_Id, True);
-Set_Is_True_Constant(Formal_Id, False);
-Set_Current_Value   (Formal_Id, Empty);
+Mutate_Ekind (Formal_Id, E_Out_Parameter);
+Set_Is_True_Constant (Formal_Id, False);
+Set_Current_Value(Formal_Id, Empty);
  end if;
 
   else




[Ada] Remove kludge for validity checks on Long_Float type

2022-07-05 Thread Pierre-Marie de Rodat via Gcc-patches
This patch reverts a fix for a spurious warning for validity checks on
type Long_Float. This fix was dubious (as it was only affecting
Long_Float and not Float) and apparently is no longer needed.

Cleanup related to improved detection of uninitialised scalar objects.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* sem_attr.adb (Note_Possible_Modification): Revert a
special-case for validity checks on Long_Float type.
* snames.ads-tmpl (Name_Attr_Long_Float): Remove name added
exclusively for the mentioned fix.diff --git a/gcc/ada/sem_attr.adb b/gcc/ada/sem_attr.adb
--- a/gcc/ada/sem_attr.adb
+++ b/gcc/ada/sem_attr.adb
@@ -11145,43 +11145,10 @@ package body Sem_Attr is
  =>
 --  Note possible modification if we have a variable
 
-if Is_Variable (P) then
-   declare
-  PN : constant Node_Id := Parent (N);
-  Nm : Node_Id;
-
-  Note : Boolean := True;
-  --  Skip this for the case of Unrestricted_Access occurring
-  --  in the context of a Valid check, since this otherwise
-  --  leads to a missed warning (the Valid check does not
-  --  really modify!) If this case, Note will be reset to
-  --  False.
-
-  --  Skip it as well if the type is an Access_To_Constant,
-  --  given that no use of the value can modify the prefix.
-
-   begin
-  if Attr_Id = Attribute_Unrestricted_Access
-and then Nkind (PN) = N_Function_Call
-  then
- Nm := Name (PN);
-
- if Nkind (Nm) = N_Expanded_Name
-   and then Chars (Nm) = Name_Valid
-   and then Nkind (Prefix (Nm)) = N_Identifier
-   and then Chars (Prefix (Nm)) = Name_Attr_Long_Float
- then
-Note := False;
- end if;
-
-  elsif Is_Access_Constant (Typ) then
- Note := False;
-  end if;
-
-  if Note then
- Note_Possible_Modification (P, Sure => False);
-  end if;
-   end;
+if Is_Variable (P)
+  and then not Is_Access_Constant (Typ)
+then
+   Note_Possible_Modification (P, Sure => False);
 end if;
 
 --  Case where prefix is an entity name


diff --git a/gcc/ada/snames.ads-tmpl b/gcc/ada/snames.ads-tmpl
--- a/gcc/ada/snames.ads-tmpl
+++ b/gcc/ada/snames.ads-tmpl
@@ -776,7 +776,6 @@ package Snames is
Name_Allow  : constant Name_Id := N + $;
Name_Amount : constant Name_Id := N + $;
Name_As_Is  : constant Name_Id := N + $;
-   Name_Attr_Long_Float: constant Name_Id := N + $;
Name_Assertion  : constant Name_Id := N + $;
Name_Assertions : constant Name_Id := N + $;
Name_Attribute_Name : constant Name_Id := N + $;




[Ada] Couple of small cleanups for Cloned_Subtype

2022-07-05 Thread Pierre-Marie de Rodat via Gcc-patches
No functional changes.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* exp_util.adb (Make_Subtype_From_Expr): Do not set field to Empty.
* sem_util.adb (Visit_Itype): Remove ??? comment.diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb
--- a/gcc/ada/exp_util.adb
+++ b/gcc/ada/exp_util.adb
@@ -10213,8 +10213,8 @@ package body Exp_Util is
 
   elsif Is_Class_Wide_Type (Unc_Typ) then
  declare
-CW_Subtype : Entity_Id;
-EQ_Typ : Entity_Id := Empty;
+CW_Subtype : constant Entity_Id :=
+   New_Class_Wide_Subtype (Unc_Typ, E);
 
  begin
 --  A class-wide equivalent type is not needed on VM targets
@@ -10237,11 +10237,10 @@ package body Exp_Util is
   Set_Etype (Unc_Typ, Base_Type (Full_View (Etype (Unc_Typ;
end if;
 
-   EQ_Typ := Make_CW_Equivalent_Type (Unc_Typ, E);
+   Set_Equivalent_Type
+ (CW_Subtype, Make_CW_Equivalent_Type (Unc_Typ, E));
 end if;
 
-CW_Subtype := New_Class_Wide_Subtype (Unc_Typ, E);
-Set_Equivalent_Type (CW_Subtype, EQ_Typ);
 Set_Cloned_Subtype (CW_Subtype, Base_Type (Unc_Typ));
 
 return New_Occurrence_Of (CW_Subtype, Loc);


diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb
--- a/gcc/ada/sem_util.adb
+++ b/gcc/ada/sem_util.adb
@@ -25146,8 +25146,7 @@ package body Sem_Util is
  end if;
 
  --  If a record subtype is simply copied, the entity list will be
- --  shared. Thus cloned_Subtype must be set to indicate the sharing.
- --  ??? What does this do?
+ --  shared, so Cloned_Subtype must be set to indicate this.
 
  if Ekind (Itype) in E_Class_Wide_Subtype | E_Record_Subtype then
 Set_Cloned_Subtype (New_Itype, Itype);




[Ada] Warn about obsolete uses of renamed Ada 83 packages

2022-07-05 Thread Pierre-Marie de Rodat via Gcc-patches
Ada 83 packages like Unchecked_Conversion or Text_IO are obsolete since
Ada 95. GNAT now warns about their uses when warnings on obsolescent
featured (Annex J) is active.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* doc/gnat_ugn/building_executable_programs_with_gnat.rst
(Warning Message Control): Update description of switch -gnatwj.
* gnat_ugn.texi: Regenerate.
* sem_ch10.adb (Analyze_With_Clause): Warn on WITH clauses for
obsolete renamed units; in Ada 83 mode do not consider
predefined renamings to be obsolete.

gcc/testsuite/

* gnat.dg/renaming1.adb: Update WITH clause.
* gnat.dg/renaming1.ads: Likewise.
* gnat.dg/warn29.adb: Likewise.diff --git a/gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst b/gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst
--- a/gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst
+++ b/gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst
@@ -3277,8 +3277,7 @@ of the pragma in the :title:`GNAT_Reference_manual`).
   If this warning option is activated, then warnings are generated for
   calls to subprograms marked with ``pragma Obsolescent`` and
   for use of features in Annex J of the Ada Reference Manual. In the
-  case of Annex J, not all features are flagged. In particular use
-  of the renamed packages (like ``Text_IO``) and use of package
+  case of Annex J, not all features are flagged. In particular, uses of package
   ``ASCII`` are not flagged, since these are very common and
   would generate many annoying positive warnings. The default is that
   such warnings are not generated.


diff --git a/gcc/ada/gnat_ugn.texi b/gcc/ada/gnat_ugn.texi
--- a/gcc/ada/gnat_ugn.texi
+++ b/gcc/ada/gnat_ugn.texi
@@ -11383,8 +11383,7 @@ This switch disables warnings on overlapping actuals in a call.
 If this warning option is activated, then warnings are generated for
 calls to subprograms marked with @code{pragma Obsolescent} and
 for use of features in Annex J of the Ada Reference Manual. In the
-case of Annex J, not all features are flagged. In particular use
-of the renamed packages (like @code{Text_IO}) and use of package
+case of Annex J, not all features are flagged. In particular, uses of package
 @code{ASCII} are not flagged, since these are very common and
 would generate many annoying positive warnings. The default is that
 such warnings are not generated.


diff --git a/gcc/ada/sem_ch10.adb b/gcc/ada/sem_ch10.adb
--- a/gcc/ada/sem_ch10.adb
+++ b/gcc/ada/sem_ch10.adb
@@ -2597,11 +2597,19 @@ package body Sem_Ch10 is
   --  Note: this is not quite right if the user defines one of these units
   --  himself, but that's a marginal case, and fixing it is hard ???
 
-  if Restriction_Check_Required (No_Obsolescent_Features) then
- if In_Predefined_Renaming (U) then
+  if Ada_Version >= Ada_95
+and then In_Predefined_Renaming (U)
+  then
+ if Restriction_Check_Required (No_Obsolescent_Features) then
 Check_Restriction (No_Obsolescent_Features, N);
 Restriction_Violation := True;
  end if;
+
+ if Warn_On_Obsolescent_Feature then
+Error_Msg_N
+  ("renamed predefined unit is an obsolescent feature "
+   & "(RM J.1)?j?", N);
+ end if;
   end if;
 
   --  Check No_Implementation_Units violation


diff --git a/gcc/testsuite/gnat.dg/renaming1.adb b/gcc/testsuite/gnat.dg/renaming1.adb
--- a/gcc/testsuite/gnat.dg/renaming1.adb
+++ b/gcc/testsuite/gnat.dg/renaming1.adb
@@ -1,12 +1,12 @@
 -- { dg-do compile}
 -- { dg-options "-gnatwa" }
 
-with Text_IO;
-use Text_IO;
+with Ada.Text_IO;
+use Ada.Text_IO;
 package body renaming1 is
-   procedure Fo (A : Text_IO.File_Access) is
+   procedure Fo (A : Ada.Text_IO.File_Access) is
begin
-  if A = Text_IO.Standard_Output then
+  if A = Ada.Text_IO.Standard_Output then
  null;
   end if;
end Fo;


diff --git a/gcc/testsuite/gnat.dg/renaming1.ads b/gcc/testsuite/gnat.dg/renaming1.ads
--- a/gcc/testsuite/gnat.dg/renaming1.ads
+++ b/gcc/testsuite/gnat.dg/renaming1.ads
@@ -1,4 +1,4 @@
-with Text_IO;
+with Ada.Text_IO;
 package renaming1 is
-   procedure Fo (A : Text_IO.File_Access);
+   procedure Fo (A : Ada.Text_IO.File_Access);
 end;


diff --git a/gcc/testsuite/gnat.dg/warn29.adb b/gcc/testsuite/gnat.dg/warn29.adb
--- a/gcc/testsuite/gnat.dg/warn29.adb
+++ b/gcc/testsuite/gnat.dg/warn29.adb
@@ -1,7 +1,7 @@
 --  { dg-do compile }
 --  { dg-options "-gnatwa" }
 
-with Text_IO; use Text_IO;
+with Ada.Text_IO; use Ada.Text_IO;
 
 package body Warn29 is
procedure P (X : T; Y : Integer) is




Re: [PATCH] Mips: Enable asynchronous unwind tables with both ASAN and TSAN

2022-07-05 Thread Xi Ruoyao via Gcc-patches
On Tue, 2022-07-05 at 12:51 +0800, Xi Ruoyao via Gcc-patches wrote:

> I agree it's fine, but the problem is TSAN is currently "unsupported"
> within GCC (i. e. when you build gcc libtsan is not built).  So it
> does
> not make any benefit to commit this change before making TSAN
> supported
> on GCC side.
> 
> Dimitrije told me TSAN should be supported on 64-bit MIPS, but I can't
> make it work fine with GCC.  I'll need some time to debug...

Hi Fangrui,

On my system dlpi_tls_modid for libtsan.so.2 is 2, instead of 1. 
GetStaticTlsBoundary seems assuming the dlpi_tls_modid for libtsan.so to
be 1, and returning wrong values if the assumption is broken.

Is it unsafe to make such an assumption?  Or, am I being haunted by a
glibc bug?
-- 
Xi Ruoyao 
School of Aerospace Science and Technology, Xidian University


[PATCH] tree-optimization/106196 - properly update virtual SSA for vector stores

2022-07-05 Thread Richard Biener via Gcc-patches
The following properly handles aggregate returns of the const marked
STORE_LANES internal function to update virtual SSA form on-the-fly
rather than relying on a costly virtual SSA rewrite.

Bootstrap and regtest running on x86_64-unknown-linux-gnu.

PR tree-optimization/106196
* tree-vect-stmts.cc (vect_finish_stmt_generation): Properly
handle aggregate returns of calls for VDEF updates.

* gcc.dg/torture/pr106196.c: New testcase.
---
 gcc/testsuite/gcc.dg/torture/pr106196.c | 14 ++
 gcc/tree-vect-stmts.cc  |  6 --
 2 files changed, 18 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr106196.c

diff --git a/gcc/testsuite/gcc.dg/torture/pr106196.c 
b/gcc/testsuite/gcc.dg/torture/pr106196.c
new file mode 100644
index 000..56723de42c2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr106196.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-ftree-vectorize -fno-vect-cost-model" } */
+
+extern char a[];
+char *b;
+void e() {
+  char *d;
+  int c;
+  d = a;
+  for (; c; c++) {
+d[2] = d[1] = d[0] = b[c];
+d += 3;
+  }
+}
diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc
index 72107afc883..3db6620dd42 100644
--- a/gcc/tree-vect-stmts.cc
+++ b/gcc/tree-vect-stmts.cc
@@ -1638,8 +1638,10 @@ vect_finish_stmt_generation (vec_info *vinfo,
  && ((is_gimple_assign (vec_stmt)
   && !is_gimple_reg (gimple_assign_lhs (vec_stmt)))
  || (is_gimple_call (vec_stmt)
- && !(gimple_call_flags (vec_stmt)
-  & (ECF_CONST|ECF_PURE|ECF_NOVOPS)
+ && (!(gimple_call_flags (vec_stmt)
+   & (ECF_CONST|ECF_PURE|ECF_NOVOPS))
+ || (gimple_call_lhs (vec_stmt)
+ && !is_gimple_reg (gimple_call_lhs 
(vec_stmt)))
{
  tree new_vdef = copy_ssa_name (vuse, vec_stmt);
  gimple_set_vdef (vec_stmt, new_vdef);
-- 
2.35.3


Re: [PATCH] aarch64: testsuite: symbol-range compile only

2022-07-05 Thread Alexandre Oliva via Gcc-patches
On Jun 30, 2022, Hans-Peter Nilsson  wrote:

> On Thu, 23 Jun 2022, Alexandre Oliva via Gcc-patches wrote:
>> +proc check_effective_target_two_plus_gigs { } {
>> +return [check_no_compiler_messages two_plus_gigs executable {
>> +int dummy[0x8000];

> Don't you mean "char" as in "char dummy[0x8000]"?

Doh.  Of course!  Thanks for catching this.

Here's what I'm installing, regstrapped on x86_64-linux-gnu, also tested
on aarch64-rtems6.0 and ppc64-vx7r2.


testsuite: fix array type in two_plus_gigs test

The array element type for the two_plus_gigs test was mistakely put in
as int rather than char.


for  gcc/testsuite/ChangeLog

* target-supports.exp (check_effective_target_two_plus_gigs):
Fix array element type.  Reported by Hans-Peter Nilsson.

---
 gcc/testsuite/lib/target-supports.exp |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/lib/target-supports.exp 
b/gcc/testsuite/lib/target-supports.exp
index 48c5dda6a1278..4ed7b25b9a4de 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -2909,7 +2909,7 @@ proc check_effective_target_le { } {
 
 proc check_effective_target_two_plus_gigs { } {
 return [check_no_compiler_messages two_plus_gigs executable {
-   int dummy[0x8000];
+   char dummy[0x8000];
int main () { return 0; }
 }]
 }


-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


Re: [PATCH] libstdc++: testsuite: avoid predictable mkstemp

2022-07-05 Thread Alexandre Oliva via Gcc-patches
On Jun 27, 2022, Alexandre Oliva  wrote:

> On Jun 23, 2022, Jonathan Wakely  wrote:
>> The attached makes this a bit more efficient, and makes more of the
>> code common to the mkstemp and non-mkstmp branches. I'll wait to hear
>> back from you before pushing it (since it has Joel's name on the
>> patch).

> Thanks, I've given it a spin, both trunk and gcc-11, and I confirm it
> works for us.

The bad news is that it broke on some other systems I didn't test back
then.  It turns out the type cast for the ::getpid result was not just
because it was passed to printf before :-/


libstdc++: testsuite: cast getpid result

On vxworks, in kernel mode, getpid's return type is a pointer type, so
std::to_string on it fails overload resolution.  Restore the type cast
from the original patch that suggested adding the pid.

Regstrapped on x86_64-linux-gnu, also tested on aarch64-rtems6.0 and
ppc64-vx7r2.  I'm going ahead and checking this in as obvious.  Please
let me know if you'd prefer this to be fixed in a different way.


for  libstdc++/ChangeLog

* testsuite/util/testsuite_fs.h (nonexistent_path): Convert
the getpid result to an integral type.
---
 libstdc++-v3/testsuite/util/testsuite_fs.h |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libstdc++-v3/testsuite/util/testsuite_fs.h 
b/libstdc++-v3/testsuite/util/testsuite_fs.h
index 908fcdbcaeed1..25f8f734dc792 100644
--- a/libstdc++-v3/testsuite/util/testsuite_fs.h
+++ b/libstdc++-v3/testsuite/util/testsuite_fs.h
@@ -163,7 +163,7 @@ namespace __gnu_test
   file.resize(64);
 // The combination of random counter and PID should be unique for a given
 // run of the testsuite.
-file += std::to_string(::getpid());
+file += std::to_string((unsigned long) ::getpid());
 p = std::move(file);
 if (test_fs::exists(p))
   throw test_fs::filesystem_error("Failed to generate unique pathname", p,


-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


Re: [PATCH] Mips: Enable asynchronous unwind tables with both ASAN and TSAN

2022-07-05 Thread Xi Ruoyao via Gcc-patches
On Mon, 2022-07-04 at 21:21 -0700, Fangrui Song wrote:

> > > 
> > > > FAIL: c-c++-common/tsan/tls_race.c   -O0  output pattern test
> > > > Output was:
> > > > ThreadSanitizer: CHECK failed: tsan_platform_linux.cpp:452
> > > > "((thr_end)) <= ((tls_addr + tls_size))" (0xffec35f8c0,
> > > > 0xffec35f784) (tid=748216)
> > > >     #0 __tsan::CheckUnwind()
> > > > ../../../../gcc/libsanitizer/tsan/tsan_rtl.cpp:627
> > > > (libtsan.so.2+0xa30ec)
> > > >     #1 __sanitizer::CheckFailed(char const*, int, char const*,
> > > > unsigned long long, unsigned long long)
> > > > ../../../../gcc/libsanitizer/sanitizer_common/sanitizer_termination.
> > > > cpp:86 (libtsan.so.2+0xeb8cc)
> > > >     #2 __tsan::ImitateTlsWrite(__tsan::ThreadState*, unsigned long,
> > > > unsigned long)
> > > > ../../../../gcc/libsanitizer/tsan/tsan_platform_linux.cpp:452
> > > > (libtsan.so.2+0xa0cac)
> > > >     #3 __tsan::ThreadStart(__tsan::ThreadState*, unsigned int,
> > > > unsigned long long, __sanitizer::ThreadType)
> > > > ../../../../gcc/libsanitizer/tsan/tsan_rtl_thread.cpp:197
> > > > (libtsan.so.2+0xc0e88)
> > > >     #4 __tsan_thread_start_func
> > > > ../../../../gcc/libsanitizer/tsan/tsan_interceptors_posix.cpp:1009
> > > > (libtsan.so.2+0x3e5dc)
> > > >     #5 start_thread /sources/glibc-2.35/nptl/pthread_create.c:442
> > > > (libc.so.6+0xc75f4)
> > > > 
> > > > I've tried to diagnose the root cause but failed.
> > > 
> > > Hi Xi, thanks for looking into this. I've tried running the testsuite
> > > on a cross-toolchain (as I do not currently have access to a physical
> > > machine)
> > > for a MIPS64R6 and the test passes successfully. Could you please
> > > verify that the test fails solely based on this change?

I've got a clue about why this happens.  See
https://reviews.llvm.org/D129112.

It depends on how the dynamic linker arranges TLS blocks so different
version of Glibc may produce different results.
-- 
Xi Ruoyao 
School of Aerospace Science and Technology, Xidian University


Re: [PATCH] libstdc++: testsuite: avoid predictable mkstemp

2022-07-05 Thread Jonathan Wakely via Gcc-patches
On Tue, 5 Jul 2022 at 10:10, Alexandre Oliva via Libstdc++
 wrote:
>
> On Jun 27, 2022, Alexandre Oliva  wrote:
>
> > On Jun 23, 2022, Jonathan Wakely  wrote:
> >> The attached makes this a bit more efficient, and makes more of the
> >> code common to the mkstemp and non-mkstmp branches. I'll wait to hear
> >> back from you before pushing it (since it has Joel's name on the
> >> patch).
>
> > Thanks, I've given it a spin, both trunk and gcc-11, and I confirm it
> > works for us.
>
> The bad news is that it broke on some other systems I didn't test back
> then.  It turns out the type cast for the ::getpid result was not just
> because it was passed to printf before :-/

Ah, whoops.

I did check that POSIX requires pid_t to be a signed integer type, but
that doesn't mean it's always true for all GCC targets.

>
>
> libstdc++: testsuite: cast getpid result
>
> On vxworks, in kernel mode, getpid's return type is a pointer type, so
> std::to_string on it fails overload resolution.  Restore the type cast
> from the original patch that suggested adding the pid.
>
> Regstrapped on x86_64-linux-gnu, also tested on aarch64-rtems6.0 and
> ppc64-vx7r2.  I'm going ahead and checking this in as obvious.  Please
> let me know if you'd prefer this to be fixed in a different way.

The cast itself is fine, but I'd like a comment like "N.B. pid_t is a
pointer on vxworks" so I don't "simplify" it again.

Thanks.



[10, committed] d: Fix error: aggregate value used where floating point was expected (PR106139)

2022-07-05 Thread Iain Buclaw via Gcc-patches
Hi,

This is the GCC-10 backport of the fix for PR106139 posted last week.

Bootstrapped and regression tested on x86_64-linux-gnu/-m32/-mx32, and
committed to releases/gcc-10.

Regards,
Iain.

---
PR d/106139

gcc/d/ChangeLog:

* d-convert.cc (convert_expr): Handle casting from array to vector.
(convert_for_rvalue): Rewrite vector to array casts of the same
element type into a constructor.
(convert_for_assignment): Return calling convert_for_rvalue.
* dmd/expressionsem.c (ExpressionSemanticVisitor::visit): Run semantic
on vector expression after lowering.
* expr.cc (ExprVisitor::visit (VectorExp *)): Handle generating a
vector expression from a static array.

gcc/testsuite/ChangeLog:

* gdc.dg/pr106139a.d: New test.
* gdc.dg/pr106139b.d: New test.
* gdc.dg/pr106139c.d: New test.
* gdc.dg/pr106139d.d: New test.
* gdc.test/fail_compilation/ice20264.d: New test.

(cherry picked from commit 488759b7ea16972c4dfbb62926cd71996b1f77a7)
---
 gcc/d/d-convert.cc| 44 ++-
 gcc/d/dmd/expressionsem.c |  1 +
 gcc/d/expr.cc | 17 ---
 gcc/testsuite/gdc.dg/pr106139a.d  | 36 +++
 gcc/testsuite/gdc.dg/pr106139b.d  | 36 +++
 gcc/testsuite/gdc.dg/pr106139c.d  | 27 
 gcc/testsuite/gdc.dg/pr106139d.d  | 27 
 .../gdc.test/fail_compilation/ice20264.d  | 13 ++
 8 files changed, 195 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/gdc.dg/pr106139a.d
 create mode 100644 gcc/testsuite/gdc.dg/pr106139b.d
 create mode 100644 gcc/testsuite/gdc.dg/pr106139c.d
 create mode 100644 gcc/testsuite/gdc.dg/pr106139d.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/ice20264.d

diff --git a/gcc/d/d-convert.cc b/gcc/d/d-convert.cc
index 87062513c33..2cfc2c8cc19 100644
--- a/gcc/d/d-convert.cc
+++ b/gcc/d/d-convert.cc
@@ -502,6 +502,15 @@ convert_expr (tree exp, Type *etype, Type *totype)
  gcc_assert (totype->size () == etype->size ());
  result = build_vconvert (build_ctype (totype), exp);
}
+  else if (tbtype->ty == Tvector && tbtype->size () == ebtype->size ())
+   {
+ /* Allow casting from array to vector as if its an unaligned load.  */
+ tree type = build_ctype (totype);
+ tree unaligned_type = build_variant_type_copy (type);
+ SET_TYPE_ALIGN (unaligned_type, 1 * BITS_PER_UNIT);
+ TYPE_USER_ALIGN (unaligned_type) = 1;
+ result = convert (type, build_vconvert (unaligned_type, exp));
+   }
   else
{
  error ("cannot cast expression of type %qs to type %qs",
@@ -634,6 +643,39 @@ convert_for_rvalue (tree expr, Type *etype, Type *totype)
   break;
 }
 
+  if (tbtype->ty == Tsarray
+  && ebtype->ty == Tsarray
+  && tbtype->nextOf ()->ty == ebtype->nextOf ()->ty
+  && INDIRECT_REF_P (expr)
+  && CONVERT_EXPR_CODE_P (TREE_CODE (TREE_OPERAND (expr, 0)))
+  && TREE_CODE (TREE_OPERAND (TREE_OPERAND (expr, 0), 0)) == ADDR_EXPR)
+{
+  /* If expression is a vector that was casted to an array either by
+explicit type cast or by taking the vector's `.array' value, strip the
+reinterpret cast and build a constructor instead.  */
+  tree ptr = TREE_OPERAND (TREE_OPERAND (expr, 0), 0);
+
+  if (VECTOR_TYPE_P (TREE_TYPE (TREE_TYPE (ptr
+   {
+ /* Rewrite: `*(Array *)&vector'
+   into: `{ vector[0], vector[1], ... }'  */
+ tree array = d_save_expr (TREE_OPERAND (ptr, 0));
+ array = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (expr), array);
+
+ uinteger_t dim = ((TypeSArray *)tbtype)->dim->toUInteger ();
+ vec  *elms = NULL;
+ for (uinteger_t i = 0; i < dim; i++)
+   {
+ tree index = size_int (i);
+ tree value = build4 (ARRAY_REF, TREE_TYPE (TREE_TYPE (array)),
+  array, index, NULL_TREE, NULL_TREE);
+ CONSTRUCTOR_APPEND_ELT (elms, index, value);
+   }
+
+ return build_constructor (build_ctype (totype), elms);
+   }
+}
+
   return result ? result : convert_expr (expr, etype, totype);
 }
 
@@ -694,7 +736,7 @@ convert_for_assignment (tree expr, Type *etype, Type 
*totype)
   return expr;
 }
 
-  return convert_expr (expr, etype, totype);
+  return convert_for_rvalue (expr, etype, totype);
 }
 
 /* Return a TREE representation of EXPR converted to represent
diff --git a/gcc/d/dmd/expressionsem.c b/gcc/d/dmd/expressionsem.c
index 5096754e55f..3c199bf1b57 100644
--- a/gcc/d/dmd/expressionsem.c
+++ b/gcc/d/dmd/expressionsem.c
@@ -4309,6 +4309,7 @@ public:
 if (tob->ty == Tvector && t1b->ty != Tvector)
 {
 result = new VectorExp(exp->loc, exp->e1, exp->to);
+result = 

[11, committed] d: Fix error: aggregate value used where floating point was expected (PR106139)

2022-07-05 Thread Iain Buclaw via Gcc-patches
Hi,

This is the GCC-11 backport of the fix for PR106139 posted last week.

Bootstrapped and regression tested on x86_64-linux-gnu/-m32/-mx32, and
committed to releases/gcc-11.

Regards,
Iain.

---
PR d/106139

gcc/d/ChangeLog:

* d-convert.cc (convert_expr): Handle casting from array to vector.
(convert_for_rvalue): Rewrite vector to array casts of the same
element type into a constructor.
(convert_for_assignment): Return calling convert_for_rvalue.
* dmd/expressionsem.c (ExpressionSemanticVisitor::visit): Run semantic
on vector expression after lowering.
* expr.cc (ExprVisitor::visit (VectorExp *)): Handle generating a
vector expression from a static array.
* toir.cc (IRVisitor::visit (ReturnStatement *)): Call
convert_for_rvalue on return value.

gcc/testsuite/ChangeLog:

* gdc.dg/pr106139a.d: New test.
* gdc.dg/pr106139b.d: New test.
* gdc.dg/pr106139c.d: New test.
* gdc.dg/pr106139d.d: New test.
* gdc.test/fail_compilation/ice20264.d: New test.

(cherry picked from commit 329bef49da30158d30fed1106002bb71674776bd)
---
 gcc/d/d-convert.cc| 44 ++-
 gcc/d/dmd/expressionsem.c |  1 +
 gcc/d/expr.cc | 10 -
 gcc/d/toir.cc |  1 +
 gcc/testsuite/gdc.dg/pr106139a.d  | 36 +++
 gcc/testsuite/gdc.dg/pr106139b.d  | 36 +++
 gcc/testsuite/gdc.dg/pr106139c.d  | 27 
 gcc/testsuite/gdc.dg/pr106139d.d  | 27 
 .../gdc.test/fail_compilation/ice20264.d  | 13 ++
 9 files changed, 192 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gdc.dg/pr106139a.d
 create mode 100644 gcc/testsuite/gdc.dg/pr106139b.d
 create mode 100644 gcc/testsuite/gdc.dg/pr106139c.d
 create mode 100644 gcc/testsuite/gdc.dg/pr106139d.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/ice20264.d

diff --git a/gcc/d/d-convert.cc b/gcc/d/d-convert.cc
index d43485dca77..cd6551e64f3 100644
--- a/gcc/d/d-convert.cc
+++ b/gcc/d/d-convert.cc
@@ -502,6 +502,15 @@ convert_expr (tree exp, Type *etype, Type *totype)
  gcc_assert (totype->size () == etype->size ());
  result = build_vconvert (build_ctype (totype), exp);
}
+  else if (tbtype->ty == Tvector && tbtype->size () == ebtype->size ())
+   {
+ /* Allow casting from array to vector as if its an unaligned load.  */
+ tree type = build_ctype (totype);
+ tree unaligned_type = build_variant_type_copy (type);
+ SET_TYPE_ALIGN (unaligned_type, 1 * BITS_PER_UNIT);
+ TYPE_USER_ALIGN (unaligned_type) = 1;
+ result = convert (type, build_vconvert (unaligned_type, exp));
+   }
   else
{
  error ("cannot cast expression of type %qs to type %qs",
@@ -636,6 +645,39 @@ convert_for_rvalue (tree expr, Type *etype, Type *totype)
   break;
 }
 
+  if (tbtype->ty == Tsarray
+  && ebtype->ty == Tsarray
+  && tbtype->nextOf ()->ty == ebtype->nextOf ()->ty
+  && INDIRECT_REF_P (expr)
+  && CONVERT_EXPR_CODE_P (TREE_CODE (TREE_OPERAND (expr, 0)))
+  && TREE_CODE (TREE_OPERAND (TREE_OPERAND (expr, 0), 0)) == ADDR_EXPR)
+{
+  /* If expression is a vector that was casted to an array either by
+explicit type cast or by taking the vector's `.array' value, strip the
+reinterpret cast and build a constructor instead.  */
+  tree ptr = TREE_OPERAND (TREE_OPERAND (expr, 0), 0);
+
+  if (VECTOR_TYPE_P (TREE_TYPE (TREE_TYPE (ptr
+   {
+ /* Rewrite: `*(Array *)&vector'
+   into: `{ vector[0], vector[1], ... }'  */
+ tree array = d_save_expr (TREE_OPERAND (ptr, 0));
+ array = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (expr), array);
+
+ uinteger_t dim = tbtype->isTypeSArray ()->dim->toUInteger ();
+ vec  *elms = NULL;
+ for (uinteger_t i = 0; i < dim; i++)
+   {
+ tree index = size_int (i);
+ tree value = build4 (ARRAY_REF, TREE_TYPE (TREE_TYPE (array)),
+  array, index, NULL_TREE, NULL_TREE);
+ CONSTRUCTOR_APPEND_ELT (elms, index, value);
+   }
+
+ return build_constructor (build_ctype (totype), elms);
+   }
+}
+
   return result ? result : convert_expr (expr, etype, totype);
 }
 
@@ -696,7 +738,7 @@ convert_for_assignment (tree expr, Type *etype, Type 
*totype)
   return expr;
 }
 
-  return convert_expr (expr, etype, totype);
+  return convert_for_rvalue (expr, etype, totype);
 }
 
 /* Return a TREE representation of EXPR converted to represent
diff --git a/gcc/d/dmd/expressionsem.c b/gcc/d/dmd/expressionsem.c
index 5ae5fe6a717..fe90039d6f0 100644
--- a/gcc/d/dmd/expressionsem.c
+++ b/gcc/d/dmd/expressionsem.c
@@ -6330,6 +6330,7 @@ p

Re: [PATCH 4/12] arm: Add testsuite library support for PACBTI target

2022-07-05 Thread Richard Earnshaw via Gcc-patches




On 04/07/2022 15:47, Andrea Corallo wrote:

Richard Earnshaw  writes:


On 01/07/2022 14:03, Richard Earnshaw via Gcc-patches wrote:

On 28/04/2022 10:40, Andrea Corallo via Gcc-patches wrote:

Add targeting-checking entities for PACBTI in testsuite
framework.

Pre-approved with the requested changes here
>.


gcc/testsuite/ChangeLog:

* testsuite/lib/target-supports.exp:
(check_effective_target_arm_pacbti_hw): New.
* doc/sourcebuild.texi: Document arm_pacbti_hw.

Co-Authored-By: Tejas Belagod  


+proc check_effective_target_arm_pacbti_hw {} {
+    return [check_runtime arm_pacbti_hw_available {
+    __attribute__ ((naked)) int
+    main (void)
+    {
+  asm ("pac r12, lr, sp");
So the armv8-m Arm ARM says that this instruction is in the NOP
space and that it is undefined if we aren't armv8-m.main or higher.
+  asm ("mov r0, #0");
+  asm ("autg r12, lr, sp");
This isn't in the nop space, but the Arm ARM says it is
unpredictable if the extension isn't present.  Unfortunately, that
means this isn't a particularly reliable way of detecting that the
PACBTI feature is present.
However, I can't think off hand of more reliable way of testing this
since reading the feature register ID_ISAR5 is not possible when in
unprivileged mode.
So I think we'll have to live with this.
+  asm ("bx lr");
+    }
+    } ""]
OK.



Or perhaps not. The test does not try to add the right options to
enable PAC/BTI if those aren't in the default selection for the
current testsuite run.

Perhaps we also need some additional tests to work out what
architecture options to add (if any) to ensure the test will at least
assemble.


Hi Richard,
thanks for reviewing.

Wouldn't be sufficient for that to have this test compiled with
-march=armv8-m.main?


Take a look at how, for example, check_effective_target_arm_mve_hw (and 
add_options_for_v8_1_m_mve_fp) is implemented.


R.



BR

   Andrea


[PATCH] tree-optimization/106186 - propagate out virtual LC PHI nodes properly

2022-07-05 Thread Richard Biener via Gcc-patches
The code to remove LC PHI nodes in clean_up_loop_closed_phi does not handle
virtual operands because may_propagate_copy generally returns false
for them.  The following copies the merge_blocks variant for
dealing with them.

This fixes a missed jump threading in gcc.dg/auto-init-uninit-4.c
which manifests in bogus uninit diagnostics.

Bootstrap and regtest pending on x86_64-unknown-linux-gnu.

PR tree-optimization/106186
* tree-ssa-propagate.cc (clean_up_loop_closed_phi):
Properly handle virtual PHI nodes.
---
 gcc/tree-ssa-propagate.cc | 16 +++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/gcc/tree-ssa-propagate.cc b/gcc/tree-ssa-propagate.cc
index 163b24f0e69..9dc4bfd85bf 100644
--- a/gcc/tree-ssa-propagate.cc
+++ b/gcc/tree-ssa-propagate.cc
@@ -1272,7 +1272,21 @@ clean_up_loop_closed_phi (function *fun)
  rhs = gimple_phi_arg_def (phi, 0);
  lhs = gimple_phi_result (phi);
 
- if (rhs && may_propagate_copy (lhs, rhs))
+ if (virtual_operand_p (rhs))
+   {
+ imm_use_iterator iter;
+ use_operand_p use_p;
+ gimple *stmt;
+
+ FOR_EACH_IMM_USE_STMT (stmt, iter, lhs)
+   FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
+ SET_USE (use_p, rhs);
+
+ if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
+   SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs) = 1;
+ remove_phi_node (&gsi, true);
+   }
+ else if (may_propagate_copy (lhs, rhs))
{
  /* Dump details.  */
  if (dump_file && (dump_flags & TDF_DETAILS))
-- 
2.35.3


Re: [PATCH] Maintain LC SSA when doing SVE vectorization

2022-07-05 Thread Richard Sandiford via Gcc-patches
Richard Biener  writes:
> The final loop IV use after the loop has that not in LC SSA
> (and inserts not simplified _2 = _3 - 0 stmts).  In particular
> since it splits the exit edge when there's a virtual PHI in the
> destination it breaks virtual LC SSA form (but likely also
> non-virtual).
>
> The following properly inserts LC PHIs instead.
>
> Bootstrap & regtest pending on x86_64-unknown-linux-gnu.
>
> OK if that succeeds?

LGTM, thanks.

Richard

>
> Thanks,
> Richard.
>
> 2022-07-04  Richard Biener  
>
>   * tree-vect-loop-manip.cc (vect_set_loop_condition_normal):
>   Maintain LC SSA.
> ---
>  gcc/tree-vect-loop-manip.cc | 19 ---
>  1 file changed, 16 insertions(+), 3 deletions(-)
>
> diff --git a/gcc/tree-vect-loop-manip.cc b/gcc/tree-vect-loop-manip.cc
> index 895957472c9..eba71c50428 100644
> --- a/gcc/tree-vect-loop-manip.cc
> +++ b/gcc/tree-vect-loop-manip.cc
> @@ -920,9 +920,22 @@ vect_set_loop_condition_normal (class loop *loop, tree 
> niters, tree step,
>  
>if (final_iv)
>  {
> -  gassign *assign = gimple_build_assign (final_iv, MINUS_EXPR,
> -  indx_after_incr, init);
> -  gsi_insert_on_edge_immediate (single_exit (loop), assign);
> +  gassign *assign;
> +  edge exit = single_exit (loop);
> +  gcc_assert (single_pred_p (exit->dest));
> +  tree phi_dest
> + = integer_zerop (init) ? final_iv : copy_ssa_name (indx_after_incr);
> +  /* Make sure to maintain LC SSA form here and elide the subtraction
> +  if the value is zero.  */
> +  gphi *phi = create_phi_node (phi_dest, exit->dest);
> +  add_phi_arg (phi, indx_after_incr, exit, UNKNOWN_LOCATION);
> +  if (!integer_zerop (init))
> + {
> +   assign = gimple_build_assign (final_iv, MINUS_EXPR,
> + phi_dest, init);
> +   gimple_stmt_iterator gsi = gsi_after_labels (exit->dest);
> +   gsi_insert_before (&gsi, assign, GSI_SAME_STMT);
> + }
>  }
>  
>return cond_stmt;


Re: [PATCH][wwwdocs] gcc-12/changes.html: document LoongArch -m{no-,}check-zero-division default change for 12.2

2022-07-05 Thread Gerald Pfeifer
On Mon, 4 Jul 2022, Xi Ruoyao wrote:
> Document a behavior change in r12-8546.  Ok for wwwdocs?

Thanks also for including the GCC 12.2 bug query as part of this. :)

Gerald


[PATCH] Remove dead loop-based LC SSA rewrite

2022-07-05 Thread Richard Biener via Gcc-patches
The following removes the now unused per-loop path in LC SSA rewrite.

Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed.

* tree-ssa-loop-manip.cc (find_uses_to_rename_def): Remove.
(find_uses_to_rename_in_loop): Likewise.
(rewrite_into_loop_closed_ssa_1): Remove loop parameter and
uses.
(rewrite_into_loop_closed_ssa): Adjust.
---
 gcc/tree-ssa-loop-manip.cc | 109 ++---
 1 file changed, 4 insertions(+), 105 deletions(-)

diff --git a/gcc/tree-ssa-loop-manip.cc b/gcc/tree-ssa-loop-manip.cc
index 623d03b9d86..9f3b62652ea 100644
--- a/gcc/tree-ssa-loop-manip.cc
+++ b/gcc/tree-ssa-loop-manip.cc
@@ -498,94 +498,6 @@ find_uses_to_rename (bitmap changed_bbs, bitmap 
*use_blocks, bitmap need_phis,
   find_uses_to_rename_bb (bb, use_blocks, need_phis, use_flags);
 }
 
-/* Mark uses of DEF that are used outside of the loop they are defined in for
-   rewrite.  Record the set of blocks in which the ssa names are used to
-   USE_BLOCKS.  Record the SSA names that will need exit PHIs in NEED_PHIS.  */
-
-static void
-find_uses_to_rename_def (tree def, bitmap *use_blocks, bitmap need_phis)
-{
-  gimple *use_stmt;
-  imm_use_iterator imm_iter;
-
-  FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
-{
-  if (is_gimple_debug (use_stmt))
-   continue;
-
-  basic_block use_bb = gimple_bb (use_stmt);
-
-  use_operand_p use_p;
-  FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
-   {
- if (gimple_code (use_stmt) == GIMPLE_PHI)
-   {
- edge e = gimple_phi_arg_edge (as_a  (use_stmt),
-   PHI_ARG_INDEX_FROM_USE (use_p));
- use_bb = e->src;
-   }
- find_uses_to_rename_use (use_bb, USE_FROM_PTR (use_p), use_blocks,
-  need_phis);
-   }
-}
-}
-
-/* Marks names matching USE_FLAGS that are defined in LOOP and used outside of
-   it for rewrite.  Records the set of blocks in which the ssa names are used 
to
-   USE_BLOCKS.  Record the SSA names that will need exit PHIs in NEED_PHIS.  */
-
-static void
-find_uses_to_rename_in_loop (class loop *loop, bitmap *use_blocks,
-bitmap need_phis, int use_flags)
-{
-  bool do_virtuals = (use_flags & SSA_OP_VIRTUAL_USES) != 0;
-  bool do_nonvirtuals = (use_flags & SSA_OP_USE) != 0;
-  int def_flags = ((do_virtuals ? SSA_OP_VIRTUAL_DEFS : 0)
-  | (do_nonvirtuals ? SSA_OP_DEF : 0));
-
-
-  basic_block *bbs = get_loop_body (loop);
-
-  for (unsigned int i = 0; i < loop->num_nodes; i++)
-{
-  basic_block bb = bbs[i];
-
-  for (gphi_iterator bsi = gsi_start_phis (bb); !gsi_end_p (bsi);
-  gsi_next (&bsi))
-   {
- gphi *phi = bsi.phi ();
- tree res = gimple_phi_result (phi);
- bool virtual_p = virtual_operand_p (res);
- if ((virtual_p && do_virtuals)
- || (!virtual_p && do_nonvirtuals))
-   find_uses_to_rename_def (res, use_blocks, need_phis);
-  }
-
-  for (gimple_stmt_iterator bsi = gsi_start_bb (bb); !gsi_end_p (bsi);
-  gsi_next (&bsi))
-   {
- gimple *stmt = gsi_stmt (bsi);
- /* FOR_EACH_SSA_TREE_OPERAND iterator does not allows
-SSA_OP_VIRTUAL_DEFS only.  */
- if (def_flags == SSA_OP_VIRTUAL_DEFS)
-   {
- tree vdef = gimple_vdef (stmt);
- if (vdef != NULL)
-   find_uses_to_rename_def (vdef, use_blocks, need_phis);
-   }
- else
-   {
- tree var;
- ssa_op_iter iter;
- FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, def_flags)
-   find_uses_to_rename_def (var, use_blocks, need_phis);
-   }
-   }
-}
-
-  XDELETEVEC (bbs);
-}
-
 /* Rewrites the program into a loop closed ssa form -- i.e. inserts extra
phi nodes to ensure that no variable is used outside the loop it is
defined in.
@@ -615,8 +527,7 @@ find_uses_to_rename_in_loop (class loop *loop, bitmap 
*use_blocks,
   is not well-behaved, while the second one is an induction variable with
   base 99 and step 1.
 
-  If LOOP is non-null, only rewrite uses that have defs in LOOP.  
Otherwise,
-  if CHANGED_BBS is not NULL, we look for uses outside loops only in the
+  If CHANGED_BBS is not NULL, we look for uses outside loops only in the
   basic blocks in this set.
 
   USE_FLAGS allows us to specify whether we want virtual, non-virtual or
@@ -627,7 +538,7 @@ find_uses_to_rename_in_loop (class loop *loop, bitmap 
*use_blocks,
 
 static void
 rewrite_into_loop_closed_ssa_1 (bitmap changed_bbs, unsigned update_flag,
-   int use_flags, class loop *loop)
+   int use_flags)
 {
   bitmap *use_blocks;
   bitmap names_to_rename;
@@ -651,18 +562,7 @@ rewrite_into_loop_closed_ssa_1 (bitmap changed_bbs, 
unsigned update_flag,
  beca

[PATCH] tree-optimization/106198 - CFG cleanup vs LC SSA

2022-07-05 Thread Richard Biener via Gcc-patches
This is another case like PR106182 where for the 2nd testcase in
the bug there are no removed or discovered loops but still changing
loop exits invalidates LC SSA and it is not enough to just scan for
uses in the blocks that changed loop depth.  One might argue that
if we'd include former exit destinations we'd pick up the original
LC SSA use but for virtuals on block merging we'd have propagated
those out (while for regular uses we insert copies).  CFG cleanup
can also be entered with loops needing fixup so any heuristics
based on loop structure are bound to fail.

Boostrapped and tested on x86_64-unknown-linux-gnu, pushed.

PR tree-optimization/106198
* tree-cfgcleanup.cc (repair_loop_structures): Always do a
full LC SSA rewrite but only if any blocks changed loop
depth.

* gcc.dg/pr106198.c: New testcase.
---
 gcc/testsuite/gcc.dg/pr106198.c | 22 ++
 gcc/tree-cfgcleanup.cc  |  6 +++---
 2 files changed, 25 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/pr106198.c

diff --git a/gcc/testsuite/gcc.dg/pr106198.c b/gcc/testsuite/gcc.dg/pr106198.c
new file mode 100644
index 000..00d2758efa7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr106198.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+int printf(const char *, ...);
+long a;
+int b;
+volatile int c;
+int main() {
+  long e = a;
+  int f = a;
+ L:
+  if (b > 0) {
+printf("0");
+goto L;
+  }
+  if (f) {
+printf("%ld", (long)b);
+goto L;
+  }
+  e >= b && c;
+  return 0;
+}
diff --git a/gcc/tree-cfgcleanup.cc b/gcc/tree-cfgcleanup.cc
index 3b24e021b6b..b9ff6896ce6 100644
--- a/gcc/tree-cfgcleanup.cc
+++ b/gcc/tree-cfgcleanup.cc
@@ -1183,9 +1183,9 @@ repair_loop_structures (void)
  become unreachable by back edges from latch).  Also a former
  irreducible loop can become reducible - in this case force a full
  rewrite into loop-closed SSA form.  */
-  if (loops_state_satisfies_p (LOOP_CLOSED_SSA))
-rewrite_into_loop_closed_ssa (n_new_or_deleted_loops ? NULL : changed_bbs,
- TODO_update_ssa);
+  if (loops_state_satisfies_p (LOOP_CLOSED_SSA)
+  && (!bitmap_empty_p (changed_bbs) || n_new_or_deleted_loops))
+rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
 
   BITMAP_FREE (changed_bbs);
 
-- 
2.35.3


Re: [PATCH] c++: generic targs and identity substitution [PR105956]

2022-07-05 Thread Patrick Palka via Gcc-patches
On Fri, 1 Jul 2022, Jason Merrill wrote:

> On 6/29/22 13:42, Patrick Palka wrote:
> > In r13-1045-gcb7fd1ea85feea I assumed that substitution into generic
> > DECL_TI_ARGS corresponds to an identity mapping of the given arguments,
> > and hence its safe to always elide such substitution.  But this PR
> > demonstrates that such a substitution isn't always the identity mapping,
> > in particular when there's an ARGUMENT_PACK_SELECT argument, which gets
> > handled specially during substitution:
> > 
> >* when substituting an APS into a template parameter, we strip the
> >  APS to its underlying argument;
> >* and when substituting an APS into a pack expansion, we strip the
> >  APS to its underlying argument pack.
> 
> Ah, right.  For instance, in variadic96.C we have
> 
> 10template < typename... T >
> 11struct derived
> 12  : public base< T, derived< T... > >...
> 
> so when substituting into the base-specifier, we're approaching it from the
> outside in, so when we get to the inner T... we need some way to find the T
> pack again.  It might be possible to remove the need for APS by substituting
> inner pack expansions before outer ones, which could improve worst-case
> complexity, but I don't know how relevant that is in real code; I imagine most
> inner pack expansions are as simple as this one.

Aha, that makes sense.

> 
> > In this testcase, when expanding the pack expansion pattern (idx + Ns)...
> > with Ns={0,1}, we specialize idx twice, first with Ns=APS<0,{0,1}> and
> > then Ns=APS<1,{0,1}>.  The DECL_TI_ARGS of idx are the generic template
> > arguments of the enclosing class template impl, so before r13-1045,
> > we'd substitute into its DECL_TI_ARGS which gave Ns={0,1} as desired.
> > But after r13-1045, we elide this substitution and end up attempting to
> > hash the original Ns argument, an APS, which ICEs.
> > 
> > So this patch partially reverts this part of r13-1045.  I considered
> > using preserve_args in this case instead, but that'd break the
> > static_assert in the testcase because preserve_args always strips APS to
> > its underlying argument, but here we want to strip it to its underlying
> > argument pack, so we'd incorrectly end up forming the specializations
> > impl<0>::idx and impl<1>::idx instead of impl<0,1>::idx.
> > 
> > Although we can't elide the substitution into DECL_TI_ARGS in light of
> > ARGUMENT_PACK_SELECT, it should still be safe to elide template argument
> > coercion in the case of a non-template decl, which this patch preserves.
> > 
> > It's unfortunate that we need to remove this optimization just because
> > it doesn't hold for one special tree code.  So this patch implements a
> > heuristic in tsubst_template_args to avoid allocating a new TREE_VEC if
> > the substituted elements are identical to those of a level from ARGS.
> > It turns out that about 30% of all calls to tsubst_template_args benefit
> > from this optimization, and it reduces memory usage by about 1.5% for
> > e.g. stdc++.h (relative to r13-1045).  (This is the maybe_reuse stuff,
> > the rest of the changes to tsubst_template_args are just drive-by
> > cleanups.)
> > 
> > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
> > trunk?  Patch generated with -w to ignore noisy whitespace changes.
> > 
> > PR c++/105956
> > 
> > gcc/cp/ChangeLog:
> > 
> > * pt.cc (tsubst_template_args): Move variable declarations
> > closer to their first use.  Replace 'orig_t' with 'r'.  Rename
> > 'need_new' to 'const_subst_p'.  Heuristically detect if the
> > substituted elements are identical to that of a level from
> > 'args' and avoid allocating a new TREE_VEC if so.
> > (tsubst_decl) : Revert
> > r13-1045-gcb7fd1ea85feea change for avoiding substitution into
> > DECL_TI_ARGS, but still avoid coercion in this case.
> > 
> > gcc/testsuite/ChangeLog:
> > 
> > * g++.dg/cpp0x/variadic183.C: New test.
> > ---
> >   gcc/cp/pt.cc | 113 ++-
> >   gcc/testsuite/g++.dg/cpp0x/variadic183.C |  14 +++
> >   2 files changed, 85 insertions(+), 42 deletions(-)
> >   create mode 100644 gcc/testsuite/g++.dg/cpp0x/variadic183.C
> > 
> > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
> > index 8672da123f4..7898834faa6 100644
> > --- a/gcc/cp/pt.cc
> > +++ b/gcc/cp/pt.cc
> > @@ -27,6 +27,7 @@ along with GCC; see the file COPYING3.  If not see
> >Fixed by: C++20 modules.  */
> > #include "config.h"
> > +#define INCLUDE_ALGORITHM // for std::equal
> >   #include "system.h"
> >   #include "coretypes.h"
> >   #include "cp-tree.h"
> > @@ -13544,17 +13545,22 @@ tsubst_argument_pack (tree orig_arg, tree args,
> > tsubst_flags_t complain,
> >   tree
> >   tsubst_template_args (tree t, tree args, tsubst_flags_t complain, tree
> > in_decl)
> >   {
> > -  tree orig_t = t;
> > -  int len, need_new = 0, i, expanded_len_adjust = 0, out;
> > -  tree *elts;
> > -
> > if (t

Re: [PATCH] c-family: Add names to diagnostics for known headers

2022-07-05 Thread Marek Polacek via Gcc-patches
On Mon, Jul 04, 2022 at 05:25:42PM +0100, Jonathan Wakely wrote:
> On Thu, 30 Jun 2022 at 16:15, Marek Polacek wrote:
> >
> > On Thu, Jun 30, 2022 at 04:11:42PM +0100, Jonathan Wakely via Gcc-patches 
> > wrote:
> > > I recently changed  to no longer include an unnecessary header,
> > > which meant it no longer includes , which means it no longer
> > > includes . This resulted in some build failures:
> > > https://issues.apache.org/jira/browse/LUCENE-10630
> > > https://github.com/openSUSE/libzypp/pull/405
> > >
> > > And that revealed that we don't suggest the right header for those
> > > functions. Fixed like so.
> > >
> > > Tested x86_64-linux. OK for trunk?
> >
> > Ok, thanks.
> 
> OK for gcc-12 too? I already backported the include streamlining for
>  that causes several packages to get errors for missing
> , so it makes sense to also backport these improved
> diagnostics.

Since the patch isn't adding any new diagnostics that previously wasn't
there, I think it's OK as well, thanks.

Marek



[PING^2] nvptx: forward '-v' command-line option to assembler, linker

2022-07-05 Thread Thomas Schwinge
Hi Tom!

Ping.


Grüße
 Thomas


On 2022-06-07T17:41:16+0200, I wrote:
> Hi!
>
> On 2022-05-30T09:06:21+0200, Tobias Burnus  wrote:
>> On 29.05.22 22:49, Thomas Schwinge wrote:
>>> Not sure if that's what you had in mind, but what do you think about the
>>> attached "nvptx: forward '-v' command-line option to assembler, linker"?
>>> OK to push to GCC master branch (after merging
>>> 
>>> "Put '-v' verbose output onto stderr instead of stdout")?
>>
>> I was mainly thinking of some way to have it available — which
>> '-foffload-options=-Wa,-v' already permits on the GCC side. (Once the
>> nvptx-tools patch actually makes use of the '-v'.)
>
> (Merged a week ago.)
>
>> If I understand your patch correctly, this patch now causes 'gcc -v' to
>> imply 'gcc -v -Wa,-v'. I think that's okay, since 'gcc -v' already
>> outputs a lot of lines and those lines can be helpful to understand what
>> happens and what not.
>
> ACK.
>
>> Tom, your thoughts on this?
>
> Ping.
>
>
> Grüße
>  Thomas


-
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 
München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas 
Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht 
München, HRB 106955
>From 17c35607d4927299b0c4bd19dd6fd205c85c4a4b Mon Sep 17 00:00:00 2001
From: Thomas Schwinge 
Date: Sun, 29 May 2022 22:31:43 +0200
Subject: [PATCH] nvptx: forward '-v' command-line option to assembler, linker

For example, for offloading compilation with '-save-temps -v', before vs. after
word-diff then looks like:

[...]
 [...]/build-gcc-offload-nvptx-none/gcc/as {+-v -v+} -o ./a.xnvptx-none.mkoffload.o ./a.xnvptx-none.mkoffload.s
{+Verifying sm_30 code with sm_35 code generation.+}
{+ ptxas -c -o /dev/null ./a.xnvptx-none.mkoffload.o --gpu-name sm_35 -O0+}
[...]
 [...]/build-gcc-offload-nvptx-none/gcc/collect2 {+-v -v+} -o ./a.xnvptx-none.mkoffload [...] @./a.xnvptx-none.mkoffload.args.1 -lgomp -lgcc -lc -lgcc
{+collect2 version 12.0.1 20220428 (experimental)+}
{+[...]/build-gcc-offload-nvptx-none/gcc/collect-ld -v -v -o ./a.xnvptx-none.mkoffload [...] ./a.xnvptx-none.mkoffload.o -lgomp -lgcc -lc -lgcc+}
{+Linking ./a.xnvptx-none.mkoffload.o as 0+}
{+trying lib libc.a+}
{+trying lib libgcc.a+}
{+trying lib libgomp.a+}
{+Resolving abort+}
{+Resolving acc_on_device+}
{+Linking libgomp.a::oacc-init.o/ as 1+}
{+Linking libc.a::lib_a-abort.o/   as 2+}
[...]

(This depends on 
"Put '-v' verbose output onto stderr instead of stdout".)

	gcc/
	* config/nvptx/nvptx.h (ASM_SPEC, LINK_SPEC): Define.
---
 gcc/config/nvptx/nvptx.h | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/gcc/config/nvptx/nvptx.h b/gcc/config/nvptx/nvptx.h
index ed72c253191..b184f1d0150 100644
--- a/gcc/config/nvptx/nvptx.h
+++ b/gcc/config/nvptx/nvptx.h
@@ -27,6 +27,13 @@
 
 /* Run-time Target.  */
 
+/* Assembler supports '-v' option; handle similar to
+   '../../gcc.cc:asm_options', 'HAVE_GNU_AS'.  */
+#define ASM_SPEC "%{v}"
+
+/* Linker supports '-v' option.  */
+#define LINK_SPEC "%{v}"
+
 #define STARTFILE_SPEC "%{mmainkernel:crt0.o}"
 
 #define TARGET_CPU_CPP_BUILTINS() nvptx_cpu_cpp_builtins ()
-- 
2.25.1



[PING] nvptx: Allow '--with-arch' to override the default '-misa' (was: nvptx multilib setup)

2022-07-05 Thread Thomas Schwinge
Hi Tom!

Ping.


Grüße
 Thomas


On 2022-06-15T23:18:10+0200, I wrote:
> Hi Tom!
>
> On 2022-05-13T16:20:14+0200, I wrote:
>> On 2022-02-04T13:09:29+0100, Tom de Vries via Gcc  wrote:
>>> On 2/4/22 08:21, Thomas Schwinge wrote:
 On 2022-02-03T13:35:55+, "vries at gcc dot gnu.org via Gcc-bugs" 
  wrote:
> I've tested this using (recommended) driver 470.94 on boards:
>>
> while iterating over dimensions { -mptx=3.1 , -mptx=6.3 } x { 
> GOMP_NVPTX_JIT=-O0,  }.

 Do you use separate (nvptx-none offload target only?) builds for
 different '-mptx' variants (likewise: '-misa'), or have you hacked up the
 multilib configuration?
>>>
>>> Neither, I'm using --target_board=unix/foffload= for that.
>>
>> ACK, I see.  So these flags then only affect GCC/nvptx code generation
>> for the actual user code (here: GCC libgomp test cases), but for the
>> GCC/nvptx target libraries (such as: libc, libm, libgfortran, libgomp --
>> the latter especially relevant for OpenMP), it uses PTX code from one of
>> the two "pre-compiled" GCC/nvptx multilibs: default or '-mptx=3.1'.
>>
>> Meaning, one can't just use such a flag for "completely building code"
>> for a specific configuration.  Random example,
>> '-foffload-options=nvptx-none=-march=sm_75': as GCC/nvptx target
>> libraries aren't being built for '-march=sm_75' multilib,
>> '-foffload-options=nvptx-none=-march=sm_75' uses the default multilib,
>> which isn't '-march=sm_75'.
>>
>>
>>>   ('gcc/config/nvptx/t-nvptx:MULTILIB_OPTIONS'
 etc., I suppose?)  Should we add a few representative configurations to
 be built by default?  And/or, should we have a way to 'configure' per
 user needs (I suppose: '--with-multilib-list=[...]', as supported for a
 few other targets?)?  (I see there's also a new
 '--with-multilib-generator=[...]', haven't looked in detail.)  No matter
 which way: again, combinatorial explosion is a problem, of course...
>>>
>>> As far as I know, the gcc build doesn't finish when switching default to
>>> higher than sm_35, so there's little point to go to a multilib setup at
>>> this point.  But once we fix that, we could reconsider, otherwise,
>>> things are likely to regress again.
>>
>> As far as I remember, several issues have been fixed.  Still waiting for
>> Roger's "middle-end: Support ABIs that pass FP values as wider integers"
>> or something similar, but that PR104489 issue is being worked around by
>> "Limit HFmode support to mexperimental", if I got that right.
>>
>> Now I'm not suggesting we should now enable all or any random GCC/nvptx
>> multilibs, to get all these variants of GCC/nvptx target libraries built;
>> especially also given that GCC/nvptx code generation currently doesn't
>> make too much use of the new capabilities.
>>
>> However, we do have a specific request that a customer would like to be
>> able to change at GCC 'configure' time the GCC/nvptx default multilib
>> (including that being used for building corresponding GCC/nvptx target
>> libraries).
>>
>> Per 'gcc/doc/install.texi', I do see that some GCC targets allow for
>> GCC 'configure'-time '--with-multilib-list=[...]', or
>> '--with-multilib-generator=[...]', and I suppose we could be doing
>> something similar?  But before starting implementing, I'd like your
>> input, as you'll be the one to approve in the end.  And/or, maybe you've
>> already made up your own ideas about that?
>
> So, instead of "random GCC/nvptx multilib configuration" (last
> paragraph), I've come up with a way to implement our customer's request
> (second last paragraph): 'configure' GCC/nvptx '--with-arch=sm_70'.
>
> I think I've implemented this in a way so that "random GCC/nvptx multilib
> configuration" may eventually be implemented on top of that.  For easy
> review/testing I've split my changes into three commits, see attached
> "nvptx: Make default '-misa=sm_30' explicit",
> "nvptx: Introduce dummy multilib option for default '-misa=sm_30'",
> "nvptx: Allow '--with-arch' to override the default '-misa'".
>
> To the best of my knowledge, the first two patches do not change any
> user-visible behavior (I generally 'diff'ed target libraries, and
> compared a good number of 'gcc -print-multi-directory [flags]'), and
> likewise with the third patch, given implicit (default) or explicit
> '--with-arch=sm_30', and that with '--with-arch=sm_70', for example, the
> '-misa=sm_70' multilib variants are used for implicit (default) or
> explicit '-misa=sm_70' or higher, and the '-misa=sm_30' multilib variants
> are used for explicit lower '-misa'.
>
> What do you think, OK to push to master branch?
>
>
> Grüße
>  Thomas


-
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 
München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas 
Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht 
München, HRB 106955
>From ae782b3d1db7a9b2dea744d2a718bec94ac57677 Mon Sep 17 00:00:00 200

[PATCH]middle-end: don't lower past veclower [PR106063]

2022-07-05 Thread Tamar Christina via Gcc-patches
Hi All,

My previous patch can cause a problem if the pattern matches after veclower
as it may replace the construct with a vector sequence which the target may not
directly support.

As such don't perform the rewriting if after veclower.

Bootstrapped Regtested on aarch64-none-linux-gnu, x86_64-pc-linux-gnu
and no issues.

Ok for master? and backport to GCC 12?

Thanks,
Tamar


gcc/ChangeLog:

PR tree-optimization/106063
* match.pd: Do not apply pattern after veclower.

gcc/testsuite/ChangeLog:

PR tree-optimization/106063
* gcc.dg/pr106063.c: New test.

--- inline copy of patch -- 
diff --git a/gcc/match.pd b/gcc/match.pd
index 
40c09bedadb89dabb6622559a8f69df5384e61fd..ba161892a98756c0278dc40fc377d7d0deaacbcf
 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -6040,7 +6040,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
   (simplify
(cmp (bit_and:c@2 @0 cst@1) integer_zerop)
 (with { tree csts = bitmask_inv_cst_vector_p (@1); }
- (if (csts && (VECTOR_TYPE_P (TREE_TYPE (@1)) || single_use (@2)))
+ (if (csts && (VECTOR_TYPE_P (TREE_TYPE (@1)) || single_use (@2))
+ && optimize_vectors_before_lowering_p ())
   (if (TYPE_UNSIGNED (TREE_TYPE (@1)))
(icmp @0 { csts; })
(with { tree utype = unsigned_type_for (TREE_TYPE (@1)); }
diff --git a/gcc/testsuite/gcc.dg/pr106063.c b/gcc/testsuite/gcc.dg/pr106063.c
new file mode 100644
index 
..b23596724f6bb98c53af2dce77d31509bab10378
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr106063.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-tree-forwprop --disable-tree-evrp" } */
+typedef __int128 __attribute__((__vector_size__ (16))) V;
+
+V
+foo (V v)
+{
+  return (v & (V){15}) == v;
+}




-- 
diff --git a/gcc/match.pd b/gcc/match.pd
index 
40c09bedadb89dabb6622559a8f69df5384e61fd..ba161892a98756c0278dc40fc377d7d0deaacbcf
 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -6040,7 +6040,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
   (simplify
(cmp (bit_and:c@2 @0 cst@1) integer_zerop)
 (with { tree csts = bitmask_inv_cst_vector_p (@1); }
- (if (csts && (VECTOR_TYPE_P (TREE_TYPE (@1)) || single_use (@2)))
+ (if (csts && (VECTOR_TYPE_P (TREE_TYPE (@1)) || single_use (@2))
+ && optimize_vectors_before_lowering_p ())
   (if (TYPE_UNSIGNED (TREE_TYPE (@1)))
(icmp @0 { csts; })
(with { tree utype = unsigned_type_for (TREE_TYPE (@1)); }
diff --git a/gcc/testsuite/gcc.dg/pr106063.c b/gcc/testsuite/gcc.dg/pr106063.c
new file mode 100644
index 
..b23596724f6bb98c53af2dce77d31509bab10378
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr106063.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-tree-forwprop --disable-tree-evrp" } */
+typedef __int128 __attribute__((__vector_size__ (16))) V;
+
+V
+foo (V v)
+{
+  return (v & (V){15}) == v;
+}





RE: [PATCH]middle-end Use subregs to expand COMPLEX_EXPR to set the lowpart.

2022-07-05 Thread Tamar Christina via Gcc-patches
> > so that the multiple_p test is skipped if the structure is undefined.
> 
> Actually, we should probably skip the constant_multiple_p test as well.
> Keeping it would only be meaningful for little-endian.
> 
> simplify_gen_subreg should alread do the necessary checks to make sure
> that the subreg can be formed (via validate_subreg).
> 

Bootstrapped Regtested on aarch64-none-linux-gnu, x86_64-pc-linux-gnu
and no issues.

Ok for master?

Thanks,
Tamar

gcc/ChangeLog:

* expmed.cc (store_bit_field):
* expmed.cc (store_bit_field_1): Add parameter that indicates if value 
is
still undefined and if so emit a subreg move instead.
(store_integral_bit_field): Likewise.
(store_bit_field): Likewise.
* expr.h (write_complex_part): Likewise.
* expmed.h (store_bit_field): Add new parameter.
* builtins.cc (expand_ifn_atomic_compare_exchange_into_call): Use new
parameter.
(expand_ifn_atomic_compare_exchange): Likewise.
* calls.cc (store_unaligned_arguments_into_pseudos): Likewise.
* emit-rtl.cc (validate_subreg): Likewise.
* expr.cc (emit_group_store): Likewise.
(copy_blkmode_from_reg): Likewise.
(copy_blkmode_to_reg): Likewise.
(clear_storage_hints): Likewise.
(write_complex_part):  Likewise.
(emit_move_complex_parts): Likewise.
(expand_assignment): Likewise.
(store_expr): Likewise.
(store_field): Likewise.
(expand_expr_real_2): Likewise.
* ifcvt.cc (noce_emit_move_insn): Likewise.
* internal-fn.cc (expand_arith_set_overflow): Likewise.
(expand_arith_overflow_result_store): Likewise.
(expand_addsub_overflow): Likewise.
(expand_neg_overflow): Likewise.
(expand_mul_overflow): Likewise.
(expand_arith_overflow): Likewise.

gcc/testsuite/ChangeLog:

* g++.target/aarch64/complex-init.C: New test.

--- inline copy of patch ---

diff --git a/gcc/builtins.cc b/gcc/builtins.cc
index 
e6816d5c86550b724e89aad834ad3314d555a6b4..35b9197945fdc8ba44a8b02a871490ed384a4927
 100644
--- a/gcc/builtins.cc
+++ b/gcc/builtins.cc
@@ -6029,8 +6029,8 @@ expand_ifn_atomic_compare_exchange_into_call (gcall 
*call, machine_mode mode)
   if (GET_MODE (boolret) != mode)
boolret = convert_modes (mode, GET_MODE (boolret), boolret, 1);
   x = force_reg (mode, x);
-  write_complex_part (target, boolret, true);
-  write_complex_part (target, x, false);
+  write_complex_part (target, boolret, true, true);
+  write_complex_part (target, x, false, false);
 }
 }
 
@@ -6085,8 +6085,8 @@ expand_ifn_atomic_compare_exchange (gcall *call)
   rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
   if (GET_MODE (boolret) != mode)
boolret = convert_modes (mode, GET_MODE (boolret), boolret, 1);
-  write_complex_part (target, boolret, true);
-  write_complex_part (target, oldval, false);
+  write_complex_part (target, boolret, true, true);
+  write_complex_part (target, oldval, false, false);
 }
 }
 
diff --git a/gcc/calls.cc b/gcc/calls.cc
index 
f4e1299505ed542f34a6873c3537b881ed288c98..4e61e558b27071ee0f2f0f4cff7c1d806741b069
 100644
--- a/gcc/calls.cc
+++ b/gcc/calls.cc
@@ -1216,7 +1216,7 @@ store_unaligned_arguments_into_pseudos (struct arg_data 
*args, int num_actuals)
 
bytes -= bitsize / BITS_PER_UNIT;
store_bit_field (reg, bitsize, endian_correction, 0, 0,
-word_mode, word, false);
+word_mode, word, false, false);
  }
   }
 }
diff --git a/gcc/emit-rtl.cc b/gcc/emit-rtl.cc
index 
1e02ae254d01293d03447bf686e7581d3758305f..3929ee08986cb9137dada62b0edcc30ed81cc1a4
 100644
--- a/gcc/emit-rtl.cc
+++ b/gcc/emit-rtl.cc
@@ -947,9 +947,11 @@ validate_subreg (machine_mode omode, machine_mode imode,
   && GET_MODE_INNER (omode) == GET_MODE_INNER (imode))
 ;
   /* Subregs involving floating point modes are not allowed to
- change size.  Therefore (subreg:DI (reg:DF) 0) is fine, but
+ change size unless it's an insert into a complex mode.
+ Therefore (subreg:DI (reg:DF) 0) and (subreg:CS (reg:SF) 0) are fine, but
  (subreg:SI (reg:DF) 0) isn't.  */
-  else if (FLOAT_MODE_P (imode) || FLOAT_MODE_P (omode))
+  else if ((FLOAT_MODE_P (imode) || FLOAT_MODE_P (omode))
+  && !COMPLEX_MODE_P (omode))
 {
   if (! (known_eq (isize, osize)
 /* LRA can use subreg to store a floating point value in
diff --git a/gcc/expmed.h b/gcc/expmed.h
index 
ee1ddc82b601ce02957c493dad0d70eee2784ed7..0b2538c4c6bd51dfdc772ef70bdf631c0bed8717
 100644
--- a/gcc/expmed.h
+++ b/gcc/expmed.h
@@ -715,7 +715,7 @@ extern rtx expand_divmod (int, enum tree_code, 
machine_mode, rtx, rtx,
 
 extern void store_bit_field (rtx, poly_uint64, poly_uint64,
 poly_uint64, poly_uint64,
-machine_mod

c++: Prune ordinary locations

2022-07-05 Thread Nathan Sidwell via Gcc-patches


Like macro locations, we only need to emit ordinary location
information for locations emitted into the CMI. This adds a hash table
noting which ordinary lines are needed.  These are then sorted and
(sufficiently) adjacent lines are coalesced to a single map.  There is
a tradeoff here, allowing greater separation reduces the number of
line maps, but increases the number of locations.  It appears allowing
2 or 3 intervening lines is the sweet spot, and this patch chooses 2.

Compiling a hello-world #includeing  in it's GMF gives a
reduction in number of locations of 5 fold, but an increase in number
of maps about 4 fold.  Examining one of the xtreme-header tests we
halve the number of locations and increase the number of maps by 9
fold.

Module interfaces that emit no entities (or macros, if a header-unit),
will now have no location tables.

nathan

--
Nathan SidwellFrom 47794da8d8ea61ea8f6a0e21d3c1731a56d0cff3 Mon Sep 17 00:00:00 2001
From: Nathan Sidwell 
Date: Fri, 24 Jun 2022 05:57:42 -0700
Subject: [PATCH] c++: Prune ordinary locations

Like macro locations, we only need to emit ordinary location
information for locations emitted into the CMI. This adds a hash table
noting which ordinary lines are needed.  These are then sorted and
(sufficiently) adjacent lines are coalesced to a single map.  There is
a tradeoff here, allowing greater separation reduces the number of
line maps, but increases the number of locations.  It appears allowing
2 or 3 intervening lines is the sweet spot, and this patch chooses 2.

Compiling a hello-world #includeing  in it's GMF gives a
reduction in number of locations of 5 fold, but an increase in number
of maps about 4 fold.  Examining one of the xtreme-header tests we
halve the number of locations and increase the number of maps by 9
fold.

Module interfaces that emit no entities (or macros, if a header-unit),
will now have no location tables.

	gcc/cp/
	* module.cc
	(struct ord_loc_info, ord_loc_traits): New.
	(ord_loc_tabke, ord_loc_remap): New globals.
	(struct location_map_info): Delete.
	(struct module_state_config): Rename ordinary_loc_align to
	loc_range_bits.
	(module_for_ordinary_loc): Adjust.
	(module_state::note_location): Note ordinary locations,
	return bool.
	(module_state::write_location): Adjust ordinary location
	streaming.
	(module_state::read_location): Likewise.
	(module_state::write_init_maps): Allocate ord_loc_table.
	(module_state::write_prepare_maps): Reimplement ordinary
	map preparation.
	(module_state::read_prepare_maps): Adjust.
	(module_state::write_ordinary_maps): Reimplement.
	(module_state::write_macro_maps): Adjust.
	(module_state::read_ordinary_maps): Reimplement.
	(module_state::write_macros): Adjust.
	(module_state::write_config): Adjust.
	(module_state::read_config): Adjust.
	(module_state::write_begin): Adjust.
	(module_state::read_initial): Adjust.
	gcc/testsuite/
	* g++.dg/modules/loc-prune-1.C: Adjust.
	* g++.dg/modules/loc-prune-4.C: New.
	* g++.dg/modules/pr98718_a.C: Adjust.
	* g++.dg/modules/pr98718_b.C: Adjust.
	* g++.dg/modules/pr99072.H: Adjust.
---
 gcc/cp/module.cc   | 625 -
 gcc/testsuite/g++.dg/modules/loc-prune-1.C |   2 +-
 gcc/testsuite/g++.dg/modules/loc-prune-4.C |  22 +
 gcc/testsuite/g++.dg/modules/pr98718_a.C   |   2 +-
 gcc/testsuite/g++.dg/modules/pr98718_b.C   |   2 +-
 gcc/testsuite/g++.dg/modules/pr99072.H |   4 +-
 6 files changed, 373 insertions(+), 284 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/modules/loc-prune-4.C

diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 238a5eb74d2..f27f4d091e5 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -3240,6 +3240,66 @@ public:
 
 static loc_spans spans;
 
+/* Information about ordinary locations we stream out.  */
+struct ord_loc_info
+{
+  const line_map_ordinary *src; // line map we're based on
+  unsigned offset;	// offset to this line
+  unsigned span;	// number of locs we span
+  unsigned remap;	// serialization
+
+  static int compare (const void *a_, const void *b_)
+  {
+auto *a = static_cast (a_);
+auto *b = static_cast (b_);
+
+if (a->src != b->src)
+  return a->src < b->src ? -1 : +1;
+
+// Ensure no overlap
+gcc_checking_assert (a->offset + a->span <= b->offset
+			 || b->offset + b->span <= a->offset);
+
+gcc_checking_assert (a->offset != b->offset);
+return a->offset < b->offset ? -1 : +1;
+  }
+};
+struct ord_loc_traits
+{
+  typedef ord_loc_info value_type;
+  typedef value_type compare_type;
+
+  static const bool empty_zero_p = false;
+
+  static hashval_t hash (const value_type &v)
+  {
+auto h = pointer_hash::hash (v.src);
+return iterative_hash_hashval_t (v.offset, h);
+  }
+  static bool equal (const value_type &v, const compare_type p)
+  {
+return v.src == p.src && v.offset == p.offset;
+  }
+
+  static void mark_empty (value_type &v)
+  {
+v.src = nullptr;
+  }
+  static bool is_empty (value_type &v)
+  {
+return !v.src;

RE: [PATCH]middle-end simplify complex if expressions where comparisons are inverse of one another.

2022-07-05 Thread Tamar Christina via Gcc-patches


> -Original Message-
> From: Richard Biener 
> Sent: Monday, June 20, 2022 9:57 AM
> To: Tamar Christina 
> Cc: gcc-patches@gcc.gnu.org; nd 
> Subject: Re: [PATCH]middle-end simplify complex if expressions where
> comparisons are inverse of one another.
> 
> On Thu, 16 Jun 2022, Tamar Christina wrote:
> 
> > Hi All,
> >
> > This optimizes the following sequence
> >
> >   ((a < b) & c) | ((a >= b) & d)
> >
> > into
> >
> >   (a < b ? c : d) & 1
> >
> > for scalar. On vector we can omit the & 1.
> >
> > This changes the code generation from
> >
> > zoo2:
> > cmp w0, w1
> > csetw0, lt
> > csetw1, ge
> > and w0, w0, w2
> > and w1, w1, w3
> > orr w0, w0, w1
> > ret
> >
> > into
> >
> > cmp w0, w1
> > cselw0, w2, w3, lt
> > and w0, w0, 1
> > ret
> >
> > and significantly reduces the number of selects we have to do in the
> > vector code.
> >
> > Bootstrapped Regtested on aarch64-none-linux-gnu, x86_64-pc-linux-gnu
> > and no issues.
> >
> > Ok for master?
> >
> > Thanks,
> > Tamar
> >
> > gcc/ChangeLog:
> >
> > * fold-const.cc (inverse_conditions_p): Traverse if SSA_NAME.
> > * match.pd: Add new rule.
> >
> > gcc/testsuite/ChangeLog:
> >
> > * gcc.target/aarch64/if-compare_1.c: New test.
> > * gcc.target/aarch64/if-compare_2.c: New test.
> >
> > --- inline copy of patch --
> > diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc index
> >
> 39a5a52958d87497f301826e706886b290771a2d..f180599b90150acd3ed895a64
> 280
> > aa3255061256 100644
> > --- a/gcc/fold-const.cc
> > +++ b/gcc/fold-const.cc
> > @@ -2833,15 +2833,38 @@ compcode_to_comparison (enum
> comparison_code
> > code)  bool  inverse_conditions_p (const_tree cond1, const_tree cond2)
> > {
> > -  return (COMPARISON_CLASS_P (cond1)
> > - && COMPARISON_CLASS_P (cond2)
> > - && (invert_tree_comparison
> > - (TREE_CODE (cond1),
> > -  HONOR_NANS (TREE_OPERAND (cond1, 0))) == TREE_CODE
> (cond2))
> > - && operand_equal_p (TREE_OPERAND (cond1, 0),
> > - TREE_OPERAND (cond2, 0), 0)
> > - && operand_equal_p (TREE_OPERAND (cond1, 1),
> > - TREE_OPERAND (cond2, 1), 0));
> > +  if (COMPARISON_CLASS_P (cond1)
> > +  && COMPARISON_CLASS_P (cond2)
> > +  && (invert_tree_comparison
> > +  (TREE_CODE (cond1),
> > +   HONOR_NANS (TREE_OPERAND (cond1, 0))) == TREE_CODE
> (cond2))
> > +  && operand_equal_p (TREE_OPERAND (cond1, 0),
> > + TREE_OPERAND (cond2, 0), 0)
> > +  && operand_equal_p (TREE_OPERAND (cond1, 1),
> > + TREE_OPERAND (cond2, 1), 0))
> > +return true;
> > +
> > +  if (TREE_CODE (cond1) == SSA_NAME
> > +  && TREE_CODE (cond2) == SSA_NAME)
> > +{
> > +  gimple *gcond1 = SSA_NAME_DEF_STMT (cond1);
> > +  gimple *gcond2 = SSA_NAME_DEF_STMT (cond2);
> > +  if (!is_gimple_assign (gcond1) || !is_gimple_assign (gcond2))
> > +   return false;
> > +
> > +  tree_code code1 = gimple_assign_rhs_code (gcond1);
> > +  tree_code code2 = gimple_assign_rhs_code (gcond2);
> > +  return TREE_CODE_CLASS (code1) == tcc_comparison
> > +&& TREE_CODE_CLASS (code2) == tcc_comparison
> > +&& invert_tree_comparison (code1,
> > + HONOR_NANS (gimple_arg (gcond1, 0))) == code2
> > +&& operand_equal_p (gimple_arg (gcond1, 0),
> > +gimple_arg (gcond2, 0), 0)
> > +&& operand_equal_p (gimple_arg (gcond1, 1),
> > +gimple_arg (gcond2, 1), 0);
> > +}
> > +
> > +  return false;
> 
> if we do extend inverse_condition_p please add an overload like

Done. 

> 
> bool
> inverse_condition_p (enum tree_code, tree op00, tree op01,
>  enum tree_code, tree op10, tree op11)
> 
> so you can avoid some code duplication here.
> 
> >  }
> >
> >  /* Return a tree for the comparison which is the combination of diff
> > --git a/gcc/match.pd b/gcc/match.pd index
> >
> 6d691d302b339c0e4556b40af158b5208c12d08f..bad49dd348add751d9ec1e30
> 23e3
> > 4d9ac123194f 100644
> > --- a/gcc/match.pd
> > +++ b/gcc/match.pd
> > @@ -1160,6 +1160,32 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
> >   (convert (bit_and (negate (convert:utype { pmop[0]; }))
> >(convert:utype @1)))
> >
> > +/* Fold (((a < b) & c) | ((a >= b) & d)) into (a < b ? c : d) & 1.
> > +*/ (simplify  (bit_ior
> > +  (bit_and:c (convert? @0) @2)
> > +  (bit_and:c (convert? @1) @3))
> 
> in case the comparison returns a signed bool this might turn out wrong.
> Maybe simply use zero_one_valued_p@0 here instead of (convert? @0)?

I think I still need the convert as the comparison gets promoted to int and
the predicate doesn't handle extensions.

So I left the convert but added the zero_one_valued_p@0 such that it's
checking that the result of the comparison itself is at least 0 or 1.

> 
> > +   (if (inverse_conditions_p (@0, @1)
> > +   /* T

RE: [PATCH 2/2]middle-end: Support recognition of three-way max/min.

2022-07-05 Thread Tamar Christina via Gcc-patches
> > }
> > +  else if (EDGE_SUCC (bb1, 0)->dest == EDGE_SUCC (bb2, 0)->dest
> > +  && single_succ_p (bb1)
> > +  && single_succ_p (bb2)
> > +  && single_pred_p (bb1)
> > +  && single_pred_p (bb2)
> > +  && single_succ_p (EDGE_SUCC (bb1, 0)->dest))
> 
> please do the single_succ/pred checks below where appropriate, also what's
> the last check about? 

Done.

> why does the merge block need a single successor?

I was using it to fix an ICE, but I realize that's not the right fix. I'm now 
checking
If the BB is empty instead, in which case it's just a fall through edge so don't
treat it as a diamond.

> 
> > +   {
> > + gimple_stmt_iterator it1 = gsi_start_nondebug_after_labels_bb
> (bb1);
> > + gimple_stmt_iterator it2 = gsi_start_nondebug_after_labels_bb
> (bb2);
> > + if (gsi_one_before_end_p (it1) && gsi_one_before_end_p (it2))
> > +   {
> > + gimple *stmt1 = gsi_stmt (it1);
> > + gimple *stmt2 = gsi_stmt (it2);
> > + if (is_gimple_assign (stmt1) && is_gimple_assign (stmt2))
> > +   {
> > + enum tree_code code1 = gimple_assign_rhs_code (stmt1);
> > + enum tree_code code2 = gimple_assign_rhs_code (stmt2);
> > + diamond_minmax_p
> > +   = (code1 == MIN_EXPR || code1 == MAX_EXPR)
> > + && (code2 == MIN_EXPR || code2 == MAX_EXPR);
> > +   }
> > +   }
> > +   }
> 
> I'd generalize this to general diamond detection, simply cutting off
> *_replacement workers that do not handle diamonds and do appropriate
> checks in minmax_replacement only.
> 

Done.

> >else
> > continue;
> >
> > @@ -316,6 +340,13 @@ tree_ssa_phiopt_worker (bool do_store_elim,
> bool do_hoist_loads, bool early_p)
> >   if (!candorest)
> > continue;
> >
> > + /* Check that we're looking for nested phis.  */
> > + if (phis == NULL && diamond_minmax_p)
> > +   {
> > + phis = phi_nodes (EDGE_SUCC (bb2, 0)->dest);
> > + e2 = EDGE_SUCC (bb2, 0);
> > +   }
> > +
> 
> instead
> 
>   basic_block merge = diamond_p ? EDGE_SUCC (bb2, 0)->dest : bb2;
>   gimple_seq phis = phi_nodes (merge);
> 

Done. 

> 
> >   phi = single_non_singleton_phi_for_edges (phis, e1, e2);
> >   if (!phi)
> > continue;
> > @@ -329,6 +360,7 @@ tree_ssa_phiopt_worker (bool do_store_elim, bool
> > do_hoist_loads, bool early_p)
> >
> >   gphi *newphi;
> >   if (single_pred_p (bb1)
> > + && !diamond_minmax_p
> >   && (newphi = factor_out_conditional_conversion (e1, e2, phi,
> >   arg0, arg1,
> >   cond_stmt)))
> > @@ -343,20 +375,25 @@ tree_ssa_phiopt_worker (bool do_store_elim,
> bool do_hoist_loads, bool early_p)
> > }
> >
> >   /* Do the replacement of conditional if it can be done.  */
> > - if (!early_p && two_value_replacement (bb, bb1, e2, phi, arg0,
> arg1))
> > + if (!early_p
> > + && !diamond_minmax_p
> > + && two_value_replacement (bb, bb1, e2, phi, arg0, arg1))
> > cfgchanged = true;
> > - else if (match_simplify_replacement (bb, bb1, e1, e2, phi,
> > -  arg0, arg1,
> > -  early_p))
> > + else if (!diamond_minmax_p
> > +  && match_simplify_replacement (bb, bb1, e1, e2, phi,
> > + arg0, arg1, early_p))
> > cfgchanged = true;
> >   else if (!early_p
> > +  && !diamond_minmax_p
> >&& single_pred_p (bb1)
> >&& cond_removal_in_builtin_zero_pattern (bb, bb1, e1,
> e2,
> > phi, arg0, arg1))
> > cfgchanged = true;
> > - else if (minmax_replacement (bb, bb1, e1, e2, phi, arg0, arg1))
> > + else if (minmax_replacement (bb, bb1, bb2, e1, e2, phi, arg0, arg1,
> > +  diamond_minmax_p))
> > cfgchanged = true;
> >   else if (single_pred_p (bb1)
> > +  && !diamond_minmax_p
> >&& spaceship_replacement (bb, bb1, e1, e2, phi, arg0,
> arg1))
> > cfgchanged = true;
> > }
> > @@ -385,7 +422,7 @@ tree_ssa_phiopt_worker (bool do_store_elim, bool
> > do_hoist_loads, bool early_p)
> >
> >  static void
> >  replace_phi_edge_with_variable (basic_block cond_block,
> > -   edge e, gphi *phi, tree new_tree)
> > +   edge e, gphi *phi, tree new_tree, bool
> delete_bb = true)
> >  {
> >basic_block bb = gimple_bb (phi);
> >gimple_stmt_iterator gsi;
> > @@ -428,7 +465,7 @@ replace_phi_edge_with_variable (basic_block
> cond_block,
> >  edge_to_remove = EDGE_SUCC (cond_block, 1);
> >else
> >  edge_to_remove = EDGE_SUCC (cond_block, 0);
> > -  if (EDGE_COUNT (edg

Re: [PATCH]middle-end Use subregs to expand COMPLEX_EXPR to set the lowpart.

2022-07-05 Thread Richard Sandiford via Gcc-patches
Tamar Christina  writes:
>> > so that the multiple_p test is skipped if the structure is undefined.
>> 
>> Actually, we should probably skip the constant_multiple_p test as well.
>> Keeping it would only be meaningful for little-endian.
>> 
>> simplify_gen_subreg should alread do the necessary checks to make sure
>> that the subreg can be formed (via validate_subreg).
>> 
>
> Bootstrapped Regtested on aarch64-none-linux-gnu, x86_64-pc-linux-gnu
> and no issues.
>
> Ok for master?
>
> Thanks,
> Tamar
>
> gcc/ChangeLog:
>
>   * expmed.cc (store_bit_field):
> * expmed.cc (store_bit_field_1): Add parameter that indicates if 
> value is
>   still undefined and if so emit a subreg move instead.
>   (store_integral_bit_field): Likewise.
>   (store_bit_field): Likewise.
>   * expr.h (write_complex_part): Likewise.
>   * expmed.h (store_bit_field): Add new parameter.
>   * builtins.cc (expand_ifn_atomic_compare_exchange_into_call): Use new
>   parameter.
>   (expand_ifn_atomic_compare_exchange): Likewise.
>   * calls.cc (store_unaligned_arguments_into_pseudos): Likewise.
>   * emit-rtl.cc (validate_subreg): Likewise.
>   * expr.cc (emit_group_store): Likewise.
>   (copy_blkmode_from_reg): Likewise.
>   (copy_blkmode_to_reg): Likewise.
>   (clear_storage_hints): Likewise.
>   (write_complex_part):  Likewise.
>   (emit_move_complex_parts): Likewise.
>   (expand_assignment): Likewise.
>   (store_expr): Likewise.
>   (store_field): Likewise.
>   (expand_expr_real_2): Likewise.
>   * ifcvt.cc (noce_emit_move_insn): Likewise.
>   * internal-fn.cc (expand_arith_set_overflow): Likewise.
>   (expand_arith_overflow_result_store): Likewise.
>   (expand_addsub_overflow): Likewise.
>   (expand_neg_overflow): Likewise.
>   (expand_mul_overflow): Likewise.
>   (expand_arith_overflow): Likewise.
>
> gcc/testsuite/ChangeLog:
>
>   * g++.target/aarch64/complex-init.C: New test.
>
> --- inline copy of patch ---
>
> […]
> diff --git a/gcc/testsuite/g++.target/aarch64/complex-init.C 
> b/gcc/testsuite/g++.target/aarch64/complex-init.C
> new file mode 100644
> index 
> ..d3fd3e88d04a87bacf1c4ee74ce25282c6ff81e8
> --- /dev/null
> +++ b/gcc/testsuite/g++.target/aarch64/complex-init.C
> @@ -0,0 +1,40 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2" } */
> +/* { dg-final { check-function-bodies "**" "" "" { target { le } } } } */
> +
> +/*
> +** _Z1fii:
> +** ...
> +**   bfi x0, x1, 32, 32
> +**   ret
> +** ...

Sorry for the test nit, but: it shouldn't be necessary to add ...
after the ret.  Same for the other tests.

OK with that change, thanks.

Richard

> +*/
> +_Complex int f(int a, int b) {
> +_Complex int t = a + b * 1i;
> +return t;
> +}
> +
> +/*
> +** _Z2f2ii:
> +** ...
> +**   bfi x0, x1, 32, 32
> +**   ret
> +** ...
> +*/
> +_Complex int f2(int a, int b) {
> +_Complex int t = {a, b};
> +return t;
> +}
> +
> +/* 
> +** _Z12f_convolutedii:
> +** ...
> +**   bfi x0, x1, 32, 32
> +**   ret
> +** ...
> +*/
> +_Complex int f_convoluted(int a, int b) {
> +_Complex int t = (_Complex int)a;
> +__imag__ t = b;
> +return t;
> +}


[PATCH v3] Enable __memcmpeq after seeing __memcmpeq prototype

2022-07-05 Thread H.J. Lu via Gcc-patches
extern int __memcmpeq (const void *, const void *, size_t);

was was added to GLIBC 2.35.  Expand BUILT_IN_MEMCMP_EQ to __memcmpeq
after seeing __memcmpeq prototype

gcc/

* builtins.cc (expand_builtin): Issue an error for
BUILT_IN___MEMCMPEQ if there is no __memcmpeq prototype.  Expand
BUILT_IN_MEMCMP_EQ to BUILT_IN___MEMCMP_EQ if there is __memcmpeq
prototype.
* builtins.def (BUILT_IN___MEMCMPEQ): New.

gcc/testsuite/

* c-c++-common/memcmpeq-1.c: New test.
* c-c++-common/memcmpeq-2.c: Likewise.
* c-c++-common/memcmpeq-3.c: Likewise.
* c-c++-common/memcmpeq-4.c: Likewise.
* c-c++-common/memcmpeq-5.c: Likewise.
* c-c++-common/memcmpeq-6.c: Likewise.
* c-c++-common/memcmpeq.h: Likewise.
---
 gcc/builtins.cc | 14 +-
 gcc/builtins.def|  3 +++
 gcc/testsuite/c-c++-common/memcmpeq-1.c | 11 +++
 gcc/testsuite/c-c++-common/memcmpeq-2.c | 11 +++
 gcc/testsuite/c-c++-common/memcmpeq-3.c | 11 +++
 gcc/testsuite/c-c++-common/memcmpeq-4.c | 11 +++
 gcc/testsuite/c-c++-common/memcmpeq-5.c | 11 +++
 gcc/testsuite/c-c++-common/memcmpeq-6.c | 10 ++
 gcc/testsuite/c-c++-common/memcmpeq.h   | 11 +++
 9 files changed, 92 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/c-c++-common/memcmpeq-1.c
 create mode 100644 gcc/testsuite/c-c++-common/memcmpeq-2.c
 create mode 100644 gcc/testsuite/c-c++-common/memcmpeq-3.c
 create mode 100644 gcc/testsuite/c-c++-common/memcmpeq-4.c
 create mode 100644 gcc/testsuite/c-c++-common/memcmpeq-5.c
 create mode 100644 gcc/testsuite/c-c++-common/memcmpeq-6.c
 create mode 100644 gcc/testsuite/c-c++-common/memcmpeq.h

diff --git a/gcc/builtins.cc b/gcc/builtins.cc
index e6816d5c865..2254a597bec 100644
--- a/gcc/builtins.cc
+++ b/gcc/builtins.cc
@@ -7395,6 +7395,15 @@ expand_builtin (tree exp, rtx target, rtx subtarget, 
machine_mode mode,
return target;
   break;
 
+case BUILT_IN___MEMCMPEQ:
+  if (!builtin_decl_declared_p (BUILT_IN___MEMCMPEQ))
+   {
+ error ("use of %<__builtin___memcmpeq ()%> without "
+"%<__memcmpeq%> prototype");
+ return const0_rtx;
+   }
+  break;
+
 /* Expand it as BUILT_IN_MEMCMP_EQ first. If not successful, change it
back to a BUILT_IN_STRCMP. Remember to delete the 3rd parameter
when changing it to a strcmp call.  */
@@ -7448,7 +7457,10 @@ expand_builtin (tree exp, rtx target, rtx subtarget, 
machine_mode mode,
return target;
   if (fcode == BUILT_IN_MEMCMP_EQ)
{
- tree newdecl = builtin_decl_explicit (BUILT_IN_MEMCMP);
+ tree newdecl = builtin_decl_explicit
+   (builtin_decl_declared_p (BUILT_IN___MEMCMPEQ)
+? BUILT_IN___MEMCMPEQ
+: BUILT_IN_MEMCMP);
  TREE_OPERAND (exp, 1) = build_fold_addr_expr (newdecl);
}
   break;
diff --git a/gcc/builtins.def b/gcc/builtins.def
index 005976f34e9..95642c6acdf 100644
--- a/gcc/builtins.def
+++ b/gcc/builtins.def
@@ -965,6 +965,9 @@ DEF_BUILTIN_STUB (BUILT_IN_ALLOCA_WITH_ALIGN_AND_MAX, 
"__builtin_alloca_with_ali
equality with zero.  */
 DEF_BUILTIN_STUB (BUILT_IN_MEMCMP_EQ, "__builtin_memcmp_eq")
 
+/* Similar to BUILT_IN_MEMCMP_EQ, but is mapped to __memcmpeq.  */
+DEF_EXT_LIB_BUILTIN (BUILT_IN___MEMCMPEQ, "__memcmpeq", 
BT_FN_INT_CONST_PTR_CONST_PTR_SIZE, ATTR_PURE_NOTHROW_NONNULL_LEAF)
+
 /* An internal version of strcmp/strncmp, used when the result is only 
tested for equality with zero.  */
 DEF_BUILTIN_STUB (BUILT_IN_STRCMP_EQ, "__builtin_strcmp_eq")
diff --git a/gcc/testsuite/c-c++-common/memcmpeq-1.c 
b/gcc/testsuite/c-c++-common/memcmpeq-1.c
new file mode 100644
index 000..14622f0d765
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/memcmpeq-1.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler "__memcmpeq" } } */
+
+#include "memcmpeq.h"
+
+int
+foo (const char *s1, const char *s2, size_t len)
+{
+  return __builtin_memcmp (s1, s2, len) != 0;
+}
diff --git a/gcc/testsuite/c-c++-common/memcmpeq-2.c 
b/gcc/testsuite/c-c++-common/memcmpeq-2.c
new file mode 100644
index 000..f57f279f173
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/memcmpeq-2.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler "__memcmpeq" } } */
+
+#include "memcmpeq.h"
+
+int
+foo (const char *s1, const char *s2, size_t len)
+{
+  return memcmp (s1, s2, len) == 0;
+}
diff --git a/gcc/testsuite/c-c++-common/memcmpeq-3.c 
b/gcc/testsuite/c-c++-common/memcmpeq-3.c
new file mode 100644
index 000..2ca2131c23a
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/memcmpeq-3.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler-not "__memcmpeq" } } */
+
+#include "memcmpeq.h"
+
+int
+foo (const c

Re: [PATCH v2] Enable __memcmpeq after seeing __memcmpeq prototype

2022-07-05 Thread H.J. Lu via Gcc-patches
On Fri, Jul 1, 2022 at 12:51 AM Richard Biener
 wrote:
>
> On Mon, Jun 20, 2022 at 5:44 PM H.J. Lu  wrote:
> >
> > extern int __memcmpeq (const void *, const void *, size_t);
> >
> > was was added to GLIBC 2.35.  Expand BUILT_IN_MEMCMP_EQ to __memcmpeq
> > after seeing __memcmpeq prototype
>
> Can you instead use builtin_decl_declared_p (), see how frontends
> set that via set_builtin_decl_declared_p?

The v3 patch is at

https://gcc.gnu.org/pipermail/gcc-patches/2022-July/597861.html

Thanks.

> > gcc/
> >
> > * builtins.cc (have_memcmpeq_prototype): New.
> > (expand_builtin): Issue an error for BUILT_IN___MEMCMPEQ if
> > there is no __memcmpeq prototype.  Expand BUILT_IN_MEMCMP_EQ
> > to BUILT_IN___MEMCMP_EQ if there is __memcmpeq prototype.
> > * builtins.def (BUILT_IN___MEMCMPEQ): New.
> > * builtins.h (have_memcmpeq_prototype): New.
> >
> > gcc/c/
> >
> > * c-decl.cc (diagnose_mismatched_decls): Set
> > have_memcmpeq_prototype to true after seeing __memcmpeq prototype.
> >
> > gcc/cp/
> >
> > *  decl.cc (duplicate_decls): Set have_memcmpeq_prototype to true
> > after seeing __memcmpeq prototype.
> >
> > gcc/testsuite/
> >
> > * c-c++-common/memcmpeq-1.c: New test.
> > * c-c++-common/memcmpeq-2.c: Likewise.
> > * c-c++-common/memcmpeq-3.c: Likewise.
> > * c-c++-common/memcmpeq-4.c: Likewise.
> > * c-c++-common/memcmpeq-5.c: Likewise.
> > * c-c++-common/memcmpeq-6.c: Likewise.
> > * c-c++-common/memcmpeq.h: Likewise.
> > ---
> >  gcc/builtins.cc | 17 -
> >  gcc/builtins.def|  3 +++
> >  gcc/builtins.h  |  3 +++
> >  gcc/c/c-decl.cc | 25 ++---
> >  gcc/cp/decl.cc  |  5 +
> >  gcc/testsuite/c-c++-common/memcmpeq-1.c | 11 +++
> >  gcc/testsuite/c-c++-common/memcmpeq-2.c | 11 +++
> >  gcc/testsuite/c-c++-common/memcmpeq-3.c | 11 +++
> >  gcc/testsuite/c-c++-common/memcmpeq-4.c | 11 +++
> >  gcc/testsuite/c-c++-common/memcmpeq-5.c | 11 +++
> >  gcc/testsuite/c-c++-common/memcmpeq-6.c | 10 ++
> >  gcc/testsuite/c-c++-common/memcmpeq.h   | 11 +++
> >  12 files changed, 121 insertions(+), 8 deletions(-)
> >  create mode 100644 gcc/testsuite/c-c++-common/memcmpeq-1.c
> >  create mode 100644 gcc/testsuite/c-c++-common/memcmpeq-2.c
> >  create mode 100644 gcc/testsuite/c-c++-common/memcmpeq-3.c
> >  create mode 100644 gcc/testsuite/c-c++-common/memcmpeq-4.c
> >  create mode 100644 gcc/testsuite/c-c++-common/memcmpeq-5.c
> >  create mode 100644 gcc/testsuite/c-c++-common/memcmpeq-6.c
> >  create mode 100644 gcc/testsuite/c-c++-common/memcmpeq.h
> >
> > diff --git a/gcc/builtins.cc b/gcc/builtins.cc
> > index 971b18c3745..96e283e5847 100644
> > --- a/gcc/builtins.cc
> > +++ b/gcc/builtins.cc
> > @@ -104,6 +104,9 @@ builtin_info_type builtin_info[(int)END_BUILTINS];
> >  /* Non-zero if __builtin_constant_p should be folded right away.  */
> >  bool force_folding_builtin_constant_p;
> >
> > +/* True if there is a __memcmpeq prototype.  */
> > +bool have_memcmpeq_prototype;
> > +
> >  static int target_char_cast (tree, char *);
> >  static int apply_args_size (void);
> >  static int apply_result_size (void);
> > @@ -7392,6 +7395,15 @@ expand_builtin (tree exp, rtx target, rtx subtarget, 
> > machine_mode mode,
> > return target;
> >break;
> >
> > +case BUILT_IN___MEMCMPEQ:
> > +  if (!have_memcmpeq_prototype)
> > +   {
> > + error ("use of %<__builtin___memcmpeq ()%> without "
> > +"%<__memcmpeq%> prototype");
> > + return const0_rtx;
> > +   }
> > +  break;
> > +
> >  /* Expand it as BUILT_IN_MEMCMP_EQ first. If not successful, change it
> > back to a BUILT_IN_STRCMP. Remember to delete the 3rd parameter
> > when changing it to a strcmp call.  */
> > @@ -7445,7 +7457,10 @@ expand_builtin (tree exp, rtx target, rtx subtarget, 
> > machine_mode mode,
> > return target;
> >if (fcode == BUILT_IN_MEMCMP_EQ)
> > {
> > - tree newdecl = builtin_decl_explicit (BUILT_IN_MEMCMP);
> > + tree newdecl = builtin_decl_explicit
> > +   (have_memcmpeq_prototype
> > +? BUILT_IN___MEMCMPEQ
> > +: BUILT_IN_MEMCMP);
> >   TREE_OPERAND (exp, 1) = build_fold_addr_expr (newdecl);
> > }
> >break;
> > diff --git a/gcc/builtins.def b/gcc/builtins.def
> > index 005976f34e9..95642c6acdf 100644
> > --- a/gcc/builtins.def
> > +++ b/gcc/builtins.def
> > @@ -965,6 +965,9 @@ DEF_BUILTIN_STUB (BUILT_IN_ALLOCA_WITH_ALIGN_AND_MAX, 
> > "__builtin_alloca_with_ali
> > equality with zero.  */
> >  DEF_BUILTIN_STUB (BUILT_IN_MEMCMP_EQ, "__builtin_memcmp_eq")
> >
> > +/* Similar to BUILT_IN_MEMCMP_EQ, but is mapped to __memcmpeq. 

[committed][wwwdocs] Add notes about and header dependencies

2022-07-05 Thread Jonathan Wakely via Gcc-patches
I backported a change to the  header which meant it no longer
includes , which broke some (incorrect) packages. This
updates the GCC 12 docs to mention it.

Pushed to wwwdocs.

-- >8 --

Also fix missing closing tag for .
---
 htdocs/gcc-12/porting_to.html | 8 
 1 file changed, 8 insertions(+)

diff --git a/htdocs/gcc-12/porting_to.html b/htdocs/gcc-12/porting_to.html
index 079bda30..3badb0cc 100644
--- a/htdocs/gcc-12/porting_to.html
+++ b/htdocs/gcc-12/porting_to.html
@@ -82,6 +82,12 @@ be included explicitly when compiled with GCC 12:
  
   (for std::atomic)
 
+ 
+  (for std::time, std::mktime etc.)
+
+ 
+  (for pthread_create, pthread_mutex_t etc.)
+
 
 
 C++ Standard Library deprecations
@@ -109,6 +115,8 @@ GCC 12 now uses OPERATION as the name of the 
function to
 the CO_REDUCE intrinsic for the pairwise reduction, thus
 conforming to the Fortran 2018 standard.  Previous versions
 used OPERATOR, which conformed to TS 18508.
+
+
 
-- 
2.36.1



[PATCH 1/2] analyzer: show close event for use_after_close diagnostic

2022-07-05 Thread Mir Immad via Gcc-patches
>From be60d5194068355ccdbf832d0de9dbfed1e0b074 Mon Sep 17 00:00:00 2001
From: Immad Mir 
Date: Tue, 5 Jul 2022 21:14:06 +0530
Subject: [PATCH 1/2] analyzer: show close event for use_after_close
diagnostic

This patch saves the "close" event in use_after_close diagnostic
and shows it where possible.

gcc/analyzer/ChangeLog:
* sm-fd.cc (use_after_close): save the "close" event and
show it where possible.

gcc/testsuite/ChangeLog:
* gcc.dg/analyzer/fd-4.c (test_3): change the message note to conform to the
changes in analyzer/sm-fd.cc
(test_4): Likewise.

Signed-off-by: Immad Mir 
---
 gcc/analyzer/sm-fd.cc| 13 +++--
 gcc/testsuite/gcc.dg/analyzer/fd-4.c |  4 ++--
 2 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/gcc/analyzer/sm-fd.cc b/gcc/analyzer/sm-fd.cc
index 4058ac53308..a85c95cc502 100644
--- a/gcc/analyzer/sm-fd.cc
+++ b/gcc/analyzer/sm-fd.cc
@@ -454,7 +454,10 @@ public:
   return label_text::borrow ("opened here");

 if (change.m_new_state == m_sm.m_closed)
+{
+  m_first_close_event = change.m_event_id;
return change.formatted_print ("closed here");
+}

 return fd_diagnostic::describe_state_change (change);
   }
@@ -462,11 +465,17 @@ public:
   label_text
   describe_final_event (const evdesc::final_event &ev) final override
   {
-return ev.formatted_print ("%qE on closed file descriptor %qE here",
-   m_callee_fndecl, m_arg);
+if (m_first_close_event.known_p ())
+  return ev.formatted_print (
+  "%qE on closed file descriptor %qE; %qs was at %@",
m_callee_fndecl,
+  m_arg, "close", &m_first_close_event);
+else
+  return ev.formatted_print ("%qE on closed file descriptor %qE",
+ m_callee_fndecl, m_arg);
   }

 private:
+  diagnostic_event_id_t m_first_close_event;
   const tree m_callee_fndecl;
 };

diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-4.c
b/gcc/testsuite/gcc.dg/analyzer/fd-4.c
index a973704f403..c992db619e7 100644
--- a/gcc/testsuite/gcc.dg/analyzer/fd-4.c
+++ b/gcc/testsuite/gcc.dg/analyzer/fd-4.c
@@ -45,7 +45,7 @@ test_3 (const char *path, void *buf)
 {
 close(fd); /* {dg-message "\\(2\\) closed here"} */
 read(fd, buf, 1); /* { dg-warning "'read' on closed file
descriptor 'fd'" }  */
-/* {dg-message "\\(3\\) 'read' on closed file descriptor 'fd'
here" "" {target *-*-*} .-1 } */
+/* {dg-message "\\(3\\) 'read' on closed file descriptor 'fd';
'close' was at \\(2\\)" "" {target *-*-*} .-1 } */
 }
 }

@@ -57,6 +57,6 @@ test_4 (const char *path, void *buf)
 {
 close(fd); /* {dg-message "\\(2\\) closed here"} */
 write(fd, buf, 1); /* { dg-warning "'write' on closed file
descriptor 'fd'" }  */
-/* {dg-message "\\(3\\) 'write' on closed file descriptor 'fd'
here" "" {target *-*-*} .-1 } */
+/* {dg-message "\\(3\\) 'write' on closed file descriptor 'fd';
'close' was at \\(2\\)" "" {target *-*-*} .-1 } */
 }
 }
-- 
2.25.1


[PATCH 2/2] analyzer: reorder initialization of state m_invalid in sm-fd.cc [PR106184]

2022-07-05 Thread Mir Immad via Gcc-patches
>From 3de908fa0c3e515b49df24460f85924211802d6c Mon Sep 17 00:00:00 2001
From: Immad Mir 
Date: Tue, 5 Jul 2022 21:21:13 +0530
Subject: [PATCH 2/2] analyzer: reorder initialization of state m_invalid in
 sm-fd.cc [PR106184]

This patch reorders the initization of state m_invalid in sm-fd.cc
to conform with standard practice in C++.

gcc/analyzer/ChangeLog:
PR analyzer/106184
* sm-fd.cc (fd_state_machine): Change ordering of intilization
of state m_invalid.

Signed-off-by: Immad Mir 
---
 gcc/analyzer/sm-fd.cc | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/gcc/analyzer/sm-fd.cc b/gcc/analyzer/sm-fd.cc
index a85c95cc502..610261bdde5 100644
--- a/gcc/analyzer/sm-fd.cc
+++ b/gcc/analyzer/sm-fd.cc
@@ -551,11 +551,12 @@ fd_state_machine::fd_state_machine (logger *logger)
   m_unchecked_read_write (add_state ("fd-unchecked-read-write")),
   m_unchecked_read_only (add_state ("fd-unchecked-read-only")),
   m_unchecked_write_only (add_state ("fd-unchecked-write-only")),
-  m_invalid (add_state ("fd-invalid")),
   m_valid_read_write (add_state ("fd-valid-read-write")),
   m_valid_read_only (add_state ("fd-valid-read-only")),
   m_valid_write_only (add_state ("fd-valid-write-only")),
-  m_closed (add_state ("fd-closed")), m_stop (add_state ("fd-stop"))
+  m_invalid (add_state ("fd-invalid")),
+  m_closed (add_state ("fd-closed")),
+  m_stop (add_state ("fd-stop"))
 {
 }

-- 
2.25.1


Re: [PATCH] libstdc++: retry removal of dir entries if dir removal fails

2022-07-05 Thread Alexandre Oliva via Gcc-patches
On Jun 30, 2022, Sebastian Huber  wrote:

> From my point of view this is behaviour is an RTEMS bug. Instead of
> adding tweaks for RTEMS, it would be better to report the issues and
> fix them in RTEMS. It could be also a Newlib issue.

Thanks, I've just filed https://devel.rtems.org/ticket/4674

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


[COMMITTED] Provide a relation verification mechanism.

2022-07-05 Thread Andrew MacLeod via Gcc-patches
the relation oracle works on a purely symbolic basis. It assumes for 
instance that x == x, along with everything in the equivalency set.


With the coming introduction of floating point ranges, we have 
circumstances beyond the symbol relation which can affect the result.  
If the range of X may contain a NaN, then  x != x.


Within ranger, folding these sorts of things is not much of an issue.  
For x == x when we invoke fold_range (==, range x, range x, VREL_EQ) 
that will be dispatched to the floating point version of 
operator_equal() which first checks if either operand has a Nan, and if 
so, ignores the incoming equality relation.


Although there are no current clients of the relation oracle outside of 
ranger, I see the potential need for a mechanism to validate any 
relation returned by the oracle with specific ranges or ssa-names.  I 
don't *THINK* we need this within ranger yet, but haven't been able to 
convince myself 100% yet :-).


This patch adds 2 new API entry points to the oracle:

  relation_kind validate_relation (relation_kind k, tree ssa1, tree ssa2);
  relation_kind validate_relation (relation_kind k, vrange &op1, vrange 
&op2);


They basically do what ranger currently does, takes the relation and 
checks to see if folding the appropriate expression with the relation 
returns the expected [1, 1]


ie  it tries folding     fold_range (r, EQ_EXPR, op1, op2, VREL_EQ)  and 
returns either VREL_EQ if the result is [1, 1], or VREL_VARYING 
otherwise.  so if op1 or op2 had a NaN, then we'd get VREL_VARYING .   
The ssa-name version simply uses a value of VARYING of the approrate type.


Anyway, Ive tested it on all the integer code by having the oracle 
always validate any relation it returns. which bootstraps with no 
regressions on 86_64-pc-linux-gnu.


The default I have checked in does not actually call these new 
routines.  but they are there when we need them now.


Andrew

PS. It also allows x == x to be registered to the oracle, which use to 
trap for no really good reason.
From 1d2aa262482fc9b23201200ca82aa3b8659b072e Mon Sep 17 00:00:00 2001
From: Andrew MacLeod 
Date: Tue, 5 Jul 2022 10:54:26 -0400
Subject: [PATCH] Provide a relation verification mechanism.

Provide a relation oracle API which validates a relation between 2 ranges.
This allows relation queries that are symbolicly true to be overridden
by range specific information.  ie. x == x is true symbolically, but for
floating point a NaN may invalidate this assumption.

	* value-relation.cc (relation_to_code): New vector.
	(relation_oracle::validate_relation): New.
	(set_relation): Allow ssa1 == ssa2 to be registered.
	* value-relation.h (validate_relation): New prototype.
	(query_relation): Make internal variant protected.
---
 gcc/value-relation.cc | 70 +--
 gcc/value-relation.h  | 10 +--
 2 files changed, 75 insertions(+), 5 deletions(-)

diff --git a/gcc/value-relation.cc b/gcc/value-relation.cc
index 85d159f5d96..13ce44199f7 100644
--- a/gcc/value-relation.cc
+++ b/gcc/value-relation.cc
@@ -184,6 +184,71 @@ relation_transitive (relation_kind r1, relation_kind r2)
   return rr_transitive_table[r1][r2];
 }
 
+// This vector maps a relation to the equivalent tree code.
+
+tree_code relation_to_code [VREL_LAST + 1] = {
+  ERROR_MARK, ERROR_MARK, LT_EXPR, LE_EXPR, GT_EXPR, GE_EXPR, EQ_EXPR,
+  NE_EXPR };
+
+// This routine validates that a relation can be applied to a specific set of
+// ranges.  In particular, floating point x == x may not be true if the NaN bit
+// is set in the range.  Symbolically the oracle will determine x == x,
+// but specific range instances may override this.
+// To verify, attempt to fold the relation using the supplied ranges.
+// One would expect [1,1] to be returned, anything else means there is something
+// in the range preventing the relation from applying.
+// If there is no mechanism to verify, assume the relation is acceptable.
+
+relation_kind
+relation_oracle::validate_relation (relation_kind rel, vrange &op1, vrange &op2)
+{
+  // If there is no mapping to a tree code, leave the relation as is.
+  tree_code code = relation_to_code [rel];
+  if (code == ERROR_MARK)
+return rel;
+
+  // Undefined ranges cannot be checked either.
+  if (op1.undefined_p () || op2.undefined_p ())
+return rel;
+
+  tree t1 = op1.type ();
+  tree t2 = op2.type ();
+
+  // If the range types are not compatible, no relation can exist.
+  if (!range_compatible_p (t1, t2))
+return VREL_VARYING;
+
+  // If there is no handler, leave the relation as is.
+  range_op_handler handler (code, t1);
+  if (!handler)
+return rel;
+
+  // If the relation cannot be folded for any reason, leave as is.
+  Value_Range result (boolean_type_node);
+  if (!handler.fold_range (result, boolean_type_node, op1, op2, rel))
+return rel;
+
+  // The expression op1 REL op2 using REL should fold to [1,1].
+  // Any other result means the relation is not verified to be true

Re: [PATCH] libstdc++: testsuite: avoid predictable mkstemp

2022-07-05 Thread Alexandre Oliva via Gcc-patches
On Jul  5, 2022, Jonathan Wakely  wrote:

> The cast itself is fine, but I'd like a comment like "N.B. pid_t is a
> pointer on vxworks" so I don't "simplify" it again.


libstdc++: testsuite: why cast getpid result

Add a comment next to the getpid call to explain why the typecast is
needed.

Regstrapped on x86_64-linux-gnu, will install later today if there's no
objection.


for  libstdc++-v3/ChangeLog

* testsuite/util/testsuite_fs (nonexistent_path): Explain why
we need the typecast.
---
 libstdc++-v3/testsuite/util/testsuite_fs.h |3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/testsuite/util/testsuite_fs.h 
b/libstdc++-v3/testsuite/util/testsuite_fs.h
index 25f8f734dc792..0e28385e99aca 100644
--- a/libstdc++-v3/testsuite/util/testsuite_fs.h
+++ b/libstdc++-v3/testsuite/util/testsuite_fs.h
@@ -162,7 +162,8 @@ namespace __gnu_test
 if (file.length() > 64)
   file.resize(64);
 // The combination of random counter and PID should be unique for a given
-// run of the testsuite.
+// run of the testsuite.  N.B. getpid() returns a pointer type on vxworks
+// in kernel mode.
 file += std::to_string((unsigned long) ::getpid());
 p = std::move(file);
 if (test_fs::exists(p))


-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


Re: [PATCH] libstdc++: testsuite: avoid predictable mkstemp

2022-07-05 Thread Jonathan Wakely via Gcc-patches
On Tue, 5 Jul 2022 at 18:46, Alexandre Oliva  wrote:
>
> On Jul  5, 2022, Jonathan Wakely  wrote:
>
> > The cast itself is fine, but I'd like a comment like "N.B. pid_t is a
> > pointer on vxworks" so I don't "simplify" it again.
>
>
> libstdc++: testsuite: why cast getpid result
>
> Add a comment next to the getpid call to explain why the typecast is
> needed.
>
> Regstrapped on x86_64-linux-gnu, will install later today if there's no
> objection.


Thanks.



[PATCH] c-family: Prevent -Wformat warnings with u8 strings [PR105626]

2022-07-05 Thread Marek Polacek via Gcc-patches
The  thread
seems to have concluded that -Wformat shouldn't warn about

  printf((const char*) u8"test %d\n", 1);

saying "format string is not an array of type 'char'".  This code
is not an aliasing violation, and there are no I/O functions for u8
strings, so the const char * cast is OK and shouldn't be disregarded.

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

PR c++/105626

gcc/c-family/ChangeLog:

* c-format.cc (check_format_arg): Don't emit -Wformat warnings with
u8 strings.

gcc/testsuite/ChangeLog:

* g++.dg/warn/Wformat-char8_t-1.C: New test.
---
 gcc/c-family/c-format.cc  |  3 ++-
 gcc/testsuite/g++.dg/warn/Wformat-char8_t-1.C | 10 ++
 2 files changed, 12 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/warn/Wformat-char8_t-1.C

diff --git a/gcc/c-family/c-format.cc b/gcc/c-family/c-format.cc
index 4559ca3e28f..754780446ba 100644
--- a/gcc/c-family/c-format.cc
+++ b/gcc/c-family/c-format.cc
@@ -1742,7 +1742,8 @@ check_format_arg (void *ctx, tree format_tree,
 }
   tree underlying_type
 = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (format_tree)));
-  if (underlying_type != char_type_node)
+  if (underlying_type != char_type_node
+  && !(flag_char8_t && underlying_type == char8_type_node))
 {
   if (underlying_type == char16_type_node
  || underlying_type == char32_type_node
diff --git a/gcc/testsuite/g++.dg/warn/Wformat-char8_t-1.C 
b/gcc/testsuite/g++.dg/warn/Wformat-char8_t-1.C
new file mode 100644
index 000..ba6f388a210
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wformat-char8_t-1.C
@@ -0,0 +1,10 @@
+// PR c++/105626
+// { dg-do compile { target c++11 } }
+// { dg-options "-Wformat" }
+// { dg-additional-options "-fchar8_t" { target c++17_down } }
+
+int main()
+{
+  __builtin_printf((const char*) u8"test %d\n", 1); // { dg-bogus "format 
string" }
+  return 0;
+}

base-commit: 1d2aa262482fc9b23201200ca82aa3b8659b072e
-- 
2.36.1



[PATCH] analyzer: Fix handling of non-ints inside allocation size checker [PR106181]

2022-07-05 Thread Tim Lange
This patch fixes the ICE reported in PR106181 by Arseny Solokha. With
this patch, the allocation size checker tries to handle floating-point
operands of allocation size arguments. Constant sizes get implicitly
converted and symbolic sizes are handled as long as the floating-point
operand could also be represented as a positive integer. In all other
cases and on unhandled constants, the checker falls back to not
emitting a warning.
Also, I unified the logic on zero byte allocations.

Regression-tested on x86_64 linux.

2022-07-05  Tim Lange  

gcc/analyzer/ChangeLog:

PR analyzer/106181
* region-model.cc (capacity_compatible_with_type):
Can handle non-integer constants now.
(region_model::check_region_size): Adapted to the new signature of
capacity_compatible_with_type.

gcc/testsuite/ChangeLog:

PR analyzer/106181
* gcc.dg/analyzer/allocation-size-1.c: New tests.
* gcc.dg/analyzer/allocation-size-2.c: New tests.
* gcc.dg/analyzer/pr106181.c: New test.

---
 gcc/analyzer/region-model.cc  | 44 ---
 .../gcc.dg/analyzer/allocation-size-1.c   | 29 +++-
 .../gcc.dg/analyzer/allocation-size-2.c   | 22 ++
 gcc/testsuite/gcc.dg/analyzer/pr106181.c  |  7 +++
 4 files changed, 95 insertions(+), 7 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr106181.c

diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index 5d939327e01..e097ecb3c07 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -2904,13 +2904,45 @@ private:
 
 static bool
 capacity_compatible_with_type (tree cst, tree pointee_size_tree,
-  bool is_struct)
+  bool is_struct, bool floor_real)
 {
-  gcc_assert (TREE_CODE (cst) == INTEGER_CST);
   gcc_assert (TREE_CODE (pointee_size_tree) == INTEGER_CST);
-
   unsigned HOST_WIDE_INT pointee_size = TREE_INT_CST_LOW (pointee_size_tree);
-  unsigned HOST_WIDE_INT alloc_size = TREE_INT_CST_LOW (cst);
+
+  unsigned HOST_WIDE_INT alloc_size;
+  switch (TREE_CODE (cst))
+{
+default:
+  /* Assume all unhandled operands are compatible.  */
+  return true;
+case INTEGER_CST:
+  alloc_size = TREE_INT_CST_LOW (cst);
+  break;
+case REAL_CST:
+  {
+   const REAL_VALUE_TYPE *rv = TREE_REAL_CST_PTR (cst);
+   if (floor_real)
+ {
+   /* If the size is constant real at compile-time,
+  we can model the conversion.  */
+   alloc_size = real_to_integer (rv);
+ }
+   else
+ {
+   /* On expressions where the value of one operator isn't
+  representable as an integer or is negative, we give up and
+  just assume that the programmer knows what they are doing.  */
+   HOST_WIDE_INT i;
+   if (real_isneg (rv) || !real_isinteger (rv, &i))
+ return true;
+   alloc_size = i;
+ }
+  }
+  break;
+}
+
+  if (alloc_size == 0)
+return true;
 
   if (is_struct)
 return alloc_size >= pointee_size;
@@ -2920,7 +2952,7 @@ capacity_compatible_with_type (tree cst, tree 
pointee_size_tree,
 static bool
 capacity_compatible_with_type (tree cst, tree pointee_size_tree)
 {
-  return capacity_compatible_with_type (cst, pointee_size_tree, false);
+  return capacity_compatible_with_type (cst, pointee_size_tree, false, false);
 }
 
 /* Checks whether SVAL could be a multiple of SIZE_CST.
@@ -3145,7 +3177,7 @@ region_model::check_region_size (const region *lhs_reg, 
const svalue *rhs_sval,
= as_a  (capacity);
tree cst_cap = cst_cap_sval->get_constant ();
if (!capacity_compatible_with_type (cst_cap, pointee_size_tree,
-   is_struct))
+   is_struct, true))
  ctxt->warn (new dubious_allocation_size (lhs_reg, rhs_reg,
   cst_cap));
   }
diff --git a/gcc/testsuite/gcc.dg/analyzer/allocation-size-1.c 
b/gcc/testsuite/gcc.dg/analyzer/allocation-size-1.c
index 4a78a81d054..1a1c8e75c98 100644
--- a/gcc/testsuite/gcc.dg/analyzer/allocation-size-1.c
+++ b/gcc/testsuite/gcc.dg/analyzer/allocation-size-1.c
@@ -114,4 +114,31 @@ void test_10 (int32_t n)
 {
   char *ptr = malloc (7 * n);
   free (ptr);
-}
\ No newline at end of file
+}
+
+void test_11 ()
+{
+  int32_t *ptr = malloc (3.0); /* { dg-line malloc11 } */
+  free (ptr);  
+  /* { dg-warning "allocated buffer size is not a multiple of the pointee's 
size \\\[CWE-131\\\]" "warning" { target *-*-* } malloc11 } */
+  /* { dg-message "'int32_t \\*' (\\\{aka '(long )?int \\*'\\\})? here; 
'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4'" "note" { target *-*-* 
} malloc11 } */
+}
+
+void test_12 ()
+{
+  int32_t *ptr = malloc (4.0);
+  free (ptr);
+}
+
+void test_13 ()
+{
+  int32_t *ptr = malloc (4.7);
+ 

Re: [PATCH] c-family: Prevent -Wformat warnings with u8 strings [PR105626]

2022-07-05 Thread Jason Merrill via Gcc-patches

On 7/5/22 15:26, Marek Polacek wrote:

The  thread
seems to have concluded that -Wformat shouldn't warn about

   printf((const char*) u8"test %d\n", 1);

saying "format string is not an array of type 'char'".  This code
is not an aliasing violation, and there are no I/O functions for u8
strings, so the const char * cast is OK and shouldn't be disregarded.

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


OK.


PR c++/105626

gcc/c-family/ChangeLog:

* c-format.cc (check_format_arg): Don't emit -Wformat warnings with
u8 strings.

gcc/testsuite/ChangeLog:

* g++.dg/warn/Wformat-char8_t-1.C: New test.
---
  gcc/c-family/c-format.cc  |  3 ++-
  gcc/testsuite/g++.dg/warn/Wformat-char8_t-1.C | 10 ++
  2 files changed, 12 insertions(+), 1 deletion(-)
  create mode 100644 gcc/testsuite/g++.dg/warn/Wformat-char8_t-1.C

diff --git a/gcc/c-family/c-format.cc b/gcc/c-family/c-format.cc
index 4559ca3e28f..754780446ba 100644
--- a/gcc/c-family/c-format.cc
+++ b/gcc/c-family/c-format.cc
@@ -1742,7 +1742,8 @@ check_format_arg (void *ctx, tree format_tree,
  }
tree underlying_type
  = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (format_tree)));
-  if (underlying_type != char_type_node)
+  if (underlying_type != char_type_node
+  && !(flag_char8_t && underlying_type == char8_type_node))
  {
if (underlying_type == char16_type_node
  || underlying_type == char32_type_node
diff --git a/gcc/testsuite/g++.dg/warn/Wformat-char8_t-1.C 
b/gcc/testsuite/g++.dg/warn/Wformat-char8_t-1.C
new file mode 100644
index 000..ba6f388a210
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wformat-char8_t-1.C
@@ -0,0 +1,10 @@
+// PR c++/105626
+// { dg-do compile { target c++11 } }
+// { dg-options "-Wformat" }
+// { dg-additional-options "-fchar8_t" { target c++17_down } }
+
+int main()
+{
+  __builtin_printf((const char*) u8"test %d\n", 1); // { dg-bogus "format 
string" }
+  return 0;
+}

base-commit: 1d2aa262482fc9b23201200ca82aa3b8659b072e




Re: [PATCH] c++: generic targs and identity substitution [PR105956]

2022-07-05 Thread Jason Merrill via Gcc-patches

On 7/5/22 10:06, Patrick Palka wrote:

On Fri, 1 Jul 2022, Jason Merrill wrote:


On 6/29/22 13:42, Patrick Palka wrote:

In r13-1045-gcb7fd1ea85feea I assumed that substitution into generic
DECL_TI_ARGS corresponds to an identity mapping of the given arguments,
and hence its safe to always elide such substitution.  But this PR
demonstrates that such a substitution isn't always the identity mapping,
in particular when there's an ARGUMENT_PACK_SELECT argument, which gets
handled specially during substitution:

* when substituting an APS into a template parameter, we strip the
  APS to its underlying argument;
* and when substituting an APS into a pack expansion, we strip the
  APS to its underlying argument pack.


Ah, right.  For instance, in variadic96.C we have

 10 template < typename... T >
 11 struct derived
 12   : public base< T, derived< T... > >...

so when substituting into the base-specifier, we're approaching it from the
outside in, so when we get to the inner T... we need some way to find the T
pack again.  It might be possible to remove the need for APS by substituting
inner pack expansions before outer ones, which could improve worst-case
complexity, but I don't know how relevant that is in real code; I imagine most
inner pack expansions are as simple as this one.


Aha, that makes sense.




In this testcase, when expanding the pack expansion pattern (idx + Ns)...
with Ns={0,1}, we specialize idx twice, first with Ns=APS<0,{0,1}> and
then Ns=APS<1,{0,1}>.  The DECL_TI_ARGS of idx are the generic template
arguments of the enclosing class template impl, so before r13-1045,
we'd substitute into its DECL_TI_ARGS which gave Ns={0,1} as desired.
But after r13-1045, we elide this substitution and end up attempting to
hash the original Ns argument, an APS, which ICEs.

So this patch partially reverts this part of r13-1045.  I considered
using preserve_args in this case instead, but that'd break the
static_assert in the testcase because preserve_args always strips APS to
its underlying argument, but here we want to strip it to its underlying
argument pack, so we'd incorrectly end up forming the specializations
impl<0>::idx and impl<1>::idx instead of impl<0,1>::idx.

Although we can't elide the substitution into DECL_TI_ARGS in light of
ARGUMENT_PACK_SELECT, it should still be safe to elide template argument
coercion in the case of a non-template decl, which this patch preserves.

It's unfortunate that we need to remove this optimization just because
it doesn't hold for one special tree code.  So this patch implements a
heuristic in tsubst_template_args to avoid allocating a new TREE_VEC if
the substituted elements are identical to those of a level from ARGS.
It turns out that about 30% of all calls to tsubst_template_args benefit
from this optimization, and it reduces memory usage by about 1.5% for
e.g. stdc++.h (relative to r13-1045).  (This is the maybe_reuse stuff,
the rest of the changes to tsubst_template_args are just drive-by
cleanups.)

Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
trunk?  Patch generated with -w to ignore noisy whitespace changes.

PR c++/105956

gcc/cp/ChangeLog:

* pt.cc (tsubst_template_args): Move variable declarations
closer to their first use.  Replace 'orig_t' with 'r'.  Rename
'need_new' to 'const_subst_p'.  Heuristically detect if the
substituted elements are identical to that of a level from
'args' and avoid allocating a new TREE_VEC if so.
(tsubst_decl) : Revert
r13-1045-gcb7fd1ea85feea change for avoiding substitution into
DECL_TI_ARGS, but still avoid coercion in this case.

gcc/testsuite/ChangeLog:

* g++.dg/cpp0x/variadic183.C: New test.
---
   gcc/cp/pt.cc | 113 ++-
   gcc/testsuite/g++.dg/cpp0x/variadic183.C |  14 +++
   2 files changed, 85 insertions(+), 42 deletions(-)
   create mode 100644 gcc/testsuite/g++.dg/cpp0x/variadic183.C

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 8672da123f4..7898834faa6 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -27,6 +27,7 @@ along with GCC; see the file COPYING3.  If not see
Fixed by: C++20 modules.  */
 #include "config.h"
+#define INCLUDE_ALGORITHM // for std::equal
   #include "system.h"
   #include "coretypes.h"
   #include "cp-tree.h"
@@ -13544,17 +13545,22 @@ tsubst_argument_pack (tree orig_arg, tree args,
tsubst_flags_t complain,
   tree
   tsubst_template_args (tree t, tree args, tsubst_flags_t complain, tree
in_decl)
   {
-  tree orig_t = t;
-  int len, need_new = 0, i, expanded_len_adjust = 0, out;
-  tree *elts;
-
 if (t == error_mark_node)
   return error_mark_node;
   -  len = TREE_VEC_LENGTH (t);
-  elts = XALLOCAVEC (tree, len);
+  const int len = TREE_VEC_LENGTH (t);
+  tree *elts = XALLOCAVEC (tree, len);
+  int expanded_len_adjust = 0;
   -  for (i = 0; i < len; i++)
+  /* True iff no element of T

[PATCH] Fortran: error recovery simplifying PACK with invalid arguments [PR106049]

2022-07-05 Thread Harald Anlauf via Gcc-patches
Dear all,

poor error recovery while trying to simplify intrinsics with given
invalid arguments seems to be a recurrent theme in testcases submitted
by Gerhard.  In the present case, simplification of PACK() chokes on
the array argument being a bad decl.

The most general approach that came to my mind is to modify function
is_constant_array_expr: when the declared shape of the array indicates
a size greater than zero, but the constructor is missing or empty,
then something bad may have happened, and the array cannot be
considered constant.  We thus punt on simplification of something
that cannot be simplified.  With some luck, this might prevent issues
in similar cases elsewhere...

Regtested on x86_64-pc-linux-gnu.  OK for mainline?

Thanks,
Harald

From b70a225cd9ac83cd182938bb8019f9138f85b222 Mon Sep 17 00:00:00 2001
From: Harald Anlauf 
Date: Tue, 5 Jul 2022 22:20:05 +0200
Subject: [PATCH] Fortran: error recovery simplifying PACK with invalid
 arguments [PR106049]

gcc/fortran/ChangeLog:

	PR fortran/106049
	* simplify.cc (is_constant_array_expr): A non-zero-sized constant
	array shall have a non-empty constructor.  When the constructor is
	empty or missing, treat as non-constant.

gcc/testsuite/ChangeLog:

	PR fortran/106049
	* gfortran.dg/pack_simplify_1.f90: New test.
---
 gcc/fortran/simplify.cc   | 12 
 gcc/testsuite/gfortran.dg/pack_simplify_1.f90 | 15 +++
 2 files changed, 27 insertions(+)
 create mode 100644 gcc/testsuite/gfortran.dg/pack_simplify_1.f90

diff --git a/gcc/fortran/simplify.cc b/gcc/fortran/simplify.cc
index ab59fbca622..fb725994653 100644
--- a/gcc/fortran/simplify.cc
+++ b/gcc/fortran/simplify.cc
@@ -233,6 +233,18 @@ is_constant_array_expr (gfc_expr *e)
   if (e->expr_type != EXPR_ARRAY || !gfc_is_constant_expr (e))
 return false;

+  /* A non-zero-sized constant array shall have a non-empty constructor.  */
+  if (e->rank > 0 && e->shape != NULL && e->value.constructor == NULL)
+{
+  mpz_init_set_ui (size, 1);
+  for (int j = 0; j < e->rank; j++)
+	mpz_mul (size, size, e->shape[j]);
+  bool not_size0 = (mpz_cmp_si (size, 0) != 0);
+  mpz_clear (size);
+  if (not_size0)
+	return false;
+}
+
   for (c = gfc_constructor_first (e->value.constructor);
c; c = gfc_constructor_next (c))
 if (c->expr->expr_type != EXPR_CONSTANT
diff --git a/gcc/testsuite/gfortran.dg/pack_simplify_1.f90 b/gcc/testsuite/gfortran.dg/pack_simplify_1.f90
new file mode 100644
index 000..06bc55a14f3
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pack_simplify_1.f90
@@ -0,0 +1,15 @@
+! { dg-do compile }
+! PR fortran/106049 - ICE in gfc_simplify_pack
+! Contributed by G.Steinmetz
+
+program p
+  type t
+  end type
+  logical, parameter :: m(0) = [ logical :: ]
+  type(t), parameter :: a(0) = [ t :: ]
+  type(t), parameter :: b(1) = [ t()  ]
+  type(t), parameter :: c(1) = [ t :: ]! { dg-error "Different shape" }
+  type(t), parameter :: d(0) = pack(a, m)
+  type(t), parameter :: e(1) = pack(b, [.true.])
+  type(t), parameter :: f(1) = pack(c, [.true.])
+end
--
2.35.3



Re: [PATCH] c++, v3: Add support for __real__/__imag__ modifications in constant expressions [PR88174]

2022-07-05 Thread Jason Merrill via Gcc-patches

On 7/4/22 11:50, Jakub Jelinek wrote:

On Mon, Jun 27, 2022 at 06:31:18PM +0200, Jakub Jelinek via Gcc-patches wrote:



Hmm, why do we need to handle complex in the !preeval case?  I'd think we
want to preevaluate all complex values or components thereof.



Because the late evaluation of the initializer could have touched
the destination, so we need to reevaluate it.
Same reason why we call get_or_insert_ctor_field again in the second
loop as we call it in the first loop.


But preeval should always be true, so we'd never reach the new handling 
in the if (!preeval) block.  Certainly the new testcase doesn't exercise 
this code.



If it would help, I could move that repeated part into:



This seems like it needs to come before the ctors loop, so that these flags
can be propagated out to enclosing constructors.


I could indeed move this in between
   bool c = TREE_CONSTANT (init);
   bool s = TREE_SIDE_EFFECTS (init);
and
   if (!c || s || activated_union_member_p)
and update c and s from *cexpr flags.


Here is it in patch form, so far lightly tested, ok for trunk if it passes
full bootstrap/regtest?

2022-07-04  Jakub Jelinek  

PR c++/88174
* constexpr.cc (canonicalize_complex_to_complex_expr): New function.
(cxx_eval_store_expression): Handle REALPART_EXPR and IMAGPART_EXPR.
Change ctors from releasing_vec to auto_vec, adjust all uses.

* g++.dg/cpp1y/constexpr-complex1.C: New test.

--- gcc/cp/constexpr.cc.jj  2022-07-04 12:26:18.147053851 +0200
+++ gcc/cp/constexpr.cc 2022-07-04 17:35:53.100556949 +0200
@@ -5640,6 +5640,26 @@ modifying_const_object_p (tree_code code
return false;
  }
  
+/* Helper of cxx_eval_store_expression, turn a COMPLEX_CST or

+   empty no clearing CONSTRUCTOR into a COMPLEX_EXPR.  */
+
+static tree
+canonicalize_complex_to_complex_expr (tree t)
+{
+  if (TREE_CODE (t) == COMPLEX_CST)
+t = build2 (COMPLEX_EXPR, TREE_TYPE (t),
+   TREE_REALPART (t), TREE_IMAGPART (t));
+  else if (TREE_CODE (t) == CONSTRUCTOR
+  && CONSTRUCTOR_NELTS (t) == 0
+  && CONSTRUCTOR_NO_CLEARING (t))
+{
+  tree r = build_constructor (TREE_TYPE (TREE_TYPE (t)), NULL);
+  CONSTRUCTOR_NO_CLEARING (r) = 1;
+  t = build2 (COMPLEX_EXPR, TREE_TYPE (t), r, r);
+}
+  return t;
+}
+
  /* Evaluate an INIT_EXPR or MODIFY_EXPR.  */
  
  static tree

@@ -5726,6 +5746,20 @@ cxx_eval_store_expression (const constex
  }
  break;
  
+	case REALPART_EXPR:

+ gcc_assert (probe == target);
+ vec_safe_push (refs, probe);
+ vec_safe_push (refs, TREE_TYPE (probe));
+ probe = TREE_OPERAND (probe, 0);
+ break;
+
+   case IMAGPART_EXPR:
+ gcc_assert (probe == target);
+ vec_safe_push (refs, probe);
+ vec_safe_push (refs, TREE_TYPE (probe));
+ probe = TREE_OPERAND (probe, 0);
+ break;
+
default:
  if (evaluated)
object = probe;
@@ -5764,7 +5798,8 @@ cxx_eval_store_expression (const constex
type = TREE_TYPE (object);
bool no_zero_init = true;
  
-  releasing_vec ctors, indexes;

+  auto_vec ctors;
+  releasing_vec indexes;
auto_vec index_pos_hints;
bool activated_union_member_p = false;
bool empty_base = false;
@@ -5804,14 +5839,26 @@ cxx_eval_store_expression (const constex
  *valp = ary_ctor;
}
  
-  /* If the value of object is already zero-initialized, any new ctors for

-subobjects will also be zero-initialized.  */
-  no_zero_init = CONSTRUCTOR_NO_CLEARING (*valp);
-
enum tree_code code = TREE_CODE (type);
tree reftype = refs->pop();
tree index = refs->pop();
  
+  if (code == COMPLEX_TYPE)

+   {
+ *valp = canonicalize_complex_to_complex_expr (*valp);
+ gcc_assert (TREE_CODE (*valp) == COMPLEX_EXPR);
+ ctors.safe_push (valp);
+ vec_safe_push (indexes, index);
+ valp = &TREE_OPERAND (*valp, TREE_CODE (index) == IMAGPART_EXPR);
+ gcc_checking_assert (refs->is_empty ());
+ type = reftype;
+ break;
+   }
+
+  /* If the value of object is already zero-initialized, any new ctors for
+subobjects will also be zero-initialized.  */
+  no_zero_init = CONSTRUCTOR_NO_CLEARING (*valp);
+
if (code == RECORD_TYPE && is_empty_field (index))
/* Don't build a sub-CONSTRUCTOR for an empty base or field, as they
   have no data and might have an offset lower than previously declared
@@ -5854,7 +5901,7 @@ cxx_eval_store_expression (const constex
  no_zero_init = true;
}
  
-  vec_safe_push (ctors, *valp);

+  ctors.safe_push (valp);
vec_safe_push (indexes, index);
  
constructor_elt *cep

@@ -5916,11 +5963,11 @@ cxx_eval_store_expression (const constex
 semantics are not applied on an object under construction.
 They come into effect when the constructor for the mos

Re: [PATCH 1/2] analyzer: show close event for use_after_close diagnostic

2022-07-05 Thread David Malcolm via Gcc-patches
On Tue, 2022-07-05 at 23:07 +0530, Mir Immad wrote:

[...snip...]

>  gcc/analyzer/sm-fd.cc    | 13 +++--
>  gcc/testsuite/gcc.dg/analyzer/fd-4.c |  4 ++--
>  2 files changed, 13 insertions(+), 4 deletions(-)
> 
> diff --git a/gcc/analyzer/sm-fd.cc b/gcc/analyzer/sm-fd.cc
> index 4058ac53308..a85c95cc502 100644
> --- a/gcc/analyzer/sm-fd.cc
> +++ b/gcc/analyzer/sm-fd.cc
> @@ -454,7 +454,10 @@ public:
>    return label_text::borrow ("opened here");
> 
>  if (change.m_new_state == m_sm.m_closed)
> +    {
> +  m_first_close_event = change.m_event_id;
>     return change.formatted_print ("closed here");
> +    }

Looks like the indentation isn't quite right here, or did the patch get
mangled during the emailing process?

[...snip...]


Otherwise, the patch looks good.

Thanks
Dave



Re: [PATCH 2/2] analyzer: reorder initialization of state m_invalid in sm-fd.cc [PR106184]

2022-07-05 Thread David Malcolm via Gcc-patches
On Tue, 2022-07-05 at 23:08 +0530, Mir Immad wrote:
> From 3de908fa0c3e515b49df24460f85924211802d6c Mon Sep 17 00:00:00
> 2001
> From: Immad Mir 
> Date: Tue, 5 Jul 2022 21:21:13 +0530
> Subject: [PATCH 2/2] analyzer: reorder initialization of state
> m_invalid in
>  sm-fd.cc [PR106184]
> 
> This patch reorders the initization of state m_invalid in sm-fd.cc
> to conform with standard practice in C++.
> 
> gcc/analyzer/ChangeLog:
> PR analyzer/106184
> * sm-fd.cc (fd_state_machine): Change ordering of intilization
> of state m_invalid.

Nit: "intilization" -> "intialization".

OK for trunk

Thanks
Dave



Re: [PATCH RFA] ubsan: do return check with -fsanitize=unreachable

2022-07-05 Thread Jason Merrill via Gcc-patches

On 6/29/22 13:26, Jakub Jelinek wrote:

On Wed, Jun 29, 2022 at 12:42:04PM -0400, Jason Merrill wrote:

The usual case is that people just use -fsanitize=undefined
and get both return and unreachable sanitization, for fall through
into end of functions returning non-void done through return sanitization.

In the rare case people use something different like
-fsanitize=undefined -fno-sanitize=return
or
-fsanitize=unreachable
etc., they presumably don't want the fall through from end of function
diagnosed at runtime.


I disagree with this assumption for the second case; it seems much more
likely to me that the user just wasn't thinking about needing to also
mention return.  Missing return is a logical subset of unreachable; if we
sanitize all the other __builtin_unreachable introduced by the compiler, why
in the world would we want to leave out this one that is such a frequent
error?


UBSan was initially implemented in LLVM and our -fsanitize= options try to
match where possible what they do.
And their behavior is too that return and unreachable are separate
sanitizers, fallthrough from function return is sanitized only for the
former, they apparently at -O0 implement something like -funreachable-traps
(but not at -Og) and emit a trap there (regardless of
-fsanitize=unreachable), for -O1 and higher they act as if non-sanitized
__builtin_unreachable () is in there regardless of -fsanitize=unreachable.


Hmm, does clang only sanitize explicit calls to __builtin_unreachable?


It would be strange to diverge from this without a strong reason.
The fact that we use __builtin_unreachable for the function ends is just our
implementation detail and when we'd report that to users, they'd just be
confused on what's going on.  With -fsanitize=return they are told what
happens.


Full -fsanitize=undefined is much higher overhead than just
-fsanitize=unreachable, which introduces no extra checks.  And adding return
checking to unreachable is essentially zero overhead.  I can't imagine any
reason to want to check unreachable points EXCEPT for missing return.


-fsanitize=unreachable isn't zero overhead, it will force evaluation of all
the conditionals guarding it and preparation of arguments for it etc.





Re: [PATCH] c++, v3: Add support for __real__/__imag__ modifications in constant expressions [PR88174]

2022-07-05 Thread Jakub Jelinek via Gcc-patches
On Tue, Jul 05, 2022 at 04:44:41PM -0400, Jason Merrill wrote:
> On 7/4/22 11:50, Jakub Jelinek wrote:
> > On Mon, Jun 27, 2022 at 06:31:18PM +0200, Jakub Jelinek via Gcc-patches 
> > wrote:
> 
> > > > Hmm, why do we need to handle complex in the !preeval case?  I'd think 
> > > > we
> > > > want to preevaluate all complex values or components thereof.
> 
> > > Because the late evaluation of the initializer could have touched
> > > the destination, so we need to reevaluate it.
> > > Same reason why we call get_or_insert_ctor_field again in the second
> > > loop as we call it in the first loop.
> 
> But preeval should always be true, so we'd never reach the new handling in
> the if (!preeval) block.  Certainly the new testcase doesn't exercise this
> code.

Ah, you're right, in the complex case SCALAR_TYPE_P (type) has to be true
because it is COMPLEX_TYPE and so preeval must be true.
I'll rework the patch then.

Jakub



[r13-1509 Regression] FAIL: gcc.target/i386/pr65105-5.c scan-assembler ptest on Linux/x86_64

2022-07-05 Thread skpandey--- via Gcc-patches
On Linux/x86_64,

c73e8d45ca0111f51d7187641963df97f5c9c63f is the first bad commit
commit c73e8d45ca0111f51d7187641963df97f5c9c63f
Author: Roger Sayle 
Date:   Tue Jul 5 18:06:13 2022 +0100

Doubleword version of and;cmp to not;test optimization on x86.

caused

FAIL: gcc.target/i386/pr65105-5.c scan-assembler pandn
FAIL: gcc.target/i386/pr65105-5.c scan-assembler ptest

with GCC configured with

../../gcc/configure 
--prefix=/local/skpandey/gccwork/toolwork/gcc-bisect-master/master/r13-1509/usr 
--enable-clocale=gnu --with-system-zlib --with-demangler-in-ld 
--with-fpmath=sse --enable-languages=c,c++,fortran --enable-cet --without-isl 
--enable-libmpx x86_64-linux --disable-bootstrap

To reproduce:

$ cd {build_dir}/gcc && make check 
RUNTESTFLAGS="i386.exp=gcc.target/i386/pr65105-5.c --target_board='unix{-m32}'"
$ cd {build_dir}/gcc && make check 
RUNTESTFLAGS="i386.exp=gcc.target/i386/pr65105-5.c --target_board='unix{-m32\ 
-march=cascadelake}'"

(Please do not reply to this email, for question about this report, contact me 
at skpgkp2 at gmail dot com)


Floating-point allocation sizes? (was Re: [PATCH] analyzer: Fix handling of non-ints inside allocation size checker [PR106181])

2022-07-05 Thread David Malcolm via Gcc-patches
On Tue, 2022-07-05 at 21:49 +0200, Tim Lange wrote:
> This patch fixes the ICE reported in PR106181 by Arseny Solokha. With
> this patch, the allocation size checker tries to handle floating-point
> operands of allocation size arguments. Constant sizes get implicitly
> converted and symbolic sizes are handled as long as the floating-point
> operand could also be represented as a positive integer. In all other
> cases and on unhandled constants, the checker falls back to not
> emitting a warning.
> Also, I unified the logic on zero byte allocations.

Hi Tim

Thanks for the patch.

We definitely don't want to crash, but my "gut reaction" to the
testsuite examples was that we ought to be warning on them - using
floating point when calculating an allocation size seems like asking
for trouble.

In particular test_16's:
  int32_t *ptr = malloc (n * 3.1);
feels to me like it deserves a warning.  I suppose it could be valid if
n is a multiple of 40 (so that the buffer is a multiple of 31 * 4 and
thus a multiple of 4), for small enough n that we don't lose precision,
but that code seems very questionable - the comment says "just assume
that the programmer knows what they are doing", but I think anyone
using -fanalyzer is opting-in to have more fussy checking and would
probably want to be warned about such code.

I also wondered what happens on NAN, with e.g.

#include 

void test_nan (void)
{
  int *p = malloc (NAN * sizeof (int));
}

but we issue -Woverflow on that.

I'm thinking that perhaps we should have a new warning for floating
point buffer size calculations, though I'm not yet sure exactly how it
should work and how fussy it should be (e.g. complain about floating
point calculations vs complain about *any* floating point used as a
buffer size, etc). 

Does anyone know of real world code that uses floating point in buffer-
size calculations?  (updating Subject accordingly)  Is there code out
there that does this?  It seems broken to me, but maybe there's a valid
use-case that I can't think of.

The closest such rule I can think of is CERT-C's 
"FLP02-C. Avoid using floating-point numbers when precise computation
is needed":
https://wiki.sei.cmu.edu/confluence/display/c/FLP02-C.+Avoid+using+floating-point+numbers+when+precise+computation+is+needed


Dave


> 
> Regression-tested on x86_64 linux.
> 
> 2022-07-05  Tim Lange  
> 
> gcc/analyzer/ChangeLog:
> 
> PR analyzer/106181
> * region-model.cc (capacity_compatible_with_type):
> Can handle non-integer constants now.
> (region_model::check_region_size): Adapted to the new signature
> of
> capacity_compatible_with_type.
> 
> gcc/testsuite/ChangeLog:
> 
> PR analyzer/106181
> * gcc.dg/analyzer/allocation-size-1.c: New tests.
> * gcc.dg/analyzer/allocation-size-2.c: New tests.
> * gcc.dg/analyzer/pr106181.c: New test.
> 
> ---
>  gcc/analyzer/region-model.cc  | 44 ---
>  .../gcc.dg/analyzer/allocation-size-1.c   | 29 +++-
>  .../gcc.dg/analyzer/allocation-size-2.c   | 22 ++
>  gcc/testsuite/gcc.dg/analyzer/pr106181.c  |  7 +++
>  4 files changed, 95 insertions(+), 7 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr106181.c
> 
> diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-
> model.cc
> index 5d939327e01..e097ecb3c07 100644
> --- a/gcc/analyzer/region-model.cc
> +++ b/gcc/analyzer/region-model.cc
> @@ -2904,13 +2904,45 @@ private:
>  
>  static bool
>  capacity_compatible_with_type (tree cst, tree pointee_size_tree,
> -  bool is_struct)
> +  bool is_struct, bool floor_real)
>  {
> -  gcc_assert (TREE_CODE (cst) == INTEGER_CST);
>    gcc_assert (TREE_CODE (pointee_size_tree) == INTEGER_CST);
> -
>    unsigned HOST_WIDE_INT pointee_size = TREE_INT_CST_LOW
> (pointee_size_tree);
> -  unsigned HOST_WIDE_INT alloc_size = TREE_INT_CST_LOW (cst);
> +
> +  unsigned HOST_WIDE_INT alloc_size;
> +  switch (TREE_CODE (cst))
> +    {
> +    default:
> +  /* Assume all unhandled operands are compatible.  */
> +  return true;
> +    case INTEGER_CST:
> +  alloc_size = TREE_INT_CST_LOW (cst);
> +  break;
> +    case REAL_CST:
> +  {
> +   const REAL_VALUE_TYPE *rv = TREE_REAL_CST_PTR (cst);
> +   if (floor_real)
> + {
> +   /* If the size is constant real at compile-time,
> +  we can model the conversion.  */
> +   alloc_size = real_to_integer (rv);
> + }
> +   else
> + {
> +   /* On expressions where the value of one operator isn't
> +  representable as an integer or is negative, we give up
> and
> +  just assume that the programmer knows what they are
> doing.  */
> +   HOST_WIDE_INT i;
> +   if (real_isneg (rv) || !real_isinteger (rv, &i))
> + return true;
> +   alloc_size = i;
> + }
> +  }
> +

Re: Floating-point allocation sizes? (was Re: [PATCH] analyzer: Fix handling of non-ints inside allocation size checker [PR106181])

2022-07-05 Thread Prathamesh Kulkarni via Gcc-patches
On Wed, 6 Jul 2022 at 03:08, David Malcolm via Gcc-patches
 wrote:
>
> On Tue, 2022-07-05 at 21:49 +0200, Tim Lange wrote:
> > This patch fixes the ICE reported in PR106181 by Arseny Solokha. With
> > this patch, the allocation size checker tries to handle floating-point
> > operands of allocation size arguments. Constant sizes get implicitly
> > converted and symbolic sizes are handled as long as the floating-point
> > operand could also be represented as a positive integer. In all other
> > cases and on unhandled constants, the checker falls back to not
> > emitting a warning.
> > Also, I unified the logic on zero byte allocations.
>
> Hi Tim
>
> Thanks for the patch.
>
> We definitely don't want to crash, but my "gut reaction" to the
> testsuite examples was that we ought to be warning on them - using
> floating point when calculating an allocation size seems like asking
> for trouble.
>
> In particular test_16's:
>   int32_t *ptr = malloc (n * 3.1);
> feels to me like it deserves a warning.  I suppose it could be valid if
> n is a multiple of 40 (so that the buffer is a multiple of 31 * 4 and
> thus a multiple of 4), for small enough n that we don't lose precision,
> but that code seems very questionable - the comment says "just assume
> that the programmer knows what they are doing", but I think anyone
> using -fanalyzer is opting-in to have more fussy checking and would
> probably want to be warned about such code.
>
> I also wondered what happens on NAN, with e.g.
>
> #include 
>
> void test_nan (void)
> {
>   int *p = malloc (NAN * sizeof (int));
> }
>
> but we issue -Woverflow on that.
>
> I'm thinking that perhaps we should have a new warning for floating
> point buffer size calculations, though I'm not yet sure exactly how it
> should work and how fussy it should be (e.g. complain about floating
> point calculations vs complain about *any* floating point used as a
> buffer size, etc).
Hi David,
For the former, I was wondering if it'd be a good idea to complain if
alloc_size is floating type,
and floor(alloc_size) != alloc_size ?
So we warn for:
int *p = malloc(4.5);
but not for
int *p = malloc(4.0);

For the latter, I guess -Wconversion should be sufficient ?

Thanks,
Prathamesh
>
> Does anyone know of real world code that uses floating point in buffer-
> size calculations?  (updating Subject accordingly)  Is there code out
> there that does this?  It seems broken to me, but maybe there's a valid
> use-case that I can't think of.
>
> The closest such rule I can think of is CERT-C's
> "FLP02-C. Avoid using floating-point numbers when precise computation
> is needed":
> https://wiki.sei.cmu.edu/confluence/display/c/FLP02-C.+Avoid+using+floating-point+numbers+when+precise+computation+is+needed
>
>
> Dave
>
>
> >
> > Regression-tested on x86_64 linux.
> >
> > 2022-07-05  Tim Lange  
> >
> > gcc/analyzer/ChangeLog:
> >
> > PR analyzer/106181
> > * region-model.cc (capacity_compatible_with_type):
> > Can handle non-integer constants now.
> > (region_model::check_region_size): Adapted to the new signature
> > of
> > capacity_compatible_with_type.
> >
> > gcc/testsuite/ChangeLog:
> >
> > PR analyzer/106181
> > * gcc.dg/analyzer/allocation-size-1.c: New tests.
> > * gcc.dg/analyzer/allocation-size-2.c: New tests.
> > * gcc.dg/analyzer/pr106181.c: New test.
> >
> > ---
> >  gcc/analyzer/region-model.cc  | 44 ---
> >  .../gcc.dg/analyzer/allocation-size-1.c   | 29 +++-
> >  .../gcc.dg/analyzer/allocation-size-2.c   | 22 ++
> >  gcc/testsuite/gcc.dg/analyzer/pr106181.c  |  7 +++
> >  4 files changed, 95 insertions(+), 7 deletions(-)
> >  create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr106181.c
> >
> > diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-
> > model.cc
> > index 5d939327e01..e097ecb3c07 100644
> > --- a/gcc/analyzer/region-model.cc
> > +++ b/gcc/analyzer/region-model.cc
> > @@ -2904,13 +2904,45 @@ private:
> >
> >  static bool
> >  capacity_compatible_with_type (tree cst, tree pointee_size_tree,
> > -  bool is_struct)
> > +  bool is_struct, bool floor_real)
> >  {
> > -  gcc_assert (TREE_CODE (cst) == INTEGER_CST);
> >gcc_assert (TREE_CODE (pointee_size_tree) == INTEGER_CST);
> > -
> >unsigned HOST_WIDE_INT pointee_size = TREE_INT_CST_LOW
> > (pointee_size_tree);
> > -  unsigned HOST_WIDE_INT alloc_size = TREE_INT_CST_LOW (cst);
> > +
> > +  unsigned HOST_WIDE_INT alloc_size;
> > +  switch (TREE_CODE (cst))
> > +{
> > +default:
> > +  /* Assume all unhandled operands are compatible.  */
> > +  return true;
> > +case INTEGER_CST:
> > +  alloc_size = TREE_INT_CST_LOW (cst);
> > +  break;
> > +case REAL_CST:
> > +  {
> > +   const REAL_VALUE_TYPE *rv = TREE_REAL_CST_PTR (cst);
> > +   if (floor_real)
> > + {
> > +   /* If the size

Re: Floating-point allocation sizes? (was Re: [PATCH] analyzer: Fix handling of non-ints inside allocation size checker [PR106181])

2022-07-05 Thread Tim Lange




On Tue, Jul 5 2022 at 05:37:46 PM -0400, David Malcolm 
 wrote:

On Tue, 2022-07-05 at 21:49 +0200, Tim Lange wrote:
 This patch fixes the ICE reported in PR106181 by Arseny Solokha. 
With
 this patch, the allocation size checker tries to handle 
floating-point

 operands of allocation size arguments. Constant sizes get implicitly
 converted and symbolic sizes are handled as long as the 
floating-point
 operand could also be represented as a positive integer. In all 
other

 cases and on unhandled constants, the checker falls back to not
 emitting a warning.
 Also, I unified the logic on zero byte allocations.


Hi Tim

Thanks for the patch.

We definitely don't want to crash, but my "gut reaction" to the
testsuite examples was that we ought to be warning on them - using
floating point when calculating an allocation size seems like asking
for trouble.

In particular test_16's:
  int32_t *ptr = malloc (n * 3.1);
feels to me like it deserves a warning.  I suppose it could be valid 
if

n is a multiple of 40 (so that the buffer is a multiple of 31 * 4 and
thus a multiple of 4), for small enough n that we don't lose 
precision,

but that code seems very questionable - the comment says "just assume
that the programmer knows what they are doing", but I think anyone
using -fanalyzer is opting-in to have more fussy checking and would
probably want to be warned about such code.
While fixing that case, I thought what sane person would think of using 
floating-point arithmetic here. The main reason why I chose to give up 
here instead of complain was because the checker can't know the result 
and it is strange enough such that it might be deliberately.
In that sense, we could also talk about allocating 0 bytes. What 
happens there seems to be undefined behavior and 
implementation-specific. I've again decided to say that allocating 0 
bytes is strange enough that it must be deliberately. The same standard 
you've linked also has a article about that case [0]. If all readers 
can't thing of any use case, I can certainly rework that patch to warn 
on such allocations.


- Tim

[0] 
https://wiki.sei.cmu.edu/confluence/display/c/MEM04-C.+Beware+of+zero-length+allocations


I also wondered what happens on NAN, with e.g.

#include 

void test_nan (void)
{
  int *p = malloc (NAN * sizeof (int));
}

but we issue -Woverflow on that.

I'm thinking that perhaps we should have a new warning for floating
point buffer size calculations, though I'm not yet sure exactly how it
should work and how fussy it should be (e.g. complain about floating
point calculations vs complain about *any* floating point used as a
buffer size, etc).

Does anyone know of real world code that uses floating point in 
buffer-

size calculations?  (updating Subject accordingly)  Is there code out
there that does this?  It seems broken to me, but maybe there's a 
valid

use-case that I can't think of.

The closest such rule I can think of is CERT-C's
"FLP02-C. Avoid using floating-point numbers when precise computation
is needed":
https://wiki.sei.cmu.edu/confluence/display/c/FLP02-C.+Avoid+using+floating-point+numbers+when+precise+computation+is+needed


Dave




 Regression-tested on x86_64 linux.

 2022-07-05  Tim Lange  

 gcc/analyzer/ChangeLog:

 PR analyzer/106181
 * region-model.cc (capacity_compatible_with_type):
 Can handle non-integer constants now.
 (region_model::check_region_size): Adapted to the new 
signature

 of
 capacity_compatible_with_type.

 gcc/testsuite/ChangeLog:

 PR analyzer/106181
 * gcc.dg/analyzer/allocation-size-1.c: New tests.
 * gcc.dg/analyzer/allocation-size-2.c: New tests.
 * gcc.dg/analyzer/pr106181.c: New test.

 ---
  gcc/analyzer/region-model.cc  | 44 
---

  .../gcc.dg/analyzer/allocation-size-1.c   | 29 +++-
  .../gcc.dg/analyzer/allocation-size-2.c   | 22 ++
  gcc/testsuite/gcc.dg/analyzer/pr106181.c  |  7 +++
  4 files changed, 95 insertions(+), 7 deletions(-)
  create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr106181.c

 diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-
 model.cc
 index 5d939327e01..e097ecb3c07 100644
 --- a/gcc/analyzer/region-model.cc
 +++ b/gcc/analyzer/region-model.cc
 @@ -2904,13 +2904,45 @@ private:

  static bool
  capacity_compatible_with_type (tree cst, tree pointee_size_tree,
 -  bool is_struct)
 +  bool is_struct, bool floor_real)
  {
 -  gcc_assert (TREE_CODE (cst) == INTEGER_CST);
gcc_assert (TREE_CODE (pointee_size_tree) == INTEGER_CST);
 -
unsigned HOST_WIDE_INT pointee_size = TREE_INT_CST_LOW
 (pointee_size_tree);
 -  unsigned HOST_WIDE_INT alloc_size = TREE_INT_CST_LOW (cst);
 +
 +  unsigned HOST_WIDE_INT alloc_size;
 +  switch (TREE_CODE (cst))
 +{
 +default:
 +  /* Assume all unhandled operands are compatible.  */
 +  return true;
 +case INTEGER_C

Go patch committed: Better error message for unknown package name

2022-07-05 Thread Ian Lance Taylor via Gcc-patches
This patch to the Go frontend gives a  better error message for an
unknown package name, saying "undefined reference" rather than
"expected package".  This requires updating a test.  This fixes
https://go.dev/issue/51237.  Bootstrapped and ran Go testsuite on
x86_64-pc-linux-gnu.  Committed to mainline.

Ian
db1256cfb4620c4d52175002940347d399148502
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 7b1d3011fff..461e2fdf271 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-6479d5976c5d848ec6f5843041275723a6b0
+a209dca9ec918535977dcab99fd9bb60986ffacd
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/gcc/go/gofrontend/parse.cc b/gcc/go/gofrontend/parse.cc
index a3c6f630a09..c93d82bba39 100644
--- a/gcc/go/gofrontend/parse.cc
+++ b/gcc/go/gofrontend/parse.cc
@@ -191,7 +191,11 @@ Parse::qualified_ident(std::string* pname, Named_object** 
ppackage)
   Named_object* package = this->gogo_->lookup(name, NULL);
   if (package == NULL || !package->is_package())
 {
-  go_error_at(this->location(), "expected package");
+  if (package == NULL)
+   go_error_at(this->location(), "reference to undefined name %qs",
+   Gogo::message_name(name).c_str());
+  else
+   go_error_at(this->location(), "expected package");
   // We expect . IDENTIFIER; skip both.
   if (this->advance_token()->is_identifier())
this->advance_token();
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue27938.go 
b/gcc/testsuite/go.test/test/fixedbugs/issue27938.go
index ed974e642df..aecc67678ac 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue27938.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue27938.go
@@ -11,13 +11,13 @@
 package p
 
 type _ struct {
-   F sync.Mutex // ERROR "undefined: sync|expected package"
+   F sync.Mutex // ERROR "undefined: sync|expected package|reference to 
undefined name"
 }
 
 type _ struct {
-   sync.Mutex // ERROR "undefined: sync|expected package"
+   sync.Mutex // ERROR "undefined: sync|expected package|reference to 
undefined name"
 }
 
 type _ interface {
-   sync.Mutex // ERROR "undefined: sync|expected package|expected 
signature or type name"
+   sync.Mutex // ERROR "undefined: sync|expected package|expected 
signature or type name|reference to undefined name"
 }


Go patch committed: Propagate array length error marker

2022-07-05 Thread Ian Lance Taylor via Gcc-patches
This patch to the Go frontend propagates the array length error marker
farther, to avoid a compiler crash on invalid code.  This fixes
https://go.dev/issue/53639.  Bootstrapped and ran Go testsuite on
x86_64-pc-linux-gnu.  Committed to mainline.

Ian
c70a48a8f8f6a43b35f783b5672c9a3c0a363c31
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 461e2fdf271..7c5c45672d7 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-a209dca9ec918535977dcab99fd9bb60986ffacd
+d295a0a2c96c0f7c3abd94fea3aa4e2303bf2af2
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index 00d35a965a9..2492d9fe735 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -8486,6 +8486,11 @@ Builtin_call_expression::do_flatten(Gogo* gogo, 
Named_object* function,
 pa != this->args()->end();
 ++pa)
  {
+   if ((*pa)->is_error_expression())
+ {
+   go_assert(saw_errors());
+   return Expression::make_error(loc);
+ }
if ((*pa)->is_nil_expression())
  {
Expression* nil = Expression::make_nil(loc);
@@ -13391,6 +13396,7 @@ Array_index_expression::do_check_types(Gogo*)
   if (array_type == NULL)
 {
   go_assert(this->array_->type()->is_error());
+  this->set_is_error();
   return;
 }
 
diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc
index 4995283bb60..9f34801f695 100644
--- a/gcc/go/gofrontend/types.cc
+++ b/gcc/go/gofrontend/types.cc
@@ -7429,7 +7429,10 @@ bool
 Array_type::do_verify()
 {
   if (this->element_type()->is_error_type())
-return false;
+{
+  this->set_is_error();
+  return false;
+}
   if (!this->verify_length())
 {
   this->length_ = Expression::make_error(this->length_->location());


libstdc++: Minor codegen improvement for atomic wait spinloop

2022-07-05 Thread Thomas Rodgers via Gcc-patches
This patch merges the spin loops in the atomic wait implementation which is
a
minor codegen improvement.

libstdc++-v3/ChangeLog:
 * include/bits/atomic_wait.h (__atomic_spin): Merge spin loops.


0001-libstdc-Minor-codegen-improvement-for-atomic-wait-sp.patch
Description: Binary data


Re: [PATCH]middle-end simplify complex if expressions where comparisons are inverse of one another.

2022-07-05 Thread Andrew Pinski via Gcc-patches
On Tue, Jul 5, 2022 at 8:16 AM Tamar Christina via Gcc-patches
 wrote:
>
>
>
> > -Original Message-
> > From: Richard Biener 
> > Sent: Monday, June 20, 2022 9:57 AM
> > To: Tamar Christina 
> > Cc: gcc-patches@gcc.gnu.org; nd 
> > Subject: Re: [PATCH]middle-end simplify complex if expressions where
> > comparisons are inverse of one another.
> >
> > On Thu, 16 Jun 2022, Tamar Christina wrote:
> >
> > > Hi All,
> > >
> > > This optimizes the following sequence
> > >
> > >   ((a < b) & c) | ((a >= b) & d)
> > >
> > > into
> > >
> > >   (a < b ? c : d) & 1
> > >
> > > for scalar. On vector we can omit the & 1.
> > >
> > > This changes the code generation from
> > >
> > > zoo2:
> > > cmp w0, w1
> > > csetw0, lt
> > > csetw1, ge
> > > and w0, w0, w2
> > > and w1, w1, w3
> > > orr w0, w0, w1
> > > ret
> > >
> > > into
> > >
> > > cmp w0, w1
> > > cselw0, w2, w3, lt
> > > and w0, w0, 1
> > > ret
> > >
> > > and significantly reduces the number of selects we have to do in the
> > > vector code.
> > >
> > > Bootstrapped Regtested on aarch64-none-linux-gnu, x86_64-pc-linux-gnu
> > > and no issues.
> > >
> > > Ok for master?
> > >
> > > Thanks,
> > > Tamar
> > >
> > > gcc/ChangeLog:
> > >
> > > * fold-const.cc (inverse_conditions_p): Traverse if SSA_NAME.
> > > * match.pd: Add new rule.
> > >
> > > gcc/testsuite/ChangeLog:
> > >
> > > * gcc.target/aarch64/if-compare_1.c: New test.
> > > * gcc.target/aarch64/if-compare_2.c: New test.
> > >
> > > --- inline copy of patch --
> > > diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc index
> > >
> > 39a5a52958d87497f301826e706886b290771a2d..f180599b90150acd3ed895a64
> > 280
> > > aa3255061256 100644
> > > --- a/gcc/fold-const.cc
> > > +++ b/gcc/fold-const.cc
> > > @@ -2833,15 +2833,38 @@ compcode_to_comparison (enum
> > comparison_code
> > > code)  bool  inverse_conditions_p (const_tree cond1, const_tree cond2)
> > > {
> > > -  return (COMPARISON_CLASS_P (cond1)
> > > - && COMPARISON_CLASS_P (cond2)
> > > - && (invert_tree_comparison
> > > - (TREE_CODE (cond1),
> > > -  HONOR_NANS (TREE_OPERAND (cond1, 0))) == TREE_CODE
> > (cond2))
> > > - && operand_equal_p (TREE_OPERAND (cond1, 0),
> > > - TREE_OPERAND (cond2, 0), 0)
> > > - && operand_equal_p (TREE_OPERAND (cond1, 1),
> > > - TREE_OPERAND (cond2, 1), 0));
> > > +  if (COMPARISON_CLASS_P (cond1)
> > > +  && COMPARISON_CLASS_P (cond2)
> > > +  && (invert_tree_comparison
> > > +  (TREE_CODE (cond1),
> > > +   HONOR_NANS (TREE_OPERAND (cond1, 0))) == TREE_CODE
> > (cond2))
> > > +  && operand_equal_p (TREE_OPERAND (cond1, 0),
> > > + TREE_OPERAND (cond2, 0), 0)
> > > +  && operand_equal_p (TREE_OPERAND (cond1, 1),
> > > + TREE_OPERAND (cond2, 1), 0))
> > > +return true;
> > > +
> > > +  if (TREE_CODE (cond1) == SSA_NAME
> > > +  && TREE_CODE (cond2) == SSA_NAME)
> > > +{
> > > +  gimple *gcond1 = SSA_NAME_DEF_STMT (cond1);
> > > +  gimple *gcond2 = SSA_NAME_DEF_STMT (cond2);
> > > +  if (!is_gimple_assign (gcond1) || !is_gimple_assign (gcond2))
> > > +   return false;
> > > +
> > > +  tree_code code1 = gimple_assign_rhs_code (gcond1);
> > > +  tree_code code2 = gimple_assign_rhs_code (gcond2);
> > > +  return TREE_CODE_CLASS (code1) == tcc_comparison
> > > +&& TREE_CODE_CLASS (code2) == tcc_comparison
> > > +&& invert_tree_comparison (code1,
> > > + HONOR_NANS (gimple_arg (gcond1, 0))) == code2
> > > +&& operand_equal_p (gimple_arg (gcond1, 0),
> > > +gimple_arg (gcond2, 0), 0)
> > > +&& operand_equal_p (gimple_arg (gcond1, 1),
> > > +gimple_arg (gcond2, 1), 0);
> > > +}
> > > +
> > > +  return false;
> >
> > if we do extend inverse_condition_p please add an overload like
>
> Done.
>
> >
> > bool
> > inverse_condition_p (enum tree_code, tree op00, tree op01,
> >  enum tree_code, tree op10, tree op11)
> >
> > so you can avoid some code duplication here.
> >
> > >  }
> > >
> > >  /* Return a tree for the comparison which is the combination of diff
> > > --git a/gcc/match.pd b/gcc/match.pd index
> > >
> > 6d691d302b339c0e4556b40af158b5208c12d08f..bad49dd348add751d9ec1e30
> > 23e3
> > > 4d9ac123194f 100644
> > > --- a/gcc/match.pd
> > > +++ b/gcc/match.pd
> > > @@ -1160,6 +1160,32 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
> > >   (convert (bit_and (negate (convert:utype { pmop[0]; }))
> > >(convert:utype @1)))
> > >
> > > +/* Fold (((a < b) & c) | ((a >= b) & d)) into (a < b ? c : d) & 1.
> > > +*/ (simplify  (bit_ior
> > > +  (bit_and:c (convert? @0) @2)
> > > +  (bit_and:c (convert? @1) @3))
> >
> > in case the comparison returns a signed bool this might turn out wrong.
> > Maybe simply use zero_on

[pushed] c++: dependent conversion operator lookup [PR106179]

2022-07-05 Thread Jason Merrill via Gcc-patches
This testcase demonstrates that my assumption that we would only be
interested in a class template lookup if the template-id is followed by ::
was wrong.

PR c++/106179
PR c++/106024

gcc/cp/ChangeLog:

* parser.cc (cp_parser_lookup_name): Remove :: requirement
for using unqualified lookup result.

gcc/testsuite/ChangeLog:

* g++.dg/template/operator16.C: New test.
---
 gcc/cp/parser.cc   | 4 
 gcc/testsuite/g++.dg/template/operator16.C | 9 +
 2 files changed, 9 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/template/operator16.C

diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index df657a3fb2b..5cd6a527d93 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -30738,10 +30738,6 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
 looking at a template arg list.  */
  if (!cp_parser_skip_entire_template_parameter_list (parser))
decl = NULL_TREE;
- /* And only use the unqualified lookup if we're looking at ::.  */
- if (decl
- && !cp_lexer_next_token_is (parser->lexer, CPP_SCOPE))
-   decl = NULL_TREE;
}
 
   /* If we know we're looking for a type (e.g. A in p->A::x),
diff --git a/gcc/testsuite/g++.dg/template/operator16.C 
b/gcc/testsuite/g++.dg/template/operator16.C
new file mode 100644
index 000..434a266850c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/operator16.C
@@ -0,0 +1,9 @@
+// PR c++/106179
+
+struct Mat {
+  template  Mat();
+};
+template  struct Mat_;
+template  Mat::Mat() {
+  _Tp commaInitializer = commaInitializer.operator Mat_<_Tp>;
+}

base-commit: 510ac273a785361f7c8f24e4815bfb477a6a2e07
-- 
2.27.0