[PATCH] Use unsigned long long in asm-x86-linux-rdmsr.c

2021-10-01 Thread H.J. Lu via Gcc-patches
On Wed, Aug 4, 2021 at 3:26 PM David Malcolm via Gcc-patches
 wrote:
>
> Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
> Pushed to trunk as r12-2749-gded2c2c068f6f2825474758cb03a05070a5837e8.
>
> gcc/ChangeLog:
> PR analyzer/101570
> * Makefile.in (ANALYZER_OBJS): Add analyzer/region-model-asm.o.
>
> gcc/analyzer/ChangeLog:
> PR analyzer/101570
> * analyzer.cc (maybe_reconstruct_from_def_stmt): Add GIMPLE_ASM
> case.
> * analyzer.h (class asm_output_svalue): New forward decl.
> (class reachable_regions): New forward decl.
> * complexity.cc (complexity::from_vec_svalue): New.
> * complexity.h (complexity::from_vec_svalue): New decl.
> * engine.cc (feasibility_state::maybe_update_for_edge): Handle
> asm stmts by calling on_asm_stmt.
> * region-model-asm.cc: New file.
> * region-model-manager.cc
> (region_model_manager::maybe_fold_asm_output_svalue): New.
> (region_model_manager::get_or_create_asm_output_svalue): New.
> (region_model_manager::log_stats): Log m_asm_output_values_map.
> * region-model.cc (region_model::on_stmt_pre): Handle GIMPLE_ASM.
> * region-model.h (visitor::visit_asm_output_svalue): New.
> (region_model_manager::get_or_create_asm_output_svalue): New decl.
> (region_model_manager::maybe_fold_asm_output_svalue): New decl.
> (region_model_manager::asm_output_values_map_t): New typedef.
> (region_model_manager::m_asm_output_values_map): New field.
> (region_model::on_asm_stmt): New.
> * store.cc (binding_cluster::on_asm): New.
> * store.h (binding_cluster::on_asm): New decl.
> * svalue.cc (svalue::cmp_ptr): Handle SK_ASM_OUTPUT.
> (asm_output_svalue::dump_to_pp): New.
> (asm_output_svalue::dump_input): New.
> (asm_output_svalue::input_idx_to_asm_idx): New.
> (asm_output_svalue::accept): New.
> * svalue.h (enum svalue_kind): Add SK_ASM_OUTPUT.
> (svalue::dyn_cast_asm_output_svalue): New.
> (class asm_output_svalue): New.
> (is_a_helper ::test): New.
> (struct default_hash_traits): New.
>
> gcc/testsuite/ChangeLog:
> PR analyzer/101570
> * gcc.dg/analyzer/asm-x86-1.c: New test.
> * gcc.dg/analyzer/asm-x86-lp64-1.c: New test.
> * gcc.dg/analyzer/asm-x86-lp64-2.c: New test.
> * gcc.dg/analyzer/pr101570.c: New test.
> * gcc.dg/analyzer/torture/asm-x86-linux-array_index_mask_nospec.c:
> New test.
> * gcc.dg/analyzer/torture/asm-x86-linux-cpuid-paravirt-1.c: New
> test.
> * gcc.dg/analyzer/torture/asm-x86-linux-cpuid-paravirt-2.c: New
> test.
> * gcc.dg/analyzer/torture/asm-x86-linux-cpuid.c: New test.
> * gcc.dg/analyzer/torture/asm-x86-linux-rdmsr-paravirt.c: New
> test.
> * gcc.dg/analyzer/torture/asm-x86-linux-rdmsr.c: New test.
> * gcc.dg/analyzer/torture/asm-x86-linux-wfx_get_ps_timeout-full.c:
> New test.
> * gcc.dg/analyzer/torture/asm-x86-linux-wfx_get_ps_timeout-reduced.c:
> New test.
>
> Signed-off-by: David Malcolm 
> ---
>  gcc/Makefile.in   |   1 +
>  gcc/analyzer/analyzer.cc  |   1 +
>  gcc/analyzer/analyzer.h   |   2 +
>  gcc/analyzer/complexity.cc|  16 +
>  gcc/analyzer/complexity.h |   1 +
>  gcc/analyzer/engine.cc|   2 +
>  gcc/analyzer/region-model-asm.cc  | 303 +
>  gcc/analyzer/region-model-manager.cc  |  48 +++
>  gcc/analyzer/region-model.cc  |   5 +-
>  gcc/analyzer/region-model.h   |  13 +
>  gcc/analyzer/store.cc |  17 +
>  gcc/analyzer/store.h  |   1 +
>  gcc/analyzer/svalue.cc|  89 +
>  gcc/analyzer/svalue.h | 145 +++-
>  gcc/testsuite/gcc.dg/analyzer/asm-x86-1.c |  69 
>  .../gcc.dg/analyzer/asm-x86-lp64-1.c  | 131 +++
>  .../gcc.dg/analyzer/asm-x86-lp64-2.c  |  34 ++
>  gcc/testsuite/gcc.dg/analyzer/pr101570.c  |   5 +
>  .../asm-x86-linux-array_index_mask_nospec.c   |  74 
>  .../torture/asm-x86-linux-cpuid-paravirt-1.c  |  81 +
>  .../torture/asm-x86-linux-cpuid-paravirt-2.c  | 135 
>  .../analyzer/torture/asm-x86-linux-cpuid.c|  46 +++
>  .../torture/asm-x86-linux-rdmsr-paravirt.c| 210 
>  .../analyzer/torture/asm-x86-linux-rdmsr.c|  33 ++
>  .../asm-x86-linux-wfx_get_ps_timeout-full.c   | 319 ++
>  ...asm-x86-linux-wfx_get_ps_timeout-reduced.c |  77 +
>  26 files changed, 1855 insertions(+), 3 deletions(-)
>  create mode 100644 gcc/analyzer/region-model-asm.cc
>  create mode 100644 gcc/testsuite/gcc.dg/analyzer/asm-x86-1.c
>  create 

[r12-4067 Regression] FAIL: g++.dg/modules/xtreme-header-3_a.H -std=c++2b (test for excess errors) on Linux/x86_64

2021-10-01 Thread sunil.k.pandey via Gcc-patches
On Linux/x86_64,

c46ecb0112e91c80ee111439e79a58a953e4479d is the first bad commit
commit c46ecb0112e91c80ee111439e79a58a953e4479d
Author: Jonathan Wakely 
Date:   Mon Apr 19 14:49:12 2021 +0100

libstdc++: Allow visiting inherited variants [PR 90943]

caused

FAIL: g++.dg/modules/xtreme-header-3_a.H module-cmi  
(gcm.cache/$srcdir/g++.dg/modules/xtreme-header-3_a.H.gcm)
FAIL: g++.dg/modules/xtreme-header-3_a.H -std=c++17 (internal compiler error)
FAIL: g++.dg/modules/xtreme-header-3_a.H -std=c++17 (test for excess errors)
FAIL: g++.dg/modules/xtreme-header-3_a.H -std=c++2a (internal compiler error)
FAIL: g++.dg/modules/xtreme-header-3_a.H -std=c++2a (test for excess errors)
FAIL: g++.dg/modules/xtreme-header-3_a.H -std=c++2b (internal compiler error)
FAIL: g++.dg/modules/xtreme-header-3_a.H -std=c++2b (test for excess errors)

with GCC configured with

../../gcc/configure 
--prefix=/local/skpandey/gccwork/toolwork/gcc-bisect-master/master/r12-4067/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="modules.exp=g++.dg/modules/xtreme-header-3_a.H 
--target_board='unix{-m32}'"
$ cd {build_dir}/gcc && make check 
RUNTESTFLAGS="modules.exp=g++.dg/modules/xtreme-header-3_a.H 
--target_board='unix{-m32\ -march=cascadelake}'"
$ cd {build_dir}/gcc && make check 
RUNTESTFLAGS="modules.exp=g++.dg/modules/xtreme-header-3_a.H 
--target_board='unix{-m64}'"
$ cd {build_dir}/gcc && make check 
RUNTESTFLAGS="modules.exp=g++.dg/modules/xtreme-header-3_a.H 
--target_board='unix{-m64\ -march=cascadelake}'"

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


Re: [PATCH] c++: unifying equal NONTYPE_ARGUMENT_PACKs [PR102547]

2021-10-01 Thread Patrick Palka via Gcc-patches
On Fri, 1 Oct 2021, Patrick Palka wrote:

> On Fri, Oct 1, 2021 at 1:29 PM Patrick Palka  wrote:
> >
> > On Fri, 1 Oct 2021, Jason Merrill wrote:
> >
> > > On 10/1/21 10:26, Patrick Palka wrote:
> > > > On Fri, 1 Oct 2021, Jason Merrill wrote:
> > > >
> > > > > On 10/1/21 09:46, Patrick Palka wrote:
> > > > > > Here during partial ordering of the two partial specializations we 
> > > > > > end
> > > > > > up in unify with parm=arg=NONTYPE_ARGUMENT_PACK, and crash
> > > > > > shortly
> > > > > > thereafter because uses_template_parms calls
> > > > > > potential_constant_expression
> > > > > > which doesn't handle NONTYPE_ARGUMENT_PACK.
> > > > > >
> > > > > > This patch fixes this by checking dependent_template_arg_p instead 
> > > > > > of
> > > > > > uses_template_parms when parm==arg, which does handle
> > > > > > NONTYPE_ARGUMENT_PACK.
> > > > > > We could also perhaps fix uses_template_parms / inst_dep_expr_p to
> > > > > > better
> > > > > > handle NONTYPE_ARGUMENT_PACK,
> > > > >
> > > > > Please.
> > > >
> > > > Sounds good, like the following then?  Passes light testing, bootstrap
> > > > and regtest on progress.
> > > >
> > > > -- >8 --
> > > >
> > > > PR c++/102547
> > > >
> > > > gcc/cp/ChangeLog:
> > > >
> > > > * pt.c (instantiation_dependent_expression_p): Sidestep checking
> > > > potential_constant_expression on NONTYPE_ARGUMENT_PACK.
> > > >
> > > > gcc/testsuite/ChangeLog:
> > > >
> > > > * g++.dg/cpp0x/variadic-partial2.C: New test.
> > > > * g++.dg/cpp0x/variadic-partial2a.C: New test.
> > > > ---
> > > >   gcc/cp/pt.c   |  4 +++-
> > > >   .../g++.dg/cpp0x/variadic-partial2.C  | 16 ++
> > > >   .../g++.dg/cpp0x/variadic-partial2a.C | 22 +++
> > > >   3 files changed, 41 insertions(+), 1 deletion(-)
> > > >   create mode 100644 gcc/testsuite/g++.dg/cpp0x/variadic-partial2.C
> > > >   create mode 100644 gcc/testsuite/g++.dg/cpp0x/variadic-partial2a.C
> > > >
> > > > diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
> > > > index 1dcdffe322a..643204103c5 100644
> > > > --- a/gcc/cp/pt.c
> > > > +++ b/gcc/cp/pt.c
> > > > @@ -27705,7 +27705,9 @@ instantiation_dependent_expression_p (tree
> > > > expression)
> > > >   {
> > > > return (instantiation_dependent_uneval_expression_p (expression)
> > > >   || (processing_template_decl
> > > > - && potential_constant_expression (expression)
> > > > + && expression != NULL_TREE
> > > > + && (TREE_CODE (expression) == NONTYPE_ARGUMENT_PACK
> > > > + || potential_constant_expression (expression))
> > >
> > > I'd prefer to loop over the elements of the pack, either here or (probably
> > > better) in potential_constant_expression.
> >
> > Ah, makes sense.  Like so?  Bootstrapped and regtested on
> > x86_64-pc-linux-gnu.
> 
> On second thought given that a NONTYPE_ARGUMENT_PACK is by
> construction a sequence of non-type template arguments, is looping
> over its elements in potential_const_expr necessary?  Maybe we should
> just return true unconditionally.

Never mind, I forgot that we also use NONTYPE_ARGUMENT_PACK to pack
function arguments, so we can't just assume the elements are always
constant.

> 
> >
> > -- >8 --
> >
> > Subject: [PATCH] c++: unifying equal NONTYPE_ARGUMENT_PACKs [PR102547]
> >
> > Here during partial ordering of the two partial specializations we end
> > up in unify with parm=arg=NONTYPE_ARGUMENT_PACK, and crash shortly
> > thereafter because uses_template_parms(parms) calls potential_const_expr
> > which doesn't handle NONTYPE_ARGUMENT_PACK.
> >
> > This patch fixes this by extending potential_constant_expression to handle
> > NONTYPE_ARGUMENT_PACK appropriately.
> >
> > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
> > trunk/11?
> >
> > PR c++/102547
> >
> > gcc/cp/ChangeLog:
> >
> > * constexpr.c (potential_constant_expression_1): Handle
> > NONTYPE_ARGUMENT_PACK.
> >
> > gcc/testsuite/ChangeLog:
> >
> > * g++.dg/cpp0x/variadic-partial2.C: New test.
> > * g++.dg/cpp0x/variadic-partial2a.C: New test.
> > ---
> >  gcc/cp/constexpr.c| 10 +
> >  .../g++.dg/cpp0x/variadic-partial2.C  | 16 ++
> >  .../g++.dg/cpp0x/variadic-partial2a.C | 22 +++
> >  3 files changed, 48 insertions(+)
> >  create mode 100644 gcc/testsuite/g++.dg/cpp0x/variadic-partial2.C
> >  create mode 100644 gcc/testsuite/g++.dg/cpp0x/variadic-partial2a.C
> >
> > diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
> > index 18d9d117a48..e95ff00774f 100644
> > --- a/gcc/cp/constexpr.c
> > +++ b/gcc/cp/constexpr.c
> > @@ -9043,6 +9043,16 @@ potential_constant_expression_1 (tree t, bool 
> > want_rval, bool strict, bool now,
> >  case CO_RETURN_EXPR:
> >return false;
> >
> > +case NONTYPE_ARGUMENT_PACK:
> > +  {
> > +   tree args = ARGUMENT_PACK_ARGS (t);
> > +   

Re: [PATCH] c++: unifying equal NONTYPE_ARGUMENT_PACKs [PR102547]

2021-10-01 Thread Patrick Palka via Gcc-patches
On Fri, Oct 1, 2021 at 1:29 PM Patrick Palka  wrote:
>
> On Fri, 1 Oct 2021, Jason Merrill wrote:
>
> > On 10/1/21 10:26, Patrick Palka wrote:
> > > On Fri, 1 Oct 2021, Jason Merrill wrote:
> > >
> > > > On 10/1/21 09:46, Patrick Palka wrote:
> > > > > Here during partial ordering of the two partial specializations we end
> > > > > up in unify with parm=arg=NONTYPE_ARGUMENT_PACK, and crash
> > > > > shortly
> > > > > thereafter because uses_template_parms calls
> > > > > potential_constant_expression
> > > > > which doesn't handle NONTYPE_ARGUMENT_PACK.
> > > > >
> > > > > This patch fixes this by checking dependent_template_arg_p instead of
> > > > > uses_template_parms when parm==arg, which does handle
> > > > > NONTYPE_ARGUMENT_PACK.
> > > > > We could also perhaps fix uses_template_parms / inst_dep_expr_p to
> > > > > better
> > > > > handle NONTYPE_ARGUMENT_PACK,
> > > >
> > > > Please.
> > >
> > > Sounds good, like the following then?  Passes light testing, bootstrap
> > > and regtest on progress.
> > >
> > > -- >8 --
> > >
> > > PR c++/102547
> > >
> > > gcc/cp/ChangeLog:
> > >
> > > * pt.c (instantiation_dependent_expression_p): Sidestep checking
> > > potential_constant_expression on NONTYPE_ARGUMENT_PACK.
> > >
> > > gcc/testsuite/ChangeLog:
> > >
> > > * g++.dg/cpp0x/variadic-partial2.C: New test.
> > > * g++.dg/cpp0x/variadic-partial2a.C: New test.
> > > ---
> > >   gcc/cp/pt.c   |  4 +++-
> > >   .../g++.dg/cpp0x/variadic-partial2.C  | 16 ++
> > >   .../g++.dg/cpp0x/variadic-partial2a.C | 22 +++
> > >   3 files changed, 41 insertions(+), 1 deletion(-)
> > >   create mode 100644 gcc/testsuite/g++.dg/cpp0x/variadic-partial2.C
> > >   create mode 100644 gcc/testsuite/g++.dg/cpp0x/variadic-partial2a.C
> > >
> > > diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
> > > index 1dcdffe322a..643204103c5 100644
> > > --- a/gcc/cp/pt.c
> > > +++ b/gcc/cp/pt.c
> > > @@ -27705,7 +27705,9 @@ instantiation_dependent_expression_p (tree
> > > expression)
> > >   {
> > > return (instantiation_dependent_uneval_expression_p (expression)
> > >   || (processing_template_decl
> > > - && potential_constant_expression (expression)
> > > + && expression != NULL_TREE
> > > + && (TREE_CODE (expression) == NONTYPE_ARGUMENT_PACK
> > > + || potential_constant_expression (expression))
> >
> > I'd prefer to loop over the elements of the pack, either here or (probably
> > better) in potential_constant_expression.
>
> Ah, makes sense.  Like so?  Bootstrapped and regtested on
> x86_64-pc-linux-gnu.

On second thought given that a NONTYPE_ARGUMENT_PACK is by
construction a sequence of non-type template arguments, is looping
over its elements in potential_const_expr necessary?  Maybe we should
just return true unconditionally.

>
> -- >8 --
>
> Subject: [PATCH] c++: unifying equal NONTYPE_ARGUMENT_PACKs [PR102547]
>
> Here during partial ordering of the two partial specializations we end
> up in unify with parm=arg=NONTYPE_ARGUMENT_PACK, and crash shortly
> thereafter because uses_template_parms(parms) calls potential_const_expr
> which doesn't handle NONTYPE_ARGUMENT_PACK.
>
> This patch fixes this by extending potential_constant_expression to handle
> NONTYPE_ARGUMENT_PACK appropriately.
>
> Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
> trunk/11?
>
> PR c++/102547
>
> gcc/cp/ChangeLog:
>
> * constexpr.c (potential_constant_expression_1): Handle
> NONTYPE_ARGUMENT_PACK.
>
> gcc/testsuite/ChangeLog:
>
> * g++.dg/cpp0x/variadic-partial2.C: New test.
> * g++.dg/cpp0x/variadic-partial2a.C: New test.
> ---
>  gcc/cp/constexpr.c| 10 +
>  .../g++.dg/cpp0x/variadic-partial2.C  | 16 ++
>  .../g++.dg/cpp0x/variadic-partial2a.C | 22 +++
>  3 files changed, 48 insertions(+)
>  create mode 100644 gcc/testsuite/g++.dg/cpp0x/variadic-partial2.C
>  create mode 100644 gcc/testsuite/g++.dg/cpp0x/variadic-partial2a.C
>
> diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
> index 18d9d117a48..e95ff00774f 100644
> --- a/gcc/cp/constexpr.c
> +++ b/gcc/cp/constexpr.c
> @@ -9043,6 +9043,16 @@ potential_constant_expression_1 (tree t, bool 
> want_rval, bool strict, bool now,
>  case CO_RETURN_EXPR:
>return false;
>
> +case NONTYPE_ARGUMENT_PACK:
> +  {
> +   tree args = ARGUMENT_PACK_ARGS (t);
> +   int len = TREE_VEC_LENGTH (args);
> +   for (int i = 0; i < len; ++i)
> + if (!RECUR (TREE_VEC_ELT (args, i), any))
> +   return false;
> +   return true;
> +  }
> +
>  default:
>if (objc_non_constant_expr_p (t))
> return false;
> diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-partial2.C 
> b/gcc/testsuite/g++.dg/cpp0x/variadic-partial2.C
> new file mode 100644
> index 000..df61f26a3c1
> --- 

[PATCH v2] c-family: Implement -Warray-compare [PR97573]

2021-10-01 Thread Marek Polacek via Gcc-patches
On Fri, Oct 01, 2021 at 11:15:45PM +0200, Jakub Jelinek wrote:
> On Fri, Oct 01, 2021 at 04:11:08PM -0400, Marek Polacek via Gcc-patches wrote:
> > +  auto_diagnostic_group d;
> > +  if (warning_at (location, OPT_Warray_compare,
> > + "comparison between two arrays%s",
> > + (c_dialect_cxx () && cxx_dialect >= cxx20)
> > + ? " is deprecated in C++20" : ""))
> 
> Not a review, just a comment.
> The above is impossible to translate, translators would translate the
> first half and the second one would be in English; but even translating
> the second part too would mean one can't reword it in some other language
> in different word order.
> 
> You can e.g. use
>   if (warning_at (location, OPT_Warray_compare,
> (c_dialect_cxx () && cxx_dialect >= cxx20)
> ? G_("comparison between two arrays is deprecated in C++20")
> : G_("comparison between two arrays")))
> instead.

Thanks, fixed:

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

-- >8 --
This patch addresses one of my leftovers from GCC 11.  C++20 introduced
[depr.array.comp]: "Equality and relational comparisons between two operands
of array type are deprecated." so this patch adds -Warray-compare.  Since the
code in question is dubious (the comparison doesn't actually compare the array
elements), I've added this warning for C too, and enabled it in all C++ modes.

PR c++/97573

gcc/c-family/ChangeLog:

* c-common.h (do_warn_array_compare): Declare.
* c-warn.c (do_warn_array_compare): New.
* c.opt (Warray-compare): New option.

gcc/c/ChangeLog:

* c-typeck.c (parser_build_binary_op): Call do_warn_array_compare.

gcc/cp/ChangeLog:

* typeck.c (cp_build_binary_op): Call do_warn_array_compare.

gcc/ChangeLog:

* doc/invoke.texi: Document -Warray-compare.

gcc/testsuite/ChangeLog:

* c-c++-common/Warray-compare-1.c: New test.
* c-c++-common/Warray-compare-2.c: New test.
---
 gcc/c-family/c-common.h   |  1 +
 gcc/c-family/c-warn.c | 32 ++
 gcc/c-family/c.opt|  4 ++
 gcc/c/c-typeck.c  |  9 +++-
 gcc/cp/typeck.c   | 13 ++
 gcc/doc/invoke.texi   | 20 -
 gcc/testsuite/c-c++-common/Warray-compare-1.c | 44 +++
 gcc/testsuite/c-c++-common/Warray-compare-2.c | 44 +++
 8 files changed, 164 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/c-c++-common/Warray-compare-1.c
 create mode 100644 gcc/testsuite/c-c++-common/Warray-compare-2.c

diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 849cefab882..078730f1e64 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -1421,6 +1421,7 @@ extern bool warn_for_restrict (unsigned, tree *, 
unsigned);
 extern void warn_for_address_or_pointer_of_packed_member (tree, tree);
 extern void warn_parm_array_mismatch (location_t, tree, tree);
 extern void maybe_warn_sizeof_array_div (location_t, tree, tree, tree, tree);
+extern void do_warn_array_compare (location_t, tree_code, tree, tree);
 
 /* Places where an lvalue, or modifiable lvalue, may be required.
Used to select diagnostic messages in lvalue_error and
diff --git a/gcc/c-family/c-warn.c b/gcc/c-family/c-warn.c
index 84ad6633c96..99cde4a2a59 100644
--- a/gcc/c-family/c-warn.c
+++ b/gcc/c-family/c-warn.c
@@ -3726,3 +3726,35 @@ maybe_warn_sizeof_array_div (location_t loc, tree arr, 
tree arr_type,
}
 }
 }
+
+/* Warn about C++20 [depr.array.comp] array comparisons: "Equality
+   and relational comparisons between two operands of array type are
+   deprecated."  We also warn in C and earlier C++ standards.  CODE is
+   the code for this comparison, OP0 and OP1 are the operands.  */
+
+void
+do_warn_array_compare (location_t location, tree_code code, tree op0, tree op1)
+{
+  STRIP_NOPS (op0);
+  STRIP_NOPS (op1);
+  if (TREE_CODE (op0) == ADDR_EXPR)
+op0 = TREE_OPERAND (op0, 0);
+  if (TREE_CODE (op1) == ADDR_EXPR)
+op1 = TREE_OPERAND (op1, 0);
+
+  auto_diagnostic_group d;
+  if (warning_at (location, OPT_Warray_compare,
+ (c_dialect_cxx () && cxx_dialect >= cxx20)
+ ? G_("comparison between two arrays is deprecated in C++20")
+ : G_("comparison between two arrays")))
+{
+  /* C doesn't allow +arr.  */
+  if (c_dialect_cxx ())
+   inform (location, "use unary %<+%> which decays operands to pointers "
+   "or %<&%D[0] %s &%D[0]%> to compare the addresses",
+   op0, op_symbol_code (code), op1);
+  else
+   inform (location, "use %<&%D[0] %s &%D[0]%> to compare the addresses",
+   op0, op_symbol_code (code), op1);
+}
+}
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 9c151d19870..06457ac739e 100644
--- 

Re: [PATCH] c-format: Add -Wformat-same-precision option [PR80060]

2021-10-01 Thread Daniil Stas via Gcc-patches
Hi, Martin

On Thu, 30 Sep 2021 09:02:28 -0600
Martin Sebor  wrote:

> On 9/26/21 3:52 PM, Daniil Stas via Gcc-patches wrote:
> > This option is enabled by default when -Wformat option is enabled. A
> > user can specify -Wno-format-same-precision to disable emitting
> > warnings about an argument passed to printf-like function having a
> > different type from the one specified in the format string if the
> > types precisions are the same.  
> 
> Having an option to control this -Wformat aspect seems useful so
> just a few comments mostly on the wording/naming choices.
> 
> Coming up with good names is tricky but I wonder if we can find
> one that's clearer than "-Wformat-same-precision".  Precision can
> mean a few different things in this context:  in the representation
> of integers it refers to the number of value bits.  In that of
> floating types, it refers to the number of significand bits.  And
> in printf directives, it refers to what comes after the optional
> period and what controls the minimum number of digits to format
> (or maximum number of characters in a string).  So "same precision"
> seems rather vague (and the proposed manual entry doesn't make it
> clear).
> 
> IIUC, the option is specifically for directives that take integer
> arguments and controls whether using an argument of an incompatible
> integer type to a conversion specifier like i or x is diagnosed when
> the argument has the same precision as the expected type.
> 
> With that in mind, would mentioning the word integer (or just int
> for short) be an improvement?  E.g., -Wformat-int-precision?
> 

Yes, I like -Wformat-int-precision name too.

> Some more comments on the documentation text are below.
> 
> > 
> > Signed-off-by: Daniil Stas 
> > 
> > gcc/c-family/ChangeLog:
> > 
> > * c-format.c (check_format_types): Don't emit warnings about
> > type differences with the format string if
> > -Wno-format-same-precision is specified and the types have
> > the same precision.
> > * c.opt: Add -Wformat-same-precision option.
> > 
> > gcc/ChangeLog:
> > 
> > * doc/invoke.texi: Add -Wformat-same-precision option
> > description.
> > 
> > gcc/testsuite/ChangeLog:
> > 
> > * c-c++-common/Wformat-same-precision-1.c: New test.
> > * c-c++-common/Wformat-same-precision-2.c: New test.
> > ---
> >   gcc/c-family/c-format.c   | 2 +-
> >   gcc/c-family/c.opt| 5 +
> >   gcc/doc/invoke.texi   | 8 +++-
> >   gcc/testsuite/c-c++-common/Wformat-same-precision-1.c | 7 +++
> >   gcc/testsuite/c-c++-common/Wformat-same-precision-2.c | 7 +++
> >   5 files changed, 27 insertions(+), 2 deletions(-)
> >   create mode 100644
> > gcc/testsuite/c-c++-common/Wformat-same-precision-1.c create mode
> > 100644 gcc/testsuite/c-c++-common/Wformat-same-precision-2.c
> > 
> > diff --git a/gcc/c-family/c-format.c b/gcc/c-family/c-format.c
> > index b4cb765a9d3..07cdcefbef8 100644
> > --- a/gcc/c-family/c-format.c
> > +++ b/gcc/c-family/c-format.c
> > @@ -4243,7 +4243,7 @@ check_format_types (const substring_loc
> > _loc, && (!pedantic || i < 2)
> >   && char_type_flag)
> > continue;
> > -  if (types->scalar_identity_flag
> > +  if ((types->scalar_identity_flag ||
> > !warn_format_same_precision) && (TREE_CODE (cur_type) == TREE_CODE
> > (wanted_type) || (INTEGRAL_TYPE_P (cur_type)
> >   && INTEGRAL_TYPE_P (wanted_type)))
> > diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
> > index 9c151d19870..e7af7365c91 100644
> > --- a/gcc/c-family/c.opt
> > +++ b/gcc/c-family/c.opt
> > @@ -656,6 +656,11 @@ C ObjC C++ LTO ObjC++ Warning
> > Alias(Wformat-overflow=, 1, 0) IntegerRange(0, 2) Warn about
> > function calls with format strings that write past the end of the
> > destination region.  Same as -Wformat-overflow=1. 
> > +Wformat-same-precision
> > +C ObjC C++ ObjC++ Var(warn_format_same_precision) Warning
> > LangEnabledBy(C ObjC C++ ObjC++,Wformat=,warn_format >= 1, 0) +Warn
> > about type differences with the format string even if the types
> > +precision is the same.  
> 
> The grammar doesn't seem quite right here (I recommend to adjust
> the text as well along similar lines as the manual, except more
> brief as is customary here).
> 
> 
> > +
> >   Wformat-security
> >   C ObjC C++ ObjC++ Var(warn_format_security) Warning
> > LangEnabledBy(C ObjC C++ ObjC++,Wformat=, warn_format >= 2, 0) Warn
> > about possible security problems with format functions. diff --git
> > a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index
> > ba98eab68a5..8833f257d75 100644 --- a/gcc/doc/invoke.texi
> > +++ b/gcc/doc/invoke.texi
> > @@ -347,7 +347,7 @@ Objective-C and Objective-C++ Dialects}.
> >   -Werror  -Werror=*  -Wexpansion-to-defined  -Wfatal-errors @gol
> >   -Wfloat-conversion  -Wfloat-equal  -Wformat  -Wformat=2 @gol
> >   -Wno-format-contains-nul  -Wno-format-extra-args  @gol
> > --Wformat-nonliteral  

Re: [committed] libstdc++: Specialize std::pointer_traits<__normal_iterator>

2021-10-01 Thread Jonathan Wakely via Gcc-patches
On Thu, 30 Sept 2021 at 21:27, François Dumont via Libstdc++
 wrote:
>
> Here is the _Safe_iterator one.
>
> Doing so I noticed that pointer_traits rebind for __normal_iterator was
> wrong and added tests on it.

Oops, thanks!

> For _Safe_iterator maybe I should specialize only when instantiated with
> __normal_iterator ? Or maybe limit to random_access_iterator_tag ?

Yes, I think that's a good idea, maybe only for __normal_iterator. I think that should cover all the cases we actually need to
support.

And could you change the existing pointer_traits<__normal_iterator> partial specialization to only be valid for
__normal_iterator as well? i.e. only for __normal_iterator that
wraps a pointer (which is true for string::iterator, vector::iterator
etc.)

> Whatever the pointer_to implementation is problematic, we can only
> produce singular iterator as I did ifor now.

Hmm, yes. I think that's OK, because I don't think anybody is actually
going to use that function. What matters is that it works with
std::__to_address for C++17 mode, and that doesn't depend on
pointer_to, so it's OK if it doesn't work usefully.

Thanks!



RE: [PATCH][GCC] aarch64: enable cortex-x2 CPU

2021-10-01 Thread Przemyslaw Wirkus via Gcc-patches
> Subject: RE: [PATCH][GCC] aarch64: enable cortex-x2 CPU
> 
> 
> 
> > -Original Message-
> > From: Kyrylo Tkachov
> > Sent: Friday, October 1, 2021 1:17 PM
> > To: Przemyslaw Wirkus ; gcc-
> > patc...@gcc.gnu.org
> > Cc: Richard Earnshaw ; Richard Sandiford
> > ; Marcus Shawcroft
> > 
> > Subject: RE: [PATCH][GCC] aarch64: enable cortex-x2 CPU
> >
> >
> >
> > > -Original Message-
> > > From: Przemyslaw Wirkus 
> > > Sent: Wednesday, September 22, 2021 9:38 AM
> > > To: gcc-patches@gcc.gnu.org
> > > Cc: Richard Earnshaw ; Richard Sandiford
> > > ; Marcus Shawcroft
> > > ; Kyrylo Tkachov
> > 
> > > Subject: [PATCH][GCC] aarch64: enable cortex-x2 CPU
> > >
> > > Patch is adding 'cortex-x2' to -mcpu command line option.
> > >
> > > OK for master?
> > >
> > > gcc/ChangeLog:
> > >
> > > 2021-09-02  Przemyslaw Wirkus  
> > >
> > >   * config/aarch64/aarch64-cores.def (AARCH64_CORE): New
> > >   Cortex-X2 core.
> > >   * config/aarch64/aarch64-tune.md: Regenerate.
> > >   * doc/invoke.texi: Update docs.
> > diff --git a/gcc/config/aarch64/aarch64-cores.def
> > b/gcc/config/aarch64/aarch64-cores.def
> > index
> >
> a8027e92fa8f7554e2b19d00f7c85c6ed48a92e5..34d9646ab6a32a19e7cd09d9
> > 5594b59278d02920 100644
> > --- a/gcc/config/aarch64/aarch64-cores.def
> > +++ b/gcc/config/aarch64/aarch64-cores.def
> > @@ -168,4 +168,6 @@ AARCH64_CORE("cortex-a510",  cortexa510,
> > cortexa55, 9A,  AARCH64_FL_FOR_ARCH9 |
> >
> >  AARCH64_CORE("cortex-a710",  cortexa710, cortexa55, 9A,
> > AARCH64_FL_FOR_ARCH9 | AARCH64_FL_SVE2_BITPERM |
> AARCH64_FL_MEMTAG |
> > AARCH64_FL_I8MM | AARCH64_FL_BF16, neoversen2, 0x41, 0xd47, -1)
> >
> > +AARCH64_CORE("cortex-x2",  cortexx2, cortexa55, 9A,
> > AARCH64_FL_FOR_ARCH9 | AARCH64_FL_SVE2_BITPERM |
> AARCH64_FL_MEMTAG |
> > AARCH64_FL_I8MM | AARCH64_FL_BF16, neoversen2, 0x41, 0xd48, -1)
> > +
> >
> > Let's use cortexa57 for scheduling here for now.
> 
> I should have said, ok with that change.

commit 257d2890a769a8aa564d079170377e637e07acb1

> Kyrill
> > Thanks,
> > Kyrill


RE: [PATCH][GCC] aarch64: enable cortex-a510 CPU

2021-10-01 Thread Przemyslaw Wirkus via Gcc-patches
> Hi Przemek,
> 
> > -Original Message-
> > From: Przemyslaw Wirkus 
> > Sent: Wednesday, September 22, 2021 9:35 AM
> > To: gcc-patches@gcc.gnu.org
> > Cc: Richard Earnshaw ; Richard Sandiford
> > ; Marcus Shawcroft
> > ; Kyrylo Tkachov
> 
> > Subject: [PATCH][GCC] aarch64: enable cortex-a510 CPU
> >
> > Patch is adding 'cortex-a510' to -mcpu command line option.
> >
> > gcc/ChangeLog:
> >
> > 2021-09-02  Przemyslaw Wirkus  
> >
> > * config/aarch64/aarch64-cores.def (AARCH64_CORE): New
> > Cortex-A510 core.
> > * config/aarch64/aarch64-tune.md: Regenerate.
> > * doc/invoke.texi: Update docs.
> 
> +/* Arm9.0-A Architecture Processors.  */
> 
> Typo, should be "Armv9.0-a".
> 
> +
> +/* Arm ('A') cores. */
> +AARCH64_CORE("cortex-a510",  cortexa510, cortexa55, 9A,
> +AARCH64_FL_FOR_ARCH9 | AARCH64_FL_SVE2_BITPERM |
> AARCH64_FL_MEMTAG |
> +AARCH64_FL_I8MM | AARCH64_FL_BF16, neoversen2, 0x41, 0xd46, -1)
> +
> 
> We'll need to update the tuning anyway once we do it properly, but for now I
> think for the COSTS field (4th to last) we should go with cortexa53 rather
> than neoversen2.
> Ok with those changes.

commit 8aa3ab5a47664023d83ea5097a53a66bd6cbb978

> Thanks,
> Kyrill


RE: [PATCH][GCC] aarch64: enable cortex-a710 CPU

2021-10-01 Thread Przemyslaw Wirkus via Gcc-patches



> -Original Message-
> From: Kyrylo Tkachov 
> Sent: 01 October 2021 13:16
> To: Przemyslaw Wirkus ; gcc-
> patc...@gcc.gnu.org
> Cc: Richard Earnshaw ; Richard Sandiford
> ; Marcus Shawcroft
> 
> Subject: RE: [PATCH][GCC] aarch64: enable cortex-a710 CPU
> 
> 
> 
> > -Original Message-
> > From: Przemyslaw Wirkus 
> > Sent: Wednesday, September 22, 2021 9:37 AM
> > To: gcc-patches@gcc.gnu.org
> > Cc: Richard Earnshaw ; Richard Sandiford
> > ; Marcus Shawcroft
> > ; Kyrylo Tkachov
> 
> > Subject: [PATCH][GCC] aarch64: enable cortex-a710 CPU
> >
> > Patch is adding 'cortex-a710' to -mcpu command line option.
> >
> > gcc/ChangeLog:
> >
> > 2021-09-02  Przemyslaw Wirkus  
> >
> > * config/aarch64/aarch64-cores.def (AARCH64_CORE): New
> > Cortex-A710 core.
> > * config/aarch64/aarch64-tune.md: Regenerate.
> > * doc/invoke.texi: Update docs.
> 
> diff --git a/gcc/config/aarch64/aarch64-cores.def
> b/gcc/config/aarch64/aarch64-cores.def
> index
> 478f7e1c8145365f42f43ad94d90c633aae66ebd..a8027e92fa8f7554e2b19d00f
> 7c85c6ed48a92e5 100644
> --- a/gcc/config/aarch64/aarch64-cores.def
> +++ b/gcc/config/aarch64/aarch64-cores.def
> @@ -166,4 +166,6 @@ AARCH64_CORE("cortex-r82", cortexr82, cortexa53,
> 8R, AARCH64_FL_FOR_ARCH8_R, cor
>  /* Arm ('A') cores. */
>  AARCH64_CORE("cortex-a510",  cortexa510, cortexa55, 9A,
> AARCH64_FL_FOR_ARCH9 | AARCH64_FL_SVE2_BITPERM |
> AARCH64_FL_MEMTAG | AARCH64_FL_I8MM | AARCH64_FL_BF16,
> neoversen2, 0x41, 0xd46, -1)
> 
> +AARCH64_CORE("cortex-a710",  cortexa710, cortexa55, 9A,
> +AARCH64_FL_FOR_ARCH9 | AARCH64_FL_SVE2_BITPERM |
> AARCH64_FL_MEMTAG |
> +AARCH64_FL_I8MM | AARCH64_FL_BF16, neoversen2, 0x41, 0xd47, -1)
> +
> 
> Again, we'd need to revisit big-core scheduling properly at some point, but
> for now I think for the scheduling field (3rd) we should use cortexa57 rather
> than cortexa55.
> Ok with that change.

commit f3cb2114d8b892fed0b6a717dab0a71d3da604bc

> Thanks,
> Kyrill



[PATCH v6] Fix for powerpc64 long double complex divide failure

2021-10-01 Thread Patrick McGehearty via Gcc-patches
- - - -

New in version 6: Due to an oversight (i.e. coding error), version 5
changed the use of __LIBGCC_TF_EPSILON__ to __LIBGCC_DF_EPSILON__ but
not the other LIBGCC_TF values. For correct execution of the long
double test case it is necessary to also switch to using
__LIBGCC_DF_MIN__. For consistency we also switch to using
__LIBGCC_DF_MAX__. LDBL_MIN is 2**53 times as larger than DBL_MIN.
The larger value causes the code to switch the order of computation
when it is not optimal, resulting in failure for one of the values
in the cdivchk_ld.c test. Using DBL_MIN does not cause that failure..

There may be opportunity for further refinement of IBM128 format
Long Double complex divide, but that's beyond the scope of this
patch.

- - - -

This revision adds a test in libgcc/libgcc2.c for when
"__LIBGCC_TF_MANT_DIG__ == 106" to use __LIBGCC_DF_EPSILON__ instead
of __LIBGCC_TF_EPSILON__. That is specific to IBM 128-bit format long
doubles where EPSILON is very, very small and 1/EPSILON oveflows to
infinity. This change avoids the overflow without affecting any other
platform. Discussion in the patch is adjusted to reflect this
limitation.

It does not make any changes to .../rs6000/_divkc3.c, leaving it to
use __LIBGCC_KF__*. That means the upstream gcc will not build in
older IBM environments that do not recognize the KF floating point
mode properly. Environments that do not need IBM longdouble support
do build cleanly.

- - - -
This patch addresses the failure of powerpc64 long double complex divide
in native ibm long double format after the patch "Practical improvement
to libgcc complex divide".

The new code uses the following macros which are intended to be mapped
to appropriate values according to the underlying hardware representation.
See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101104

RBIG a value near the maximum representation
RMIN a value near the minimum representation
 (but not in the subnormal range)
RMIN2a value moderately less than 1
RMINSCAL the inverse of RMIN2
RMAX2RBIG * RMIN2  - a value to limit scaling to not overflow

When "long double" values were not using the IEEE 128-bit format but
the traditional IBM 128-bit, the previous code used the LDBL values
which caused overflow for RMINSCAL. The new code uses the DBL values.

RBIG  LDBL_MAX = 0x1.f800p+1022
  DBL_MAX  = 0x1.f000p+1022

RMIN  LDBL_MIN = 0x1.p-969
RMIN  DBL_MIN  = 0x1.p-1022

RMIN2 LDBL_EPSILON = 0x0.1000p-1022 = 0x1.0p-1074
RMIN2 DBL_EPSILON  = 0x1.p-52

RMINSCAL 1/LDBL_EPSILON = inf (1.0p+1074 does not fit in IBM 128-bit).
 1/DBL_EPSILON  = 0x1.p+52

RMAX2 = RBIG * RMIN2 = 0x1.f800p-52
RBIG * RMIN2 = 0x1.f000p+970

The MAX and MIN values have only modest changes since the maximum and
minimum values are about the same as for double precision.  The
EPSILON field is considerably different. Due to how very small values
can be represented in the lower 64 bits of the IBM 128-bit floating
point, EPSILON is extremely small, so far beyond the desired value
that inversion of the value overflows and even without the overflow,
the RMAX2 is so small as to eliminate most usage of the test.

The change has been tested on gcc135.fsffrance.org and gains the
expected improvements in accuracy for long double complex divide.

libgcc/
PR target/101104
* libgcc2.c (RMIN2, RMINSCAL, RMAX2):
Use more correct values for native IBM 128-bit.
---
 libgcc/libgcc2.c | 15 +++
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/libgcc/libgcc2.c b/libgcc/libgcc2.c
index 38f935e..e66e6f0 100644
--- a/libgcc/libgcc2.c
+++ b/libgcc/libgcc2.c
@@ -1904,10 +1904,17 @@ NAME (TYPE x, int m)
 # define MODE  tc
 # define CEXT  __LIBGCC_TF_FUNC_EXT__
 # define NOTRUNC (!__LIBGCC_TF_EXCESS_PRECISION__)
-# define RBIG  (__LIBGCC_TF_MAX__ / 2)
-# define RMIN  (__LIBGCC_TF_MIN__)
-# define RMIN2 (__LIBGCC_TF_EPSILON__)
-# define RMINSCAL (1 / __LIBGCC_TF_EPSILON__)
+# if __LIBGCC_TF_MANT_DIG__ == 106
+#  define RBIG (__LIBGCC_DF_MAX__ / 2)
+#  define RMIN (__LIBGCC_DF_MIN__)
+#  define RMIN2  (__LIBGCC_DF_EPSILON__)
+#  define RMINSCAL (1 / __LIBGCC_DF_EPSILON__)
+# else
+#  define RBIG (__LIBGCC_TF_MAX__ / 2)
+#  define RMIN (__LIBGCC_TF_MIN__)
+#  define RMIN2(__LIBGCC_TF_EPSILON__)
+#  define RMINSCAL (1 / __LIBGCC_TF_EPSILON__)
+# endif
 # define RMAX2 (RBIG * RMIN2)
 #else
 # error
-- 
1.8.3.1



Re: [PATCH] c-family: Implement -Warray-compare [PR97573]

2021-10-01 Thread Jakub Jelinek via Gcc-patches
On Fri, Oct 01, 2021 at 04:11:08PM -0400, Marek Polacek via Gcc-patches wrote:
> +  auto_diagnostic_group d;
> +  if (warning_at (location, OPT_Warray_compare,
> +   "comparison between two arrays%s",
> +   (c_dialect_cxx () && cxx_dialect >= cxx20)
> +   ? " is deprecated in C++20" : ""))

Not a review, just a comment.
The above is impossible to translate, translators would translate the
first half and the second one would be in English; but even translating
the second part too would mean one can't reword it in some other language
in different word order.

You can e.g. use
  if (warning_at (location, OPT_Warray_compare,
  (c_dialect_cxx () && cxx_dialect >= cxx20)
  ? G_("comparison between two arrays is deprecated in C++20")
  : G_("comparison between two arrays")))
instead.

Jakub



[PATCH] c++: Do not warn about lifetime of std::initializer_list& [PR102482]

2021-10-01 Thread Jonathan Wakely via Gcc-patches
An initializer-list constructor taking a non-const lvalue cannot be
called with a temporary, so the array's lifetime probably doesn't end
with the full expression. -Winit-list-lifetime should not warn for that
case.

PR c++/102482

gcc/cp/ChangeLog:

* init.c (maybe_warn_list_ctor): Do not warn for a reference to
a non-const std::initializer_list.

gcc/testsuite/ChangeLog:

* g++.dg/warn/Winit-list5.C: New test.



Tested x86_64-linux. OK for trunk?


commit 474f2ae9c9f8312d9c732094bfb1c8da7342d6a9
Author: Jonathan Wakely 
Date:   Wed Sep 29 21:19:49 2021

c++: Do not warn about lifetime of std::initializer_list& [PR102482]

An initializer-list constructor taking a non-const lvalue cannot be
called with a temporary, so the array's lifetime probably doesn't end
with the full expression. -Winit-list-lifetime should not warn for that
case.

PR c++/102482

gcc/cp/ChangeLog:

* init.c (maybe_warn_list_ctor): Do not warn for a reference to
a non-const std::initializer_list.

gcc/testsuite/ChangeLog:

* g++.dg/warn/Winit-list5.C: New test.

diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 1426f9a5434..771a19bc402 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -749,8 +749,15 @@ maybe_warn_list_ctor (tree member, tree init)
   || !is_list_ctor (current_function_decl))
 return;
 
-  tree parms = FUNCTION_FIRST_USER_PARMTYPE (current_function_decl);
-  tree initlist = non_reference (TREE_VALUE (parms));
+  tree parm = FUNCTION_FIRST_USER_PARMTYPE (current_function_decl);
+  parm = TREE_VALUE (parm);
+  tree initlist = non_reference (parm);
+
+  /* Do not warn if the parameter is an lvalue reference to non-const.  */
+  if (TYPE_REF_P (parm) && !TYPE_REF_IS_RVALUE (parm)
+  && !CP_TYPE_CONST_P (initlist))
+return;
+
   tree targs = CLASSTYPE_TI_ARGS (initlist);
   tree elttype = TREE_VEC_ELT (targs, 0);
 
diff --git a/gcc/testsuite/g++.dg/warn/Winit-list5.C 
b/gcc/testsuite/g++.dg/warn/Winit-list5.C
new file mode 100644
index 000..07b3a69e46b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Winit-list5.C
@@ -0,0 +1,61 @@
+// PR c++/102482
+// { dg-do compile { target c++11 } }
+// Test we don't warn for non-const lvalue refs.
+
+#include 
+
+struct X { };
+
+struct span
+{
+  span(std::initializer_list& il)
+  : begin(il.begin()) // { dg-bogus "initializer_list" }
+  { }
+
+  const int* begin;
+};
+
+struct span_warn
+{
+  span_warn(std::initializer_list il)
+  : begin(il.begin()) // { dg-warning "initializer_list" }
+  { }
+
+  const int* begin;
+};
+
+struct span_warn2
+{
+  span_warn2(std::initializer_list&& il)
+  : begin(il.begin()) // { dg-warning "initializer_list" }
+  { }
+
+  const int* begin;
+};
+
+struct span_warn3
+{
+  span_warn3(std::initializer_list const& il)
+  : begin(il.begin()) // { dg-warning "initializer_list" }
+  { }
+
+  const int* begin;
+};
+
+struct span_warn4
+{
+  span_warn4(std::initializer_list const il)
+  : begin(il.begin()) // { dg-warning "initializer_list" }
+  { }
+
+  const int* begin;
+};
+
+struct span_warn5
+{
+  span_warn5(std::initializer_list const&& il)
+  : begin(il.begin()) // { dg-warning "initializer_list" }
+  { }
+
+  const int* begin;
+};


Re: [committed] libstdc++: Make std::jthread support pointers to member functions [PR 100612]

2021-10-01 Thread Jonathan Wakely via Gcc-patches
On Fri, 1 Oct 2021 at 21:26, Ville Voutilainen wrote:
>
> On Fri, 1 Oct 2021 at 23:19, Jonathan Wakely via Libstdc++
>  wrote:
> >
> > This adds a non-standard extension to support initializing a
> > std::jthread with a pointer to a member function that expects a
> > stop_token to be added to the arguments. That use case is not supported
> > by C++20, because the stop_token would get added as the first argument,
> > which is where the object argument needs to be to invoke a pointer to
> > member function.
>
> Yeah, and the use-case is supported by applying a wrapper that does
> the right kind of argument binding, like
> shown in the BZ. Why are we doing this?

The lambda workaround is not as convenient as having it Just Work. so
it seemed like a useful extension to try, with no downside. It doesn't
even change the is_constructible result , because the
std::thread constructor isn't constrained, so is_constructible is true for nearly all arg types anyway. The only
"non-conformance" is that we don't diagnose the
is_invocable_v, decay_t...> requirement if F is a
pointer-to-member-function.

Maybe I should have sent it as an RFC, or just left it in my fork not
pushed to trunk. If a proposal comes before the committee and gets
rejected then we can remove it again.



Re: [committed] libstdc++: Make std::jthread support pointers to member functions [PR 100612]

2021-10-01 Thread Ville Voutilainen via Gcc-patches
On Fri, 1 Oct 2021 at 23:19, Jonathan Wakely via Libstdc++
 wrote:
>
> This adds a non-standard extension to support initializing a
> std::jthread with a pointer to a member function that expects a
> stop_token to be added to the arguments. That use case is not supported
> by C++20, because the stop_token would get added as the first argument,
> which is where the object argument needs to be to invoke a pointer to
> member function.

Yeah, and the use-case is supported by applying a wrapper that does
the right kind of argument binding, like
shown in the BZ. Why are we doing this?


[committed] libstdc++: Restore printing of assertion messages [PR102100]

2021-10-01 Thread Jonathan Wakely via Gcc-patches
My changes for PR 101429 broke the _-replacement_assert function,
because we now always just abort without printing anything. That's
because I added checks for _GLIBCXX_HOSTED and _GLIBCXX_VERBOSE, but the
checks are done before those get defined.

This adds a new macro which is set
by the sed command in include/Makefile, once the HOSTED and VERBOSE
macros have been set by the configure script.

libstdc++-v3/ChangeLog:

PR libstdc++/102100
* include/Makefile.am (c++config.h): Define
_GLIBCXX_VERBOSE_ASSERT based on configure output.
* include/Makefile.in: Regenerate.
* include/bits/c++config: Fix condition for verbose assertions.

Tested powerpc64le-linux. Committed to trunk.

commit 92936be47461b99d624b6a90a745f6cdc60d3e51
Author: Jonathan Wakely 
Date:   Fri Oct 1 15:55:57 2021

libstdc++: Restore printing of assertion messages [PR102100]

My changes for PR 101429 broke the _-replacement_assert function,
because we now always just abort without printing anything. That's
because I added checks for _GLIBCXX_HOSTED and _GLIBCXX_VERBOSE, but the
checks are done before those get defined.

This adds a new macro which is set
by the sed command in include/Makefile, once the HOSTED and VERBOSE
macros have been set by the configure script.

libstdc++-v3/ChangeLog:

PR libstdc++/102100
* include/Makefile.am (c++config.h): Define
_GLIBCXX_VERBOSE_ASSERT based on configure output.
* include/Makefile.in: Regenerate.
* include/bits/c++config: Fix condition for verbose assertions.

diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index 15c0ad8dd03..5a5b5fd1d1b 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -1315,6 +1315,12 @@ ${host_builddir}/c++config.h: ${CONFIG_HEADER} \
grep "^[ ]*#[]*define[   ][  
]*_GLIBCXX_LONG_DOUBLE_ALT128_COMPAT[   ][  ]*1[]*$$" \
${CONFIG_HEADER} > /dev/null 2>&1 \
&& ldbl_alt128_compat='s,^#undef 
_GLIBCXX_LONG_DOUBLE_ALT128_COMPAT$$,#define _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT 
1,' ;\
+   verbose_assert='s,g,g,' ; \
+   grep "^[ ]*#[]*define[   ][  ]*_GLIBCXX_HOSTED[ 
 ][  ]*1[]*$$" \
+   ${CONFIG_HEADER} > /dev/null 2>&1 \
+   && grep "^[  ]*#[]*define[   ][  ]*_GLIBCXX_VERBOSE[
 ][  ]*1[]*$$" \
+   ${CONFIG_HEADER} > /dev/null 2>&1 \
+   && verbose_assert='s,^#undef _GLIBCXX_VERBOSE_ASSERT$$,#define 
_GLIBCXX_VERBOSE_ASSERT 1,' ;\
sed -e "s,define __GLIBCXX__,define __GLIBCXX__ $$date," \
-e "s,define _GLIBCXX_RELEASE,define _GLIBCXX_RELEASE $$release," \
-e "s,define _GLIBCXX_INLINE_VERSION, define _GLIBCXX_INLINE_VERSION 
$$ns_version," \
@@ -1326,6 +1332,7 @@ ${host_builddir}/c++config.h: ${CONFIG_HEADER} \
-e "s,define _GLIBCXX_USE_FLOAT128,$$float128," \
-e "$$ldbl_compat" \
-e "$$ldbl_alt128_compat" \
+   -e "$$verbose_assert" \
< ${glibcxx_srcdir}/include/bits/c++config > $@ ;\
sed -e 's/HAVE_/_GLIBCXX_HAVE_/g' \
-e 's/PACKAGE/_GLIBCXX_PACKAGE/g' \
diff --git a/libstdc++-v3/include/bits/c++config 
b/libstdc++-v3/include/bits/c++config
index 32b8957f814..69343a25533 100644
--- a/libstdc++-v3/include/bits/c++config
+++ b/libstdc++-v3/include/bits/c++config
@@ -506,11 +506,12 @@ namespace std
 # define __glibcxx_constexpr_assert(unevaluated)
 #endif
 
+#undef _GLIBCXX_VERBOSE_ASSERT
 
 // Assert.
 #if defined(_GLIBCXX_ASSERTIONS) \
   || defined(_GLIBCXX_PARALLEL) || defined(_GLIBCXX_PARALLEL_ASSERTIONS)
-# if _GLIBCXX_HOSTED && _GLIBCXX_VERBOSE
+# ifdef _GLIBCXX_VERBOSE_ASSERT
 namespace std
 {
   // Avoid the use of assert, because we're trying to keep the 
@@ -533,7 +534,7 @@ namespace std
 std::__replacement_assert(__FILE__, __LINE__, __PRETTY_FUNCTION__, \
  #_Condition);\
   }
-# else // ! VERBOSE
+# else // ! VERBOSE_ASSERT
 # define __glibcxx_assert_impl(_Condition) \
   if (__builtin_expect(!bool(_Condition), false))  \
   {\


Re: [PATCH] c++: Implement C++20 -Wdeprecated-array-compare [PR97573]

2021-10-01 Thread Marek Polacek via Gcc-patches
On Fri, Oct 01, 2021 at 09:30:41AM -0400, Jason Merrill wrote:
> On 9/30/21 17:56, Marek Polacek wrote:
> > On Thu, Sep 30, 2021 at 03:34:24PM -0400, Jason Merrill wrote:
> > > On 9/30/21 10:50, Marek Polacek wrote:
> > > > This patch addresses one of my leftovers from GCC 11.  C++20 introduced
> > > > [depr.array.comp]:
> > > > "Equality and relational comparisons between two operands of array type 
> > > > are
> > > > deprecated."
> > > > so this patch adds -Wdeprecated-array-compare (enabled by default in 
> > > > C++20).
> > > 
> > > Why not enable it by default in all modes?  It was always pretty dubious
> > > code.
> > 
> > Sure, it could be done, but it kind of complicates things: we'd probably
> > need a different option and a different message because it seems incorrect
> > to say "deprecated" in e.g. C++17 when this was only deprecated in C++20.
> 
> The warning could say "deprecated in C++20", which is always true?
> 
> > I'd rather not add another option; if it stays -Wdeprecated-array-compare
> > but -Wno-deprecated doesn't turn it off that also seems weird.
> > 
> > I could rename it to -Warray-compare, enable by -Wall, and only
> > append "is deprecated" to the warning message in C++20.  Does that seem
> > better?
> 
> That sounds fine too.

I did this so that I can add the warning to the C FE too.  Please
take a look at

if you get the chance, thanks.

So consider this patch discarded.  I wonder what I could do so that
Patchwork marks it as such, too.

Marek



[PATCH] c-family: Implement -Warray-compare [PR97573]

2021-10-01 Thread Marek Polacek via Gcc-patches
This patch addresses one of my leftovers from GCC 11.  C++20 introduced
[depr.array.comp]: "Equality and relational comparisons between two operands
of array type are deprecated." so this patch adds -Warray-compare.  Since the
code in question is dubious (the comparison doesn't actually compare the array
elements), I've added this warning for C too, and enabled it in all C++ modes.

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

PR c++/97573

gcc/c-family/ChangeLog:

* c-common.h (do_warn_array_compare): Declare.
* c-warn.c (do_warn_array_compare): New.
* c.opt (Warray-compare): New option.

gcc/c/ChangeLog:

* c-typeck.c (parser_build_binary_op): Call do_warn_array_compare.

gcc/cp/ChangeLog:

* typeck.c (cp_build_binary_op): Call do_warn_array_compare.

gcc/ChangeLog:

* doc/invoke.texi: Document -Warray-compare.

gcc/testsuite/ChangeLog:

* c-c++-common/Warray-compare-1.c: New test.
* c-c++-common/Warray-compare-2.c: New test.
---
 gcc/c-family/c-common.h   |  1 +
 gcc/c-family/c-warn.c | 32 ++
 gcc/c-family/c.opt|  4 ++
 gcc/c/c-typeck.c  |  9 +++-
 gcc/cp/typeck.c   | 13 ++
 gcc/doc/invoke.texi   | 20 -
 gcc/testsuite/c-c++-common/Warray-compare-1.c | 44 +++
 gcc/testsuite/c-c++-common/Warray-compare-2.c | 44 +++
 8 files changed, 164 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/c-c++-common/Warray-compare-1.c
 create mode 100644 gcc/testsuite/c-c++-common/Warray-compare-2.c

diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 849cefab882..078730f1e64 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -1421,6 +1421,7 @@ extern bool warn_for_restrict (unsigned, tree *, 
unsigned);
 extern void warn_for_address_or_pointer_of_packed_member (tree, tree);
 extern void warn_parm_array_mismatch (location_t, tree, tree);
 extern void maybe_warn_sizeof_array_div (location_t, tree, tree, tree, tree);
+extern void do_warn_array_compare (location_t, tree_code, tree, tree);
 
 /* Places where an lvalue, or modifiable lvalue, may be required.
Used to select diagnostic messages in lvalue_error and
diff --git a/gcc/c-family/c-warn.c b/gcc/c-family/c-warn.c
index 84ad6633c96..96aff1c0e5a 100644
--- a/gcc/c-family/c-warn.c
+++ b/gcc/c-family/c-warn.c
@@ -3726,3 +3726,35 @@ maybe_warn_sizeof_array_div (location_t loc, tree arr, 
tree arr_type,
}
 }
 }
+
+/* Warn about C++20 [depr.array.comp] array comparisons: "Equality
+   and relational comparisons between two operands of array type are
+   deprecated."  We also warn in C and earlier C++ standards.  CODE is
+   the code for this comparison, OP0 and OP1 are the operands.  */
+
+void
+do_warn_array_compare (location_t location, tree_code code, tree op0, tree op1)
+{
+  STRIP_NOPS (op0);
+  STRIP_NOPS (op1);
+  if (TREE_CODE (op0) == ADDR_EXPR)
+op0 = TREE_OPERAND (op0, 0);
+  if (TREE_CODE (op1) == ADDR_EXPR)
+op1 = TREE_OPERAND (op1, 0);
+
+  auto_diagnostic_group d;
+  if (warning_at (location, OPT_Warray_compare,
+ "comparison between two arrays%s",
+ (c_dialect_cxx () && cxx_dialect >= cxx20)
+ ? " is deprecated in C++20" : ""))
+{
+  /* C doesn't allow +arr.  */
+  if (c_dialect_cxx ())
+   inform (location, "use unary %<+%> which decays operands to pointers "
+   "or %<&%D[0] %s &%D[0]%> to compare the addresses",
+   op0, op_symbol_code (code), op1);
+  else
+   inform (location, "use %<&%D[0] %s &%D[0]%> to compare the addresses",
+   op0, op_symbol_code (code), op1);
+}
+}
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 9c151d19870..06457ac739e 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -350,6 +350,10 @@ Warray-bounds=
 LangEnabledBy(C ObjC C++ LTO ObjC++,Wall,1,0)
 ; in common.opt
 
+Warray-compare
+C ObjC C++ ObjC++ Var(warn_array_compare) Warning LangEnabledBy(C ObjC C++ 
ObjC++, Wall)
+Warn about comparisons between two operands of array type.
+
 Warray-parameter
 C ObjC C++ ObjC++ Warning Alias(Warray-parameter=, 2, 0)
 Warn about mismatched declarations of array parameters and unsafe accesses to 
them.
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 33963d7555a..f9eb0e5176f 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -3940,7 +3940,14 @@ parser_build_binary_op (location_t location, enum 
tree_code code,
   else if (TREE_CODE_CLASS (code) == tcc_comparison
   && (code1 == STRING_CST || code2 == STRING_CST))
 warning_at (location, OPT_Waddress,
-   "comparison with string literal results in unspecified 
behavior");
+   "comparison with string literal results in unspecified "
+   

[PATCH] c++: ttp variadic constraint subsumption [PR99904]

2021-10-01 Thread Patrick Palka via Gcc-patches
Here we're crashing when level-lowering the variadic constraints on the
template template parameter TT because tsubst_pack_expansion expects
processing_template_decl to be set during a partial substitution.

bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
trunk/11?  Also tested on cmcstl2 and range-v3.

PR c++/99904

gcc/cp/ChangeLog:

* pt.c (is_compatible_template_arg): Set processing_template_decl
around tsubst_constraint_info.

gcc/testsuite/ChangeLog:

* g++.dg/cpp2a/concepts-ttp4.C: New test.
---
 gcc/cp/pt.c| 2 ++
 gcc/testsuite/g++.dg/cpp2a/concepts-ttp4.C | 9 +
 2 files changed, 11 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-ttp4.C

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 1dcdffe322a..f950f4a21b7 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -8223,8 +8223,10 @@ is_compatible_template_arg (tree parm, tree arg)
 {
   tree aparms = DECL_INNERMOST_TEMPLATE_PARMS (arg);
   new_args = template_parms_level_to_args (aparms);
+  ++processing_template_decl;
   parm_cons = tsubst_constraint_info (parm_cons, new_args,
  tf_none, NULL_TREE);
+  --processing_template_decl;
   if (parm_cons == error_mark_node)
 return false;
 }
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-ttp4.C 
b/gcc/testsuite/g++.dg/cpp2a/concepts-ttp4.C
new file mode 100644
index 000..cf3e71ea974
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-ttp4.C
@@ -0,0 +1,9 @@
+// PR c++/99904
+// { dg-do compile { target c++20 } }
+
+template concept C = (Ts::value && ...);
+template requires C struct A;
+template requires true struct B;
+template requires C class TT> struct S;
+using ty1 = S;
+using ty2 = S; // { dg-error "constraint" } TT's constraints don't subsume 
B's
-- 
2.33.0.610.gcefe983a32



Re: [PATCH] c++: Suppress error when cv-qualified reference is introduced by typedef [PR101783]

2021-10-01 Thread Nick Huang via Gcc-patches
> ...the subject line for the commit should be the first line of the
> commit message, followed by a blank line, followed by the description of
> the patch; without the subject line, git format-patch thought your whole
> description was the subject of the patch.

oh,  I didn't realize this without your mentioning it. I read this guide
(https://gcc.gnu.org/codingconventions.html#ChangeLogs) many times
and still don't get this. I guess it was written long long ago.

> I've corrected this and pushed the patch, thanks!
I do thank you and without your help I might  never accomplish this task.
Once again appreciate your patient help!

On Fri, Oct 1, 2021 at 11:46 AM Jason Merrill  wrote:
>
> On 10/1/21 11:10, Nick Huang wrote:
> >> gcc-verify still fails with this version:
> >>
> >>> ERR: line should start with a tab: "PR c++/101783"
> >>> ERR: line should start with a tab: "* tree.c 
> >>> (cp_build_qualified_type_real): Excluding typedef from error"
> >>> ERR: line should start with a tab: "PR c++/101783"
> >>> ERR: line should start with a tab: "* g++.dg/parse/pr101783.C: New 
> >>> test."
> >
> >> It might work better to attach the output of git format-patch.
> > Sorry for my clumsy copy/paste from git commit message. I now attach
> > git format-patch output
> > file as attachment. Also maybe for a little convenience of your work,
> > I also attach the original
> > commit message file when I do git commit -F.
>
> Thanks, but that isn't necessary; it should be the same in the
> format-patch output, except...
>
> > From e592a475030d99647de736d294cb3c6a7588af49 Mon Sep 17 00:00:00 2001
> > From: qingzhe huang 
> > Date: Fri, 1 Oct 2021 10:46:35 -0400
> > Subject: [PATCH] The root cause of this bug is that it considers reference
> >  with cv-qualifiers as an error by generating value for variable 
> > "bad_quals".
> >  However, this is not correct for case of typedef. Here I quote spec
> >  [dcl.ref]/1 : "Cv-qualified references are ill-formed except when the
> >  cv-qualifiers are introduced through the use of a typedef-name
> >  ([dcl.typedef], [temp.param]) or decltype-specifier ([dcl.type.decltype]), 
> > in
> >  which case the cv-qualifiers are ignored."
>
> ...the subject line for the commit should be the first line of the
> commit message, followed by a blank line, followed by the description of
> the patch; without the subject line, git format-patch thought your whole
> description was the subject of the patch.
>
> I've corrected this and pushed the patch, thanks!
>
> Jason
>


-- 
nick huang/qingzhe huang
http://www.staroceans.com
http://www.staroceans.com/english.htm


[committed] libstdc++: Allow stateful allocators in std::list::sort [PR 66742]

2021-10-01 Thread Jonathan Wakely via Gcc-patches
The temporary lists used by std::list::sort are default constructed,
which means they use default constructed allocators. The sort operation
is defined in terms of merge and splice operations, which have undefined
behaviour (and abort) if the allocators do not compare equal. This means
it is not possible to sort a list that uses an allocator that compares
unequal to an default constructed allocator.

The solution is to avoid using temporary std::list objects at all. We do
not need to be able to allocate memory because no nodes are allocated,
only spliced from one list to another. That means the temporary lists
don't need an allocator at all, so whether it would compare equal
doesn't matter.

Instead of temporary std::list objects, we can just use a collection of
_List_node_base objects that nodes can be spliced onto as needed. Those
objects are wrapped in a _Scratch_list type that implements the splicing
and merging operations used by list::sort.

We also don't need to update the list size during the sort, because
sorting doesn't alter the number of nodes. Although we move nodes in and
out of the scratch lists, at the end of the function all nodes are back
in the original std::list and the scratch lists are empty.  So for the
cxx11 ABI we can avoid the _M_size modifications usually done when
splicing nodes.

Signed-off-by: Jonathan Wakely 

libstdc++-v3/ChangeLog:

PR libstdc++/66742
* include/bits/list.tcc (list::sort()): Use _Scratch_list
objects for splicing and merging.
(list::sort(StrictWeakOrdering)): Likewise.
* include/bits/stl_list.h (__detail::_Scratch_list): New type.
* src/c++98/list.cc (_List_node_base::_M_transfer): Add
assertion for --enable-libstdcxx-debug library.
* testsuite/23_containers/list/operations/66742.cc: New test.

Tested powerpc64le-linux. Committed to trunk.

commit ff7793bea465019683b3a07d7ffceb6eae22def5
Author: Jonathan Wakely 
Date:   Tue May 25 14:33:15 2021

libstdc++: Allow stateful allocators in std::list::sort [PR 66742]

The temporary lists used by std::list::sort are default constructed,
which means they use default constructed allocators. The sort operation
is defined in terms of merge and splice operations, which have undefined
behaviour (and abort) if the allocators do not compare equal. This means
it is not possible to sort a list that uses an allocator that compares
unequal to an default constructed allocator.

The solution is to avoid using temporary std::list objects at all. We do
not need to be able to allocate memory because no nodes are allocated,
only spliced from one list to another. That means the temporary lists
don't need an allocator at all, so whether it would compare equal
doesn't matter.

Instead of temporary std::list objects, we can just use a collection of
_List_node_base objects that nodes can be spliced onto as needed. Those
objects are wrapped in a _Scratch_list type that implements the splicing
and merging operations used by list::sort.

We also don't need to update the list size during the sort, because
sorting doesn't alter the number of nodes. Although we move nodes in and
out of the scratch lists, at the end of the function all nodes are back
in the original std::list and the scratch lists are empty.  So for the
cxx11 ABI we can avoid the _M_size modifications usually done when
splicing nodes.

Signed-off-by: Jonathan Wakely 

libstdc++-v3/ChangeLog:

PR libstdc++/66742
* include/bits/list.tcc (list::sort()): Use _Scratch_list
objects for splicing and merging.
(list::sort(StrictWeakOrdering)): Likewise.
* include/bits/stl_list.h (__detail::_Scratch_list): New type.
* src/c++98/list.cc (_List_node_base::_M_transfer): Add
assertion for --enable-libstdcxx-debug library.
* testsuite/23_containers/list/operations/66742.cc: New test.

diff --git a/libstdc++-v3/include/bits/list.tcc 
b/libstdc++-v3/include/bits/list.tcc
index 62b0ba1063a..7f4e1569ab1 100644
--- a/libstdc++-v3/include/bits/list.tcc
+++ b/libstdc++-v3/include/bits/list.tcc
@@ -485,21 +485,34 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
   if (this->_M_impl._M_node._M_next != >_M_impl._M_node
  && this->_M_impl._M_node._M_next->_M_next != >_M_impl._M_node)
   {
-list __carry;
-list __tmp[64];
-list * __fill = __tmp;
-list * __counter;
+   using __detail::_Scratch_list;
+   // The algorithm used here is largely unchanged from the SGI STL
+   // and is described in The C++ Standard Template Library by Plauger,
+   // Stepanov, Lee, Musser.
+   // Each element of *this is spliced out and merged into one of the
+   // sorted lists in __tmp, then all the lists in __tmp are merged
+   // together and then swapped back into *this.
+   

[committed] libstdc++: Make std::jthread support pointers to member functions [PR 100612]

2021-10-01 Thread Jonathan Wakely via Gcc-patches
This adds a non-standard extension to support initializing a
std::jthread with a pointer to a member function that expects a
stop_token to be added to the arguments. That use case is not supported
by C++20, because the stop_token would get added as the first argument,
which is where the object argument needs to be to invoke a pointer to
member function.

Signed-off-by: Jonathan Wakely 

libstdc++-v3/ChangeLog:

PR libstdc++/100612
* include/std/thread (__pmf_expects_stop_token): New variable
template to detect a pointer to member function that needs a
stop_token to be added to the arguments.
(jthread::__S_create): Use __pmf_expects_stop_token.
(jthread::__S_create_pmf): New function.
* testsuite/30_threads/jthread/100612.cc: New test.

Tested powerpc64le-linux. Committed to trunk.

commit 34e9407b3b4298bd587e0df2e0047679019b66cf
Author: Jonathan Wakely 
Date:   Thu May 20 22:36:16 2021

libstdc++: Make std::jthread support pointers to member functions [PR 
100612]

This adds a non-standard extension to support initializing a
std::jthread with a pointer to a member function that expects a
stop_token to be added to the arguments. That use case is not supported
by C++20, because the stop_token would get added as the first argument,
which is where the object argument needs to be to invoke a pointer to
member function.

Signed-off-by: Jonathan Wakely 

libstdc++-v3/ChangeLog:

PR libstdc++/100612
* include/std/thread (__pmf_expects_stop_token): New variable
template to detect a pointer to member function that needs a
stop_token to be added to the arguments.
(jthread::__S_create): Use __pmf_expects_stop_token.
(jthread::__S_create_pmf): New function.
* testsuite/30_threads/jthread/100612.cc: New test.

diff --git a/libstdc++-v3/include/std/thread b/libstdc++-v3/include/std/thread
index f51392ab42c..46519086aae 100644
--- a/libstdc++-v3/include/std/thread
+++ b/libstdc++-v3/include/std/thread
@@ -99,6 +99,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 #ifdef __cpp_lib_jthread
 
+#ifndef __STRICT_ANSI__
+template
+  constexpr bool __pmf_expects_stop_token = false;
+
+template
+  constexpr bool __pmf_expects_stop_token<_Callable, _Obj, _Args...>
+   = __and_>,
+is_invocable<_Callable, _Obj, stop_token, _Args...>>::value;
+#endif
+
   /// A thread that can be requested to stop and automatically joined.
   class jthread
   {
@@ -211,6 +221,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   static thread
   _S_create(stop_source& __ssrc, _Callable&& __f, _Args&&... __args)
   {
+#ifndef __STRICT_ANSI__
+   if constexpr (__pmf_expects_stop_token<_Callable, _Args...>)
+ return _S_create_pmf(__ssrc, __f, std::forward<_Args>(__args)...);
+   else
+#endif
if constexpr(is_invocable_v, stop_token,
decay_t<_Args>...>)
  return thread{std::forward<_Callable>(__f), __ssrc.get_token(),
@@ -226,6 +241,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  }
   }
 
+#ifndef __STRICT_ANSI__
+template
+  static thread
+  _S_create_pmf(stop_source& __ssrc, _Callable __f, _Obj&& __obj,
+   _Args&&... __args)
+  {
+   return thread{__f, std::forward<_Obj>(__obj), __ssrc.get_token(),
+ std::forward<_Args>(__args)...};
+  }
+#endif
+
 stop_source _M_stop_source;
 thread _M_thread;
   };
diff --git a/libstdc++-v3/testsuite/30_threads/jthread/100612.cc 
b/libstdc++-v3/testsuite/30_threads/jthread/100612.cc
new file mode 100644
index 000..d6c81706b8f
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/jthread/100612.cc
@@ -0,0 +1,24 @@
+// { dg-options "-std=gnu++20" }
+// { dg-do compile { target c++20 } }
+// { dg-additional-options "-pthread" { target pthread } }
+// { dg-require-gthreads "" }
+
+#include 
+
+void
+test_pfm()
+{
+  // PR libstdc++/100612
+  struct X
+  {
+void run(std::stop_token) { }
+void run_arg(int) { }
+void run_args(std::stop_token, int, int) { }
+  };
+
+  X x;
+
+  std::jthread{::run, };
+  std::jthread{::run_arg, , 1};
+  std::jthread{::run_args, , 1, 1};
+}


[committed] libstdc++: Add container adaptor constructors taking iterators (P1425R4)

2021-10-01 Thread Jonathan Wakely via Gcc-patches
This adds a feature that was recently added to the C++23 working draft.

Signed-off-by: Jonathan Wakely 

libstdc++-v3/ChangeLog:

* include/bits/stl_queue.h
(__cpp_lib_adaptor_iterator_pair_constructor): Define for C++23, as
per P1425R4.
(queue(InputIterator, InputIterator)): Likewise.
(queue(InputIterator, InputIterator, const Alloc&)): Likewise.
* include/bits/stl_stack.h
(__cpp_lib_adaptor_iterator_pair_constructor): Likewise.
(stack(InputIterator, InputIterator)): Likewise.
(stack(InputIterator, InputIterator, const Alloc&)): Likewise.
* include/std/version (__cpp_lib_adaptor_iterator_pair_constructor):
Define.
* testsuite/23_containers/queue/cons_from_iters.cc: New test.
* testsuite/23_containers/stack/cons_from_iters.cc: New test.

Tested powerpc64le-linux. Committed to trunk.

commit b7e8fb5e48279ffa5f424e3dd0bb3dfcbe69f5d5
Author: Jonathan Wakely 
Date:   Thu May 13 16:16:26 2021

libstdc++: Add container adaptor constructors taking iterators (P1425R4)

This adds a feature that was recently added to the C++23 working draft.

Signed-off-by: Jonathan Wakely 

libstdc++-v3/ChangeLog:

* include/bits/stl_queue.h
(__cpp_lib_adaptor_iterator_pair_constructor): Define for C++23, as
per P1425R4.
(queue(InputIterator, InputIterator)): Likewise.
(queue(InputIterator, InputIterator, const Alloc&)): Likewise.
* include/bits/stl_stack.h
(__cpp_lib_adaptor_iterator_pair_constructor): Likewise.
(stack(InputIterator, InputIterator)): Likewise.
(stack(InputIterator, InputIterator, const Alloc&)): Likewise.
* include/std/version (__cpp_lib_adaptor_iterator_pair_constructor):
Define.
* testsuite/23_containers/queue/cons_from_iters.cc: New test.
* testsuite/23_containers/stack/cons_from_iters.cc: New test.

diff --git a/libstdc++-v3/include/bits/stl_queue.h 
b/libstdc++-v3/include/bits/stl_queue.h
index 4519f9f2fec..ccd1122f848 100644
--- a/libstdc++-v3/include/bits/stl_queue.h
+++ b/libstdc++-v3/include/bits/stl_queue.h
@@ -194,6 +194,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template>
queue(queue&& __q, const _Alloc& __a)
: c(std::move(__q.c), __a) { }
+
+#if __cplusplus > 202002L
+#define __cpp_lib_adaptor_iterator_pair_constructor 202100L
+
+  template>
+   queue(_InputIterator __first, _InputIterator __last)
+   : c(__first, __last) { }
+
+  template,
+  typename = _Uses<_Alloc>>
+   queue(_InputIterator __first, _InputIterator __last, const _Alloc& __a)
+   : c(__first, __last, __a) { }
+#endif
 #endif
 
   /**
@@ -331,6 +346,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   typename = _RequireAllocator<_Allocator>>
 queue(_Container, _Allocator)
 -> queue;
+
+#ifdef __cpp_lib_adaptor_iterator_pair_constructor
+  template::value_type,
+  typename = _RequireInputIter<_InputIterator>>
+queue(_InputIterator, _InputIterator) -> queue<_ValT>;
+
+  template::value_type,
+  typename = _RequireInputIter<_InputIterator>,
+  typename = _RequireAllocator<_Allocator>>
+queue(_InputIterator, _InputIterator, _Allocator)
+-> queue<_ValT, deque<_ValT, _Allocator>>;
+#endif
 #endif
 
   /**
diff --git a/libstdc++-v3/include/bits/stl_stack.h 
b/libstdc++-v3/include/bits/stl_stack.h
index 85137b9d428..af234d6899c 100644
--- a/libstdc++-v3/include/bits/stl_stack.h
+++ b/libstdc++-v3/include/bits/stl_stack.h
@@ -170,6 +170,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   stack(_Sequence&& __c)
   : c(std::move(__c)) { }
 
+#if __cplusplus > 202002L
+#define __cpp_lib_adaptor_iterator_pair_constructor 202100L
+
+  template>
+   stack(_InputIterator __first, _InputIterator __last)
+   : c(__first, __last) { }
+#endif
+
+
   template>
explicit
stack(const _Alloc& __a)
@@ -190,6 +200,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template>
stack(stack&& __q, const _Alloc& __a)
: c(std::move(__q.c), __a) { }
+
+#if __cplusplus > 202002L
+  template,
+  typename = _Uses<_Alloc>>
+   stack(_InputIterator __first, _InputIterator __last, const _Alloc& __a)
+   : c(__first, __last, __a) { }
+#endif
 #endif
 
   /**
@@ -303,6 +321,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   typename = _RequireAllocator<_Allocator>>
 stack(_Container, _Allocator)
 -> stack;
+
+#ifdef __cpp_lib_adaptor_iterator_pair_constructor
+  template::value_type,
+  typename = _RequireInputIter<_InputIterator>>
+stack(_InputIterator, _InputIterator) -> stack<_ValT>;
+
+  template::value_type,
+  typename = _RequireInputIter<_InputIterator>,
+  typename = _RequireAllocator<_Allocator>>
+stack(_InputIterator, _InputIterator, _Allocator)
+-> stack<_ValT, 

[committed] libstdc++: Implement LWG 3506 for std::priority_queue

2021-10-01 Thread Jonathan Wakely via Gcc-patches
The LWG 3506 issue ads allocator-extended versions of the constructors
that take iterator arguments.

Signed-off-by: Jonathan Wakely 

libstdc++-v3/ChangeLog:

* include/bits/stl_queue.h (priority_queue): Add
allocator-extended overloads for constructors taking iterator.
* testsuite/23_containers/priority_queue/lwg3506.cc: New test.

Tested powerpc64le-linux. Committed to trunk.

commit 6ccffeb56b92041991aba923545532087e1977f5
Author: Jonathan Wakely 
Date:   Thu May 13 14:30:26 2021

libstdc++: Implement LWG 3506 for std::priority_queue

The LWG 3506 issue ads allocator-extended versions of the constructors
that take iterator arguments.

Signed-off-by: Jonathan Wakely 

libstdc++-v3/ChangeLog:

* include/bits/stl_queue.h (priority_queue): Add
allocator-extended overloads for constructors taking iterator.
* testsuite/23_containers/priority_queue/lwg3506.cc: New test.

diff --git a/libstdc++-v3/include/bits/stl_queue.h 
b/libstdc++-v3/include/bits/stl_queue.h
index f801ebda77f..4519f9f2fec 100644
--- a/libstdc++-v3/include/bits/stl_queue.h
+++ b/libstdc++-v3/include/bits/stl_queue.h
@@ -626,6 +626,49 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  c.insert(c.end(), __first, __last);
  std::make_heap(c.begin(), c.end(), comp);
}
+
+  // _GLIBCXX_RESOLVE_LIB_DEFECTS
+  // 3506. Missing allocator-extended constructors for priority_queue
+  template,
+  typename _Requires = _Uses<_Alloc>>
+   priority_queue(_InputIterator __first, _InputIterator __last,
+  const _Alloc& __alloc)
+   : c(__first, __last, __alloc), comp()
+   { std::make_heap(c.begin(), c.end(), comp); }
+
+  template,
+  typename _Requires = _Uses<_Alloc>>
+   priority_queue(_InputIterator __first, _InputIterator __last,
+  const _Compare& __x, const _Alloc& __alloc)
+   : c(__first, __last, __alloc), comp(__x)
+   { std::make_heap(c.begin(), c.end(), comp); }
+
+  template,
+  typename _Requires = _Uses<_Alloc>>
+   priority_queue(_InputIterator __first, _InputIterator __last,
+  const _Compare& __x, const _Sequence& __s,
+  const _Alloc& __alloc)
+   : c(__s, __alloc), comp(__x)
+   {
+ __glibcxx_requires_valid_range(__first, __last);
+ c.insert(c.end(), __first, __last);
+ std::make_heap(c.begin(), c.end(), comp);
+   }
+
+  template>
+   priority_queue(_InputIterator __first, _InputIterator __last,
+  const _Compare& __x, _Sequence&& __s,
+  const _Alloc& __alloc)
+   : c(std::move(__s), __alloc), comp(__x)
+   {
+ __glibcxx_requires_valid_range(__first, __last);
+ c.insert(c.end(), __first, __last);
+ std::make_heap(c.begin(), c.end(), comp);
+   }
 #endif
 
   /**
diff --git a/libstdc++-v3/testsuite/23_containers/priority_queue/lwg3506.cc 
b/libstdc++-v3/testsuite/23_containers/priority_queue/lwg3506.cc
new file mode 100644
index 000..c9c803df8d2
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/priority_queue/lwg3506.cc
@@ -0,0 +1,54 @@
+// { dg-do run { target c++11 } }
+
+#include 
+#include 
+#include 
+
+void
+test_lwg3506()
+{
+  // LWG 3506 Missing allocator-extended constructors for priority_queue
+
+  using Alloc = __gnu_test::uneq_allocator;
+
+  using Container = std::vector;
+
+  struct Queue : std::priority_queue
+  {
+using priority_queue::priority_queue;
+
+Alloc get_allocator() const { return c.get_allocator(); }
+  };
+
+  using Compare = Queue::value_compare;
+
+  const Alloc a1(1), a2(2), a3(3), a4(4);
+  const int vals[] = { 5, 3, 9, 1, 7 };
+  Container cont({ 20, 30, 40 }, Alloc(99));
+
+  Queue q1(vals, vals+5, a1);
+  VERIFY( q1.get_allocator() == a1 );
+  VERIFY( q1.size() == 5 );
+  VERIFY( q1.top() == 9 );
+
+  Queue q2(vals, vals+5, Compare(), a2);
+  VERIFY( q2.get_allocator() == a2 );
+  VERIFY( q2.size() == 5 );
+  VERIFY( q2.top() == 9 );
+
+  Queue q3(vals, vals+5, Compare(), cont, a3);
+  VERIFY( q3.get_allocator() == a3 );
+  VERIFY( q3.size() == 8 );
+  VERIFY( q3.top() == 40 );
+
+  Queue q4(vals, vals+5, Compare(), std::move(cont), a4);
+  VERIFY( q4.get_allocator() == a4 );
+  VERIFY( q4.size() == 8 );
+  VERIFY( q4.top() == 40 );
+  VERIFY( cont.empty() );
+}
+
+int main()
+{
+  test_lwg3506();
+}


[committed] libstdc++: Implement LWG 3529 for std::priority_queue

2021-10-01 Thread Jonathan Wakely via Gcc-patches
The LWG 3529 issue changes to use two overloads instead of one with a
default argument, so that the sequence can be initialized directly with
the iterator range when no sequence argument is provided.

Signed-off-by: Jonathan Wakely 

libstdc++-v3/ChangeLog:

* include/bits/stl_queue.h (priority_queue): Construct sequence
from iterators when no sequence argument is present (LWG 3529).
* testsuite/23_containers/priority_queue/lwg3529.cc: New test.

Tested powerpc64le-linux. Committed to trunk.

commit e79bde6ada42a47b0a266f1cc85efb2eed44e45a
Author: Jonathan Wakely 
Date:   Thu May 13 14:30:26 2021

libstdc++: Implement LWG 3529 for std::priority_queue

The LWG 3529 issue changes to use two overloads instead of one with a
default argument, so that the sequence can be initialized directly with
the iterator range when no sequence argument is provided.

Signed-off-by: Jonathan Wakely 

libstdc++-v3/ChangeLog:

* include/bits/stl_queue.h (priority_queue): Construct sequence
from iterators when no sequence argument is present (LWG 3529).
* testsuite/23_containers/priority_queue/lwg3529.cc: New test.

diff --git a/libstdc++-v3/include/bits/stl_queue.h 
b/libstdc++-v3/include/bits/stl_queue.h
index 5e7808c0247..f801ebda77f 100644
--- a/libstdc++-v3/include/bits/stl_queue.h
+++ b/libstdc++-v3/include/bits/stl_queue.h
@@ -594,13 +594,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  std::make_heap(c.begin(), c.end(), comp);
}
 #else
+  // _GLIBCXX_RESOLVE_LIB_DEFECTS
+  // 3529. priority_queue(first, last) should construct c with (first, 
last)
+  template>
+   priority_queue(_InputIterator __first, _InputIterator __last,
+  const _Compare& __x = _Compare())
+   : c(__first, __last), comp(__x)
+   { std::make_heap(c.begin(), c.end(), comp); }
+
   // _GLIBCXX_RESOLVE_LIB_DEFECTS
   // 3522. Missing requirement on InputIterator template parameter
   template>
priority_queue(_InputIterator __first, _InputIterator __last,
-  const _Compare& __x,
-  const _Sequence& __s)
+  const _Compare& __x, const _Sequence& __s)
: c(__s), comp(__x)
{
  __glibcxx_requires_valid_range(__first, __last);
@@ -611,8 +619,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template>
priority_queue(_InputIterator __first, _InputIterator __last,
-  const _Compare& __x = _Compare(),
-  _Sequence&& __s = _Sequence())
+  const _Compare& __x, _Sequence&& __s)
: c(std::move(__s)), comp(__x)
{
  __glibcxx_requires_valid_range(__first, __last);
diff --git a/libstdc++-v3/testsuite/23_containers/priority_queue/lwg3529.cc 
b/libstdc++-v3/testsuite/23_containers/priority_queue/lwg3529.cc
new file mode 100644
index 000..014b5aa0f35
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/priority_queue/lwg3529.cc
@@ -0,0 +1,13 @@
+// { dg-do compile { target c++11 } }
+
+#include 
+
+struct C : std::vector
+{
+  C(int*, int*) { }
+};
+
+int i;
+
+// LWG 3529. priority_queue(first, last) should construct c with (first, last)
+std::priority_queue q(, );


[committed] libstdc++: Implement LWG 3522 for std::priority_queue

2021-10-01 Thread Jonathan Wakely via Gcc-patches
The LWG 3522 issue constrains all constructors of container adaptors
that have InputIterator parameters.

Signed-off-by: Jonathan Wakely 

libstdc++-v3/ChangeLog:

* include/bits/stl_queue.h (priority_queue): Constrain
constructors with InputIterator parameters (LWG 3522).
* testsuite/23_containers/priority_queue/lwg3522.cc: New test.

Tested powerpc64le-linux. Committed to trunk.

commit e5c093e515c4d1745ea3887da21a49d196475da6
Author: Jonathan Wakely 
Date:   Thu May 13 14:30:26 2021

libstdc++: Implement LWG 3522 for std::priority_queue

The LWG 3522 issue constrains all constructors of container adaptors
that have InputIterator parameters.

Signed-off-by: Jonathan Wakely 

libstdc++-v3/ChangeLog:

* include/bits/stl_queue.h (priority_queue): Constrain
constructors with InputIterator parameters (LWG 3522).
* testsuite/23_containers/priority_queue/lwg3522.cc: New test.

diff --git a/libstdc++-v3/include/bits/stl_queue.h 
b/libstdc++-v3/include/bits/stl_queue.h
index 41ffc50d380..5e7808c0247 100644
--- a/libstdc++-v3/include/bits/stl_queue.h
+++ b/libstdc++-v3/include/bits/stl_queue.h
@@ -594,7 +594,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  std::make_heap(c.begin(), c.end(), comp);
}
 #else
-  template
+  // _GLIBCXX_RESOLVE_LIB_DEFECTS
+  // 3522. Missing requirement on InputIterator template parameter
+  template>
priority_queue(_InputIterator __first, _InputIterator __last,
   const _Compare& __x,
   const _Sequence& __s)
@@ -605,7 +608,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  std::make_heap(c.begin(), c.end(), comp);
}
 
-  template
+  template>
priority_queue(_InputIterator __first, _InputIterator __last,
   const _Compare& __x = _Compare(),
   _Sequence&& __s = _Sequence())
diff --git a/libstdc++-v3/testsuite/23_containers/priority_queue/lwg3522.cc 
b/libstdc++-v3/testsuite/23_containers/priority_queue/lwg3522.cc
new file mode 100644
index 000..c026438585b
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/priority_queue/lwg3522.cc
@@ -0,0 +1,24 @@
+// { dg-do compile { target c++11 } }
+
+#include 
+
+// LWG 3522
+// Missing requirement on InputIterator template parameter for priority_queue
+// constructors
+std::priority_queue x = {1, 2}; // { dg-error "could not convert" }
+
+using Q = std::priority_queue;
+using Compare = Q::value_compare;
+using Sequence = Q::container_type;
+
+static_assert( ! std::is_constructible(),
+  "priority_queue(InputIterator, InputIterator) is constrained" );
+
+static_assert( ! std::is_constructible(),
+  "priority_queue(InputIterator, InputIterator, const Compare&) "
+  " is constrained" );
+
+static_assert( ! std::is_constructible(),
+  "and with const Sequence lvalue argument" );
+static_assert( ! std::is_constructible(),
+  "and with Sequence rvalue argument" );


[committed] libstdc++: Implement LWG 3392 for std::ranges::distance

2021-10-01 Thread Jonathan Wakely via Gcc-patches
libstdc++-v3/ChangeLog:

* include/bits/ranges_base.h (ranges::distance): Split overload
into two (LWG 3392).
* testsuite/24_iterators/range_operations/lwg3392.cc: New test.

Tested powerpc64le-linux. Committed to trunk.

commit 20751fad19e1b0fb4272309dd6d7fde182b08dc1
Author: Jonathan Wakely 
Date:   Tue Jun 1 14:22:38 2021

libstdc++: Implement LWG 3392 for std::ranges::distance

libstdc++-v3/ChangeLog:

* include/bits/ranges_base.h (ranges::distance): Split overload
into two (LWG 3392).
* testsuite/24_iterators/range_operations/lwg3392.cc: New test.

diff --git a/libstdc++-v3/include/bits/ranges_base.h 
b/libstdc++-v3/include/bits/ranges_base.h
index d6166ab1dd3..01d0c35f4b4 100644
--- a/libstdc++-v3/include/bits/ranges_base.h
+++ b/libstdc++-v3/include/bits/ranges_base.h
@@ -787,22 +787,25 @@ namespace ranges
   struct __distance_fn final
   {
 template _Sent>
+  requires (!sized_sentinel_for<_Sent, _It>)
+  constexpr iter_difference_t<_It>
+  operator()[[nodiscard]](_It __first, _Sent __last) const
+  {
+   iter_difference_t<_It> __n = 0;
+   while (__first != __last)
+ {
+   ++__first;
+   ++__n;
+ }
+   return __n;
+  }
+
+template _Sent>
   [[nodiscard]]
   constexpr iter_difference_t<_It>
-  operator()(_It __first, _Sent __last) const
+  operator()(const _It& __first, const _Sent& __last) const
   {
-   if constexpr (sized_sentinel_for<_Sent, _It>)
- return __last - __first;
-   else
- {
-   iter_difference_t<_It> __n = 0;
-   while (__first != __last)
- {
-   ++__first;
-   ++__n;
- }
-   return __n;
- }
+   return __last - __first;
   }
 
 template
diff --git a/libstdc++-v3/testsuite/24_iterators/range_operations/lwg3392.cc 
b/libstdc++-v3/testsuite/24_iterators/range_operations/lwg3392.cc
new file mode 100644
index 000..32780353512
--- /dev/null
+++ b/libstdc++-v3/testsuite/24_iterators/range_operations/lwg3392.cc
@@ -0,0 +1,30 @@
+// { dg-options "-std=gnu++20" }
+// { dg-do compile { target c++20 } }
+
+#include 
+
+struct movable_iterator
+{
+  using difference_type = long;
+
+  movable_iterator() = default;
+  movable_iterator(movable_iterator&&) = default;
+  movable_iterator& operator=(movable_iterator&&) = default;
+
+  int operator*() const { return 1; }
+
+  movable_iterator& operator++() { return *this; }
+  void operator++(int) { }
+
+  bool operator==(const movable_iterator&) const = default;
+};
+
+using namespace std;
+
+constexpr counted_iterator it({}, 3);
+
+static_assert( sized_sentinel_for> );
+// LWG 3392
+// ranges::distance() cannot be used on a move-only iterator
+// with a sized sentinel
+static_assert( ranges::distance(it, default_sentinel) == 3 );


[committed] libstdc++: Remove unary_function base classes from std::thread tests

2021-10-01 Thread Jonathan Wakely via Gcc-patches
std::thread does not care if a function object is adaptable, so there is
no need to derive from the deprecated std::unary_function class in these
tests.

Signed-off-by: Jonathan Wakely 

libstdc++-v3/ChangeLog:

* testsuite/30_threads/thread/cons/3.cc: Remove derivation from
std::unary_function.
* testsuite/30_threads/thread/cons/4.cc: Likewise.
* testsuite/30_threads/thread/cons/5.cc: Likewise.

Tested powerpc64le-linux. Committed to trunk.

commit 9b790acc2207d69b4ebc0f4addd34a0aa32ec6cf
Author: Jonathan Wakely 
Date:   Mon May 24 18:32:22 2021

libstdc++: Remove unary_function base classes from std::thread tests

std::thread does not care if a function object is adaptable, so there is
no need to derive from the deprecated std::unary_function class in these
tests.

Signed-off-by: Jonathan Wakely 

libstdc++-v3/ChangeLog:

* testsuite/30_threads/thread/cons/3.cc: Remove derivation from
std::unary_function.
* testsuite/30_threads/thread/cons/4.cc: Likewise.
* testsuite/30_threads/thread/cons/5.cc: Likewise.

diff --git a/libstdc++-v3/testsuite/30_threads/thread/cons/3.cc 
b/libstdc++-v3/testsuite/30_threads/thread/cons/3.cc
index efdc631d950..6677156b7f2 100644
--- a/libstdc++-v3/testsuite/30_threads/thread/cons/3.cc
+++ b/libstdc++-v3/testsuite/30_threads/thread/cons/3.cc
@@ -21,12 +21,12 @@
 // .
 
 
-#include  // std::unary_function, std::ref
+#include  // std::ref
 #include 
 #include 
 #include 
 
-struct copyable : public std::unary_function
+struct copyable
 {
   copyable() = default;
   ~copyable() = default;
@@ -84,5 +84,4 @@ void test03()
 int main()
 {
   test03();
-  return 0;
 }
diff --git a/libstdc++-v3/testsuite/30_threads/thread/cons/4.cc 
b/libstdc++-v3/testsuite/30_threads/thread/cons/4.cc
index d74ad9715e3..9508cb45a1b 100644
--- a/libstdc++-v3/testsuite/30_threads/thread/cons/4.cc
+++ b/libstdc++-v3/testsuite/30_threads/thread/cons/4.cc
@@ -21,12 +21,12 @@
 // .
 
 
-#include  // std::unary_function, std::ref, std::cref
+#include  // std::ref, std::cref
 #include 
 #include 
 #include 
 
-struct noncopyable : std::unary_function
+struct noncopyable
 {
   noncopyable() = default;
   ~noncopyable() = default;
diff --git a/libstdc++-v3/testsuite/30_threads/thread/cons/5.cc 
b/libstdc++-v3/testsuite/30_threads/thread/cons/5.cc
index 74dcd84c058..6d4d6854b30 100644
--- a/libstdc++-v3/testsuite/30_threads/thread/cons/5.cc
+++ b/libstdc++-v3/testsuite/30_threads/thread/cons/5.cc
@@ -21,12 +21,12 @@
 // .
 
 
-#include  // std::unary_function, std::ref
+#include  // std::ref
 #include 
 #include 
 #include 
 
-struct nonconst : public std::unary_function
+struct nonconst
 {
   void operator()(std::thread::id& id)
   {


[committed] libstdc++: Remove useless base classes in pb_db tests

2021-10-01 Thread Jonathan Wakely via Gcc-patches
These function objects do not need to be adaptable, so stop deriving
from deprecated classes. Also the 'inline' keyword is redundant on
member functions defined in the class body.

Signed-off-by: Jonathan Wakely 

libstdc++-v3/ChangeLog:

* testsuite/ext/pb_ds/example/basic_multimap.cc: Remove
unnecesary derivation from std::unary_function.
* testsuite/ext/pb_ds/example/erase_if.cc: Likewise.
* testsuite/ext/pb_ds/example/hash_illegal_resize.cc: Likewise.
* testsuite/ext/pb_ds/example/hash_initial_size.cc: Likewise.
* testsuite/ext/pb_ds/example/hash_load_set_change.cc: Likewise.
* testsuite/ext/pb_ds/example/hash_mod.cc: Likewise.
* testsuite/ext/pb_ds/example/hash_resize.cc: Likewise.
* testsuite/ext/pb_ds/example/hash_shift_mask.cc: Likewise.
* testsuite/ext/pb_ds/example/priority_queue_dijkstra.cc:
Likewise.
* testsuite/ext/pb_ds/example/ranged_hash.cc: Likewise.
* testsuite/ext/pb_ds/example/store_hash.cc: Likewise.

Tested powerpc64le-linux. Committed to trunk.

commit e3869a48fc2e5fbb9e8eb7058e5176446479673f
Author: Jonathan Wakely 
Date:   Mon May 24 18:27:16 2021

libstdc++: Remove useless base classes in pb_db tests

These function objects do not need to be adaptable, so stop deriving
from deprecated classes. Also the 'inline' keyword is redundant on
member functions defined in the class body.

Signed-off-by: Jonathan Wakely 

libstdc++-v3/ChangeLog:

* testsuite/ext/pb_ds/example/basic_multimap.cc: Remove
unnecesary derivation from std::unary_function.
* testsuite/ext/pb_ds/example/erase_if.cc: Likewise.
* testsuite/ext/pb_ds/example/hash_illegal_resize.cc: Likewise.
* testsuite/ext/pb_ds/example/hash_initial_size.cc: Likewise.
* testsuite/ext/pb_ds/example/hash_load_set_change.cc: Likewise.
* testsuite/ext/pb_ds/example/hash_mod.cc: Likewise.
* testsuite/ext/pb_ds/example/hash_resize.cc: Likewise.
* testsuite/ext/pb_ds/example/hash_shift_mask.cc: Likewise.
* testsuite/ext/pb_ds/example/priority_queue_dijkstra.cc:
Likewise.
* testsuite/ext/pb_ds/example/ranged_hash.cc: Likewise.
* testsuite/ext/pb_ds/example/store_hash.cc: Likewise.

diff --git a/libstdc++-v3/testsuite/ext/pb_ds/example/basic_multimap.cc 
b/libstdc++-v3/testsuite/ext/pb_ds/example/basic_multimap.cc
index 1d0b49146b9..143f3ee62e3 100644
--- a/libstdc++-v3/testsuite/ext/pb_ds/example/basic_multimap.cc
+++ b/libstdc++-v3/testsuite/ext/pb_ds/example/basic_multimap.cc
@@ -51,9 +51,9 @@ using namespace __gnu_pbds;
 // A simple hash functor.
 // hash could serve instead of this functor, but it is not yet
 // standard everywhere.
-struct string_hash : public unary_function
+struct string_hash
 {
-  inline size_t
+  size_t
   operator()(const string& r_s) const
   {
 size_t ret = 0;
diff --git a/libstdc++-v3/testsuite/ext/pb_ds/example/erase_if.cc 
b/libstdc++-v3/testsuite/ext/pb_ds/example/erase_if.cc
index 74ed84676ed..bb8e9c494a5 100644
--- a/libstdc++-v3/testsuite/ext/pb_ds/example/erase_if.cc
+++ b/libstdc++-v3/testsuite/ext/pb_ds/example/erase_if.cc
@@ -48,7 +48,7 @@ using namespace __gnu_pbds;
 
 // The following functor takes a map's value-type object and returns
 // whether its key is between two numbers.
-struct between : public unary_function, bool>
+struct between
 {
   // Constructor taking two numbers determining a range.
   between(int b, int e) : m_b(b), m_e(e)
@@ -56,7 +56,7 @@ struct between : public unary_function, 
bool>
 
   // Operator determining whether a value-type object's key is within
   // the range.
-  inline bool
+  bool
   operator()(const pair& r_val)
   { return r_val.first >= m_b&&  r_val.first < m_e; }
 
diff --git a/libstdc++-v3/testsuite/ext/pb_ds/example/hash_illegal_resize.cc 
b/libstdc++-v3/testsuite/ext/pb_ds/example/hash_illegal_resize.cc
index d045b40654a..73eda50374c 100644
--- a/libstdc++-v3/testsuite/ext/pb_ds/example/hash_illegal_resize.cc
+++ b/libstdc++-v3/testsuite/ext/pb_ds/example/hash_illegal_resize.cc
@@ -62,9 +62,9 @@ using namespace __gnu_pbds;
 // A simple hash functor.
 // hash could serve instead of this functor, but it is not yet
 // standard everywhere.
-struct int_hash : public unary_function
+struct int_hash
 {
-  inline size_t
+  size_t
   operator()(const int& r_i) const
   { return r_i; }
 };
diff --git a/libstdc++-v3/testsuite/ext/pb_ds/example/hash_initial_size.cc 
b/libstdc++-v3/testsuite/ext/pb_ds/example/hash_initial_size.cc
index 0fe99d291ee..a69c9c99bd8 100644
--- a/libstdc++-v3/testsuite/ext/pb_ds/example/hash_initial_size.cc
+++ b/libstdc++-v3/testsuite/ext/pb_ds/example/hash_initial_size.cc
@@ -49,9 +49,9 @@ using namespace __gnu_pbds;
 // A simple hash functor.
 // hash could serve instead of this functor, but it is not yet
 // standard everywhere.
-struct 

[committed] libstdc++: Simplify __throw_out_of_range_fmt for freestanding

2021-10-01 Thread Jonathan Wakely via Gcc-patches
There is no point expanding the format string if we're just going to
abort instead of throw an exception. And for freestanding or non-verbose
builds we shouldn't do it either, to reduce the binary size.

Signed-off-by: Jonathan Wakely 

libstdc++-v3/ChangeLog:

* src/c++11/functexcept.cc (__throw_out_of_range_fmt): Do not
expand the format string for freestanding, or non-vebose, or if
we're just going to abort anyway.
* src/c++11/snprintf_lite.cc: Remove unused header and
declaration.

Tested powerpc64le-linux. Committed to trunk.

commit 44967af830a8d887f0d7b6848d40e1c0870b6b0e
Author: Jonathan Wakely 
Date:   Thu May 20 18:13:00 2021

libstdc++: Simplify __throw_out_of_range_fmt for freestanding

There is no point expanding the format string if we're just going to
abort instead of throw an exception. And for freestanding or non-verbose
builds we shouldn't do it either, to reduce the binary size.

Signed-off-by: Jonathan Wakely 

libstdc++-v3/ChangeLog:

* src/c++11/functexcept.cc (__throw_out_of_range_fmt): Do not
expand the format string for freestanding, or non-vebose, or if
we're just going to abort anyway.
* src/c++11/snprintf_lite.cc: Remove unused header and
declaration.

diff --git a/libstdc++-v3/src/c++11/functexcept.cc 
b/libstdc++-v3/src/c++11/functexcept.cc
index 6f0071391c7..d1570b69f15 100644
--- a/libstdc++-v3/src/c++11/functexcept.cc
+++ b/libstdc++-v3/src/c++11/functexcept.cc
@@ -88,6 +88,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   void
   __throw_out_of_range_fmt(const char* __fmt, ...)
   {
+#if _GLIBCXX_HOSTED && _GLIBCXX_VERBOSE && __cpp_exceptions
 const size_t __len = __builtin_strlen(__fmt);
 // We expect at most 2 numbers, and 1 short string. The additional
 // 512 bytes should provide more than enough space for expansion.
@@ -96,9 +97,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 va_list __ap;
 
 va_start(__ap, __fmt);
-__gnu_cxx::__snprintf_lite(__s, __alloca_size, __fmt, __ap);
-_GLIBCXX_THROW_OR_ABORT(out_of_range(_(__s)));
+__gnu_cxx::__snprintf_lite(__s, __alloca_size, _(__fmt), __ap);
+throw out_of_range(__s);
 va_end(__ap);  // Not reached.
+#else
+__throw_out_of_range(__fmt);
+#endif
   }
 
   void
diff --git a/libstdc++-v3/src/c++11/snprintf_lite.cc 
b/libstdc++-v3/src/c++11/snprintf_lite.cc
index dcf8421cac2..ffeb7bf64c0 100644
--- a/libstdc++-v3/src/c++11/snprintf_lite.cc
+++ b/libstdc++-v3/src/c++11/snprintf_lite.cc
@@ -24,17 +24,8 @@
 // .
 
 #include 
+#include 
 #include 
-#include 
-
-namespace std {
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-  template
-  int
-  __int_to_char(_CharT* __bufend, _ValueT __v, const _CharT* __lit,
-ios_base::fmtflags __flags, bool __dec);
-_GLIBCXX_END_NAMESPACE_VERSION
-}
 
 namespace __gnu_cxx {
 


[committed] libstdc++: Fix narrowing conversion in std::visit

2021-10-01 Thread Jonathan Wakely via Gcc-patches
Signed-off-by: Jonathan Wakely 

libstdc++-v3/ChangeLog:

* include/std/variant (__do_visit): Use variant_npos instead of
literal -1 that requires a narrowing conversion.

Tested powerpc64le-linux. Committed to trunk.

commit dc1b29508d765b874372f4b1737ac6dc86962506
Author: Jonathan Wakely 
Date:   Thu May 20 18:04:16 2021

libstdc++: Fix narrowing conversion in std::visit

Signed-off-by: Jonathan Wakely 

libstdc++-v3/ChangeLog:

* include/std/variant (__do_visit): Use variant_npos instead of
literal -1 that requires a narrowing conversion.

diff --git a/libstdc++-v3/include/std/variant b/libstdc++-v3/include/std/variant
index ddeefd9b35e..d50c6b7de1d 100644
--- a/libstdc++-v3/include/std/variant
+++ b/libstdc++-v3/include/std/variant
@@ -1830,7 +1830,8 @@ namespace __variant
  if constexpr (is_same_v<_Result_type, __variant_idx_cookie>
|| is_same_v<_Result_type, __variant_cookie>)
{
- return __gen_vtable_impl<_Ma, index_sequence<-1>>::
+ using _Npos = index_sequence;
+ return __gen_vtable_impl<_Ma, _Npos>::
__visit_invoke(std::forward<_Visitor>(__visitor),
   std::forward<_V0>(__v0));
}


[committed] libstdc++: Avoid unconditional use of errc::not_supported [PR 99327]

2021-10-01 Thread Jonathan Wakely via Gcc-patches
The errc::not_supported constant is only defined if ENOTSUP is defined,
which is not true for all targets. Many uses of errc::not_supported in
the filesystem library do not actually match the intended meaning of
ENOTSUP described by POSIX. They should be using ENOSYS instead
(i.e. errc::function_not_supported).

This change ensures that appropriate error codes are used by the
filesystem library. The remaining uses of errc::not_supported are
replaced with a call to a new helper function so that an alternative
value will be used on targets that don't support errc::not_supported.

Signed-off-by: Jonathan Wakely 

libstdc++-v3/ChangeLog:

PR libstdc++/99327
* src/filesystem/ops-common.h (__unsupported): New function to
return a suitable error code for missing functionality.
(posix::off_t): New typedef.
(posix::*): Set errno to ENOSYS instead of ENOTSUP for no-op
fallback implementations.
(do_copy_file): Replace uses of errc::not_supported.
* src/c++17/fs_ops.cc (fs::copy, fs::copy_file, create_dir)
(fs::create_directory, fs::create_directory_symlink)
(fs::create_hard_link, fs::create_symlink, fs::current_path)
(fs::equivalent, do_stat, fs::file_size, fs::hard_link_count)
(fs::last_write_time, fs::permissions, fs::read_symlink):
Replace uses of errc::not_supported.
(fs::resize_file): Qualify off_t.
* src/filesystem/ops.cc (fs::copy, fs::copy_file, create_dir)
(fs::create_directory, fs::create_directory_symlink)
(fs::create_hard_link, fs::create_symlink, fs::current_path)
(fs::equivalent, do_stat, fs::file_size, fs::last_write_time)
(fs::permissions, fs::read_symlink, fs::system_complete):
Replace uses of errc::not_supported.
(fs::resize_file): Qualify off_t and enable unconditionally.
* testsuite/19_diagnostics/system_error/cons-1.cc: Likewise.

Tested powerpc64le-linux. Committed to trunk.

commit 59ffa3e3dba5a7805585c61dd4387c5644249d52
Author: Jonathan Wakely 
Date:   Tue May 11 18:47:18 2021

libstdc++: Avoid unconditional use of errc::not_supported [PR 99327]

The errc::not_supported constant is only defined if ENOTSUP is defined,
which is not true for all targets. Many uses of errc::not_supported in
the filesystem library do not actually match the intended meaning of
ENOTSUP described by POSIX. They should be using ENOSYS instead
(i.e. errc::function_not_supported).

This change ensures that appropriate error codes are used by the
filesystem library. The remaining uses of errc::not_supported are
replaced with a call to a new helper function so that an alternative
value will be used on targets that don't support errc::not_supported.

Signed-off-by: Jonathan Wakely 

libstdc++-v3/ChangeLog:

PR libstdc++/99327
* src/filesystem/ops-common.h (__unsupported): New function to
return a suitable error code for missing functionality.
(posix::off_t): New typedef.
(posix::*): Set errno to ENOSYS instead of ENOTSUP for no-op
fallback implementations.
(do_copy_file): Replace uses of errc::not_supported.
* src/c++17/fs_ops.cc (fs::copy, fs::copy_file, create_dir)
(fs::create_directory, fs::create_directory_symlink)
(fs::create_hard_link, fs::create_symlink, fs::current_path)
(fs::equivalent, do_stat, fs::file_size, fs::hard_link_count)
(fs::last_write_time, fs::permissions, fs::read_symlink):
Replace uses of errc::not_supported.
(fs::resize_file): Qualify off_t.
* src/filesystem/ops.cc (fs::copy, fs::copy_file, create_dir)
(fs::create_directory, fs::create_directory_symlink)
(fs::create_hard_link, fs::create_symlink, fs::current_path)
(fs::equivalent, do_stat, fs::file_size, fs::last_write_time)
(fs::permissions, fs::read_symlink, fs::system_complete):
Replace uses of errc::not_supported.
(fs::resize_file): Qualify off_t and enable unconditionally.
* testsuite/19_diagnostics/system_error/cons-1.cc: Likewise.

diff --git a/libstdc++-v3/src/c++17/fs_ops.cc b/libstdc++-v3/src/c++17/fs_ops.cc
index 4f3715bbbec..cb2dc2c617e 100644
--- a/libstdc++-v3/src/c++17/fs_ops.cc
+++ b/libstdc++-v3/src/c++17/fs_ops.cc
@@ -353,7 +353,7 @@ fs::copy(const path& from, const path& to, copy_options 
options,
 }
   if (is_other(f) || is_other(t))
 {
-  ec = std::make_error_code(std::errc::not_supported);
+  ec = std::make_error_code(std::errc::invalid_argument);
   return;
 }
   if (is_directory(f) && is_regular_file(t))
@@ -412,7 +412,7 @@ fs::copy(const path& from, const path& to, copy_options 
options,
   else
 ec.clear();
 #else
-  ec = std::make_error_code(std::errc::not_supported);
+  ec = 

[committed] libstdc++: Add std::__conditional_t alias template

2021-10-01 Thread Jonathan Wakely via Gcc-patches
This change is inspired by the suggestion in
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1715r0.html

The new std::__conditional_t alias template is functionally equivalent
to std::conditional_t but should be more efficient to compile, due to
only ever instantiating two specializations (std::__conditional
and std::__conditional) rather than a new specialization for
every use of std::conditional.

The new alias template is also available in C++11, unlike the C++14
std::conditional_t alias.

Signed-off-by: Jonathan Wakely 

libstdc++-v3/ChangeLog:

* include/std/type_traits (__conditional): New class template
for internal uses of std::conditional.
(__conditional_t): New alias template to replace conditional_t.
(__and_, __or_, __result_of_memfun, __result_of_memobj): Use
__conditional_t instead of conditional::type.
* include/bits/atomic_base.h (__atomic_impl::_Diff): Likewise.
* include/bits/hashtable.h (_Hashtable): Likewise.
* include/bits/hashtable_policy.h (_Node_iterator, _Insert_base)
(_Local_iterator): Likewise. Replace typedefs with
using-declarations.
* include/bits/move.h (move_if_noexcept): Use __conditional_t.
* include/bits/parse_numbers.h (_Select_int_base): Likewise.
* include/bits/ptr_traits.h (__make_not_void): Likewise.
* include/bits/ranges_algobase.h (__copy_or_move_backward)
(__copy_or_move): Likewise.
* include/bits/ranges_base.h (borrowed_iterator_t): Likewise.
* include/bits/ranges_util.h (borrowed_subrange_t): Likewise.
* include/bits/regex_compiler.h (_BracketMatcher): Use
__conditional_t. Replace typedefs with using-declarations.
* include/bits/shared_ptr_base.h (__shared_count): Use
__conditional_t.
* include/bits/stl_algobase.h (__copy_move, __copy_move_backward):
Likewise.
* include/bits/stl_iterator.h (__detail::__clamp_iter_cat)
(reverse_iterator::iterator_concept)
(__make_move_if_noexcept_iterator)
(iterator_traits>)
(iterator_traits>): Likewise.
* include/bits/stl_pair.h (_PCC, pair::operator=): Likewise.
* include/bits/stl_tree.h (_Rb_tree::insert_return_type)
(_Rb_tree::_M_clone_node): Likewise.
* include/bits/unique_ptr.h (unique_ptr(unique_ptr&&)):
Likewise.
* include/bits/uses_allocator.h (__uses_alloc): Likewise.
(__is_uses_allocator_predicate): Likewise.
* include/debug/functions.h (__foreign_iterator_aux2): Likewise.
* include/experimental/any (any::_Manager, __any_caster):
Likewise.
* include/experimental/executor (async_completion): Likewise.
* include/experimental/functional (__boyer_moore_base_t):
Likewise.
* include/std/any (any::_Manager): Likewise.
* include/std/functional (__boyer_moore_base_t): Likewise.
* include/std/ranges (borrowed_iterator_t)
(borrowed_subrange_t, __detail::__maybe_present_t)
(__detail::__maybe_const_t, split_view): Likewise.
* include/std/tuple (__empty_not_final, tuple::operator=):
Likewise.
* include/std/variant (__detail::__variant::__get_t): Likewise.

Tested powerpc64le-linux. Committed to trunk.

commit a09bb4a852f82af02b3f965358cd44b0aa266a5b
Author: Jonathan Wakely 
Date:   Thu May 6 16:26:21 2021

libstdc++: Add std::__conditional_t alias template

This change is inspired by the suggestion in
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1715r0.html

The new std::__conditional_t alias template is functionally equivalent
to std::conditional_t but should be more efficient to compile, due to
only ever instantiating two specializations (std::__conditional
and std::__conditional) rather than a new specialization for
every use of std::conditional.

The new alias template is also available in C++11, unlike the C++14
std::conditional_t alias.

Signed-off-by: Jonathan Wakely 

libstdc++-v3/ChangeLog:

* include/std/type_traits (__conditional): New class template
for internal uses of std::conditional.
(__conditional_t): New alias template to replace conditional_t.
(__and_, __or_, __result_of_memfun, __result_of_memobj): Use
__conditional_t instead of conditional::type.
* include/bits/atomic_base.h (__atomic_impl::_Diff): Likewise.
* include/bits/hashtable.h (_Hashtable): Likewise.
* include/bits/hashtable_policy.h (_Node_iterator, _Insert_base)
(_Local_iterator): Likewise. Replace typedefs with
using-declarations.
* include/bits/move.h (move_if_noexcept): Use __conditional_t.
* include/bits/parse_numbers.h (_Select_int_base): Likewise.
* include/bits/ptr_traits.h (__make_not_void): Likewise.
* 

[committed] libstdc++: Add utility for creating std::error_code from OS errors

2021-10-01 Thread Jonathan Wakely via Gcc-patches
This adds a helper function to encapsulate obtaining an error code for
errors from OS calls. For Windows we want to use GetLastError() and the
system error category, but otherwise just use errno and the generic
error category.

This should not be used to replace existing uses of
ec.assign(errno, generic_category()) because in those cases we really do
want to get the value of errno, not a system-specific error. Only the
cases that currently use GetLastError() are replace by this new
function.

Signed-off-by: Jonathan Wakely 

libstdc++-v3/ChangeLog:

* src/filesystem/ops-common.h (last_error): New helper function.
(filesystem::do_space): Use last_error().
* src/c++17/fs_ops.cc (fs::absolute, fs::create_hard_link)
(fs::equivalent, fs::remove, fs::temp_directory_path): Use
last_error().
* src/filesystem/ops.cc (fs::create_hard_link)
(fs::remove, fs::temp_directory_path): Likewise.

Tested powerpc64le-linux. Committed to trunk.

commit d71476c9df931f3ca674941f1942b03eabea010d
Author: Jonathan Wakely 
Date:   Wed Feb 10 18:00:00 2021

libstdc++: Add utility for creating std::error_code from OS errors

This adds a helper function to encapsulate obtaining an error code for
errors from OS calls. For Windows we want to use GetLastError() and the
system error category, but otherwise just use errno and the generic
error category.

This should not be used to replace existing uses of
ec.assign(errno, generic_category()) because in those cases we really do
want to get the value of errno, not a system-specific error. Only the
cases that currently use GetLastError() are replace by this new
function.

Signed-off-by: Jonathan Wakely 

libstdc++-v3/ChangeLog:

* src/filesystem/ops-common.h (last_error): New helper function.
(filesystem::do_space): Use last_error().
* src/c++17/fs_ops.cc (fs::absolute, fs::create_hard_link)
(fs::equivalent, fs::remove, fs::temp_directory_path): Use
last_error().
* src/filesystem/ops.cc (fs::create_hard_link)
(fs::remove, fs::temp_directory_path): Likewise.

diff --git a/libstdc++-v3/src/c++17/fs_ops.cc b/libstdc++-v3/src/c++17/fs_ops.cc
index 2eac9977785..4f3715bbbec 100644
--- a/libstdc++-v3/src/c++17/fs_ops.cc
+++ b/libstdc++-v3/src/c++17/fs_ops.cc
@@ -113,7 +113,7 @@ fs::absolute(const path& p, error_code& ec)
   while (len > buf.size());
 
   if (len == 0)
-ec.assign((int)GetLastError(), std::system_category());
+ec = __last_system_error();
   else
 {
   buf.resize(len);
@@ -682,7 +682,7 @@ fs::create_hard_link(const path& to, const path& 
new_hard_link,
   if (CreateHardLinkW(new_hard_link.c_str(), to.c_str(), NULL))
 ec.clear();
   else
-ec.assign((int)GetLastError(), system_category());
+ec = __last_system_error();
 #else
   ec = std::make_error_code(std::errc::not_supported);
 #endif
@@ -874,12 +874,12 @@ fs::equivalent(const path& p1, const path& p2, 
error_code& ec) noexcept
   if (!h1 || !h2)
{
  if (!h1 && !h2)
-   ec.assign((int)GetLastError(), system_category());
+   ec = __last_system_error();
  return false;
}
   if (!h1.get_info() || !h2.get_info())
{
- ec.assign((int)GetLastError(), system_category());
+ ec = __last_system_error();
  return false;
}
   return h1.info.dwVolumeSerialNumber == h2.info.dwVolumeSerialNumber
@@ -1255,7 +1255,7 @@ fs::remove(const path& p, error_code& ec) noexcept
  return true;
}
   else if (!ec)
-   ec.assign((int)GetLastError(), system_category());
+   ec = __last_system_error();
 }
   else if (status_known(st))
 ec.clear();
diff --git a/libstdc++-v3/src/filesystem/ops-common.h 
b/libstdc++-v3/src/filesystem/ops-common.h
index bf26c06b7b5..e999e11b422 100644
--- a/libstdc++-v3/src/filesystem/ops-common.h
+++ b/libstdc++-v3/src/filesystem/ops-common.h
@@ -57,6 +57,18 @@
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  // Get the last OS error (for POSIX this is just errno).
+  inline error_code
+  __last_system_error() noexcept
+  {
+#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
+return {::GetLastError(), std::system_category()};
+#else
+return {errno, std::generic_category()};
+#endif
+  }
+
 namespace filesystem
 {
 namespace __gnu_posix
@@ -558,7 +570,7 @@ _GLIBCXX_BEGIN_NAMESPACE_FILESYSTEM
ec.clear();
   }
 else
-  ec.assign((int)GetLastError(), std::system_category());
+  ec = std::last_system_error();
 #else
 ec = std::make_error_code(std::errc::not_supported);
 #endif
@@ -583,7 +595,7 @@ _GLIBCXX_BEGIN_NAMESPACE_FILESYSTEM
   } while (len > buf.size());
 
 if (len == 0)
-  ec.assign((int)GetLastError(), std::system_category());
+  ec = __last_system_error();
 else
   ec.clear();
 
diff 

[committed] libstdc++: Optimize std::visit for the common case [PR 78113]

2021-10-01 Thread Jonathan Wakely via Gcc-patches
GCC does not do a good job of optimizing the table of function pointers
used for variant visitation. This avoids using the table for the common
case of visiting a single variant with a small number of alternative
types. Instead we use:

  switch(v.index())
  {
  case 0: return visitor(get<0>(v));
  case 1: return visitor(get<1>(v));
  ...
  }

It's not quite that simple, because get<1>(v) is ill-formed if the
variant only has one alternative, and similarly for each get.  We
need to ensure each case only applies the visitor if the index is in
range for the actual type we're dealing with, and tell the compiler that
the case is unreachable otherwise. We also need to invoke the visitor
via the __gen_vtable_impl::__visit_invoke function, to handle the raw
visitation cases used to implement std::variant assignments and
comparisons.

Because that gets quite verbose and repetitive, a macro is used to stamp
out the cases.

We also need to handle the valueless_by_exception case, but only for raw
visitation, because std::visit already checks for it before calling
__do_visit.

Signed-off-by: Jonathan Wakely 

libstdc++-v3/ChangeLog:

PR libstdc++/78113
* include/std/variant (__do_visit): Use a switch when we have a
single variant with a small number of alternatives.

Tested powerpc64le-linux. Committed to trunk.

commit cfb582f62791dfadc243d97d37f0b83ef77cf480
Author: Jonathan Wakely 
Date:   Tue May 4 23:31:48 2021

libstdc++: Optimize std::visit for the common case [PR 78113]

GCC does not do a good job of optimizing the table of function pointers
used for variant visitation. This avoids using the table for the common
case of visiting a single variant with a small number of alternative
types. Instead we use:

  switch(v.index())
  {
  case 0: return visitor(get<0>(v));
  case 1: return visitor(get<1>(v));
  ...
  }

It's not quite that simple, because get<1>(v) is ill-formed if the
variant only has one alternative, and similarly for each get.  We
need to ensure each case only applies the visitor if the index is in
range for the actual type we're dealing with, and tell the compiler that
the case is unreachable otherwise. We also need to invoke the visitor
via the __gen_vtable_impl::__visit_invoke function, to handle the raw
visitation cases used to implement std::variant assignments and
comparisons.

Because that gets quite verbose and repetitive, a macro is used to stamp
out the cases.

We also need to handle the valueless_by_exception case, but only for raw
visitation, because std::visit already checks for it before calling
__do_visit.

Signed-off-by: Jonathan Wakely 

libstdc++-v3/ChangeLog:

PR libstdc++/78113
* include/std/variant (__do_visit): Use a switch when we have a
single variant with a small number of alternatives.

diff --git a/libstdc++-v3/include/std/variant b/libstdc++-v3/include/std/variant
index c651326ead9..19b2158690a 100644
--- a/libstdc++-v3/include/std/variant
+++ b/libstdc++-v3/include/std/variant
@@ -485,6 +485,12 @@ namespace __variant
   {
if constexpr (__variant::__never_valueless<_Types...>())
  return true;
+   // It would be nice if we could just return true for -fno-exceptions.
+   // It's possible (but inadvisable) that a std::variant could become
+   // valueless in a translation unit compiled with -fexceptions and then
+   // be passed to functions compiled with -fno-exceptions. We would need
+   // some #ifdef _GLIBCXX_NO_EXCEPTIONS_GLOBALLY property to elide all
+   // checks for valueless_by_exception().
return this->_M_index != static_cast<__index_type>(variant_npos);
   }
 
@@ -1754,12 +1760,89 @@ namespace __variant
 constexpr decltype(auto)
 __do_visit(_Visitor&& __visitor, _Variants&&... __variants)
 {
-  constexpr auto& __vtable = __detail::__variant::__gen_vtable<
-   _Result_type, _Visitor&&, _Variants&&...>::_S_vtable;
+  // Get the silly case of visiting no variants out of the way first.
+  if constexpr (sizeof...(_Variants) == 0)
+   return std::forward<_Visitor>(__visitor)();
+  else
+   {
+ constexpr size_t __max = 11; // "These go to eleven."
 
-  auto __func_ptr = __vtable._M_access(__variants.index()...);
-  return (*__func_ptr)(std::forward<_Visitor>(__visitor),
-  std::forward<_Variants>(__variants)...);
+ // The type of the first variant in the pack.
+ using _V0
+   = typename __detail::__variant::_Nth_type<0, _Variants...>::type;
+ // The number of alternatives in that first variant.
+ constexpr auto __n = variant_size_v>;
+
+ if constexpr (sizeof...(_Variants) > 1 || __n > __max)
+   {
+ // Use a jump table for the general case.
+ constexpr auto& 

[committed] libstdc++: Allow visiting inherited variants [PR 90943]

2021-10-01 Thread Jonathan Wakely via Gcc-patches
Implement the changes from P2162R2 (as a DR for C++17).

Signed-off-by: Jonathan Wakely 

libstdc++-v3/ChangeLog:

PR libstdc++/90943
* include/std/variant (__cpp_lib_variant): Update value.
(__detail::__variant::__as): New helpers implementing the
as-variant exposition-only function templates.
(visit, visit): Use __as to upcast the variant parameters.
* include/std/version (__cpp_lib_variant): Update value.
* testsuite/20_util/variant/visit_inherited.cc: New test.

Tested powerpc64le-linux. Committed to trunk.

commit c46ecb0112e91c80ee111439e79a58a953e4479d
Author: Jonathan Wakely 
Date:   Mon Apr 19 14:49:12 2021

libstdc++: Allow visiting inherited variants [PR 90943]

Implement the changes from P2162R2 (as a DR for C++17).

Signed-off-by: Jonathan Wakely 

libstdc++-v3/ChangeLog:

PR libstdc++/90943
* include/std/variant (__cpp_lib_variant): Update value.
(__detail::__variant::__as): New helpers implementing the
as-variant exposition-only function templates.
(visit, visit): Use __as to upcast the variant parameters.
* include/std/version (__cpp_lib_variant): Update value.
* testsuite/20_util/variant/visit_inherited.cc: New test.

diff --git a/libstdc++-v3/include/std/variant b/libstdc++-v3/include/std/variant
index 6383cf4e502..c651326ead9 100644
--- a/libstdc++-v3/include/std/variant
+++ b/libstdc++-v3/include/std/variant
@@ -71,7 +71,7 @@ namespace __variant
 } // namespace __variant
 } // namespace __detail
 
-#define __cpp_lib_variant 201606L
+#define __cpp_lib_variant 202102L
 
   template class tuple;
   template class variant;
@@ -202,6 +202,28 @@ namespace __variant
  std::forward<_Variants>(__variants)...);
 }
 
+  // The __as function templates implement the exposition-only "as-variant"
+
+  template
+constexpr std::variant<_Types...>&
+__as(std::variant<_Types...>& __v)
+{ return __v; }
+
+  template
+constexpr const std::variant<_Types...>&
+__as(const std::variant<_Types...>& __v) noexcept
+{ return __v; }
+
+  template
+constexpr std::variant<_Types...>&&
+__as(std::variant<_Types...>&& __v) noexcept
+{ return std::move(__v); }
+
+  template
+constexpr const std::variant<_Types...>&&
+__as(const std::variant<_Types...>&& __v) noexcept
+{ return std::move(__v); }
+
   // _Uninitialized is guaranteed to be a trivially destructible type,
   // even if T is not.
   template>
@@ -1063,8 +1085,12 @@ namespace __variant
  std::index_sequence<__indices...>>
 : _Base_dedup<__indices, __poison_hash>>... { };
 
-  template
-using __get_t = decltype(std::get<_Np>(std::declval<_Variant>()));
+  // Equivalent to decltype(get<_Np>(as-variant(declval<_Variant>(
+  template())),
+  typename _Tp = variant_alternative_t<_Np, remove_reference_t<_AsV>>>
+using __get_t
+  = conditional_t, _Tp&, _Tp&&>;
 
   // Return type of std::visit.
   template
@@ -1741,7 +1767,9 @@ namespace __variant
 constexpr __detail::__variant::__visit_result_t<_Visitor, _Variants...>
 visit(_Visitor&& __visitor, _Variants&&... __variants)
 {
-  if ((__variants.valueless_by_exception() || ...))
+  namespace __variant = std::__detail::__variant;
+
+  if ((__variant::__as(__variants).valueless_by_exception() || ...))
__throw_bad_variant_access("std::visit: variant is valueless");
 
   using _Result_type
@@ -1751,10 +1779,11 @@ namespace __variant
 
   if constexpr (sizeof...(_Variants) == 1)
{
+ using _Vp = decltype(__variant::__as(std::declval<_Variants>()...));
+
  constexpr bool __visit_rettypes_match = __detail::__variant::
-   __check_visitor_results<_Visitor, _Variants...>(
- std::make_index_sequence<
-   std::variant_size...>::value>());
+   __check_visitor_results<_Visitor, _Vp>(
+ make_index_sequence>>());
  if constexpr (!__visit_rettypes_match)
{
  static_assert(__visit_rettypes_match,
@@ -1765,12 +1794,12 @@ namespace __variant
  else
return std::__do_visit<_Tag>(
  std::forward<_Visitor>(__visitor),
- std::forward<_Variants>(__variants)...);
+ static_cast<_Vp>(__variants)...);
}
   else
return std::__do_visit<_Tag>(
  std::forward<_Visitor>(__visitor),
- std::forward<_Variants>(__variants)...);
+ __variant::__as(std::forward<_Variants>(__variants))...);
 }
 
 #if __cplusplus > 201703L
@@ -1778,11 +1807,13 @@ namespace __variant
 constexpr _Res
 visit(_Visitor&& __visitor, _Variants&&... __variants)
 {
-  if ((__variants.valueless_by_exception() || ...))
+  namespace __variant = std::__detail::__variant;
+
+  if ((__variant::__as(__variants).valueless_by_exception() || 

[committed] libstdc++: Simplify __normal_iterator converting constructor

2021-10-01 Thread Jonathan Wakely via Gcc-patches
This uses C++11 features to simplify the definition of the
__normal_iterator constructor that allows converting from iterator to
const_iterator. The previous definition relied on _Container::pointer
which is present in std::vector and std::basic_string, but is not
actually part of the container requirements.

Removing the use of _Container::pointer and defining it in terms of
is_convertible allows __normal_iterator to be used with new container
types which do not define a pointer member. Specifically, this will
allow it to be used in std::basic_stacktrace.

In theory this will enable some conversions which were not previously
permitted, for example __normal_iterator> can
now be converted to __normal_iterator>.
In practice this doesn't matter because the library never uses such
types.  In any case, allowing those conversions is consistent with
the corresponding constructors of std::reverse_iterator and
std::move_iterator.

Signed-off-by: Jonathan Wakely 

libstdc++-v3/ChangeLog:

* include/bits/stl_iterator.h (__normal_iterator): Simplify
converting constructor and do not require _Container::pointer.

Tested powerpc64le-linux. Committed to trunk.

commit fb4d55ef61ca3191ec946d4d41e0e715f4cc4197
Author: Jonathan Wakely 
Date:   Thu May 6 13:44:36 2021

libstdc++: Simplify __normal_iterator converting constructor

This uses C++11 features to simplify the definition of the
__normal_iterator constructor that allows converting from iterator to
const_iterator. The previous definition relied on _Container::pointer
which is present in std::vector and std::basic_string, but is not
actually part of the container requirements.

Removing the use of _Container::pointer and defining it in terms of
is_convertible allows __normal_iterator to be used with new container
types which do not define a pointer member. Specifically, this will
allow it to be used in std::basic_stacktrace.

In theory this will enable some conversions which were not previously
permitted, for example __normal_iterator> can
now be converted to __normal_iterator>.
In practice this doesn't matter because the library never uses such
types.  In any case, allowing those conversions is consistent with
the corresponding constructors of std::reverse_iterator and
std::move_iterator.

Signed-off-by: Jonathan Wakely 

libstdc++-v3/ChangeLog:

* include/bits/stl_iterator.h (__normal_iterator): Simplify
converting constructor and do not require _Container::pointer.

diff --git a/libstdc++-v3/include/bits/stl_iterator.h 
b/libstdc++-v3/include/bits/stl_iterator.h
index 8517652a173..df774eeb63f 100644
--- a/libstdc++-v3/include/bits/stl_iterator.h
+++ b/libstdc++-v3/include/bits/stl_iterator.h
@@ -1022,6 +1022,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   typedef std::iterator_traits<_Iterator>  __traits_type;
 
+#if __cplusplus >= 201103L
+  template
+   using __convertible_from
+ = std::__enable_if_t::value>;
+#endif
+
 public:
   typedef _Iteratoriterator_type;
   typedef typename __traits_type::iterator_category iterator_category;
@@ -1042,12 +1048,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   : _M_current(__i) { }
 
   // Allow iterator to const_iterator conversion
+#if __cplusplus >= 201103L
+  template>
+   _GLIBCXX20_CONSTEXPR
+   __normal_iterator(const __normal_iterator<_Iter, _Container>& __i)
+   noexcept
+#else
+  // N.B. _Container::pointer is not actually in container requirements,
+  // but is present in std::vector and std::basic_string.
   template
-_GLIBCXX20_CONSTEXPR
 __normal_iterator(const __normal_iterator<_Iter,
  typename __enable_if<
-  (std::__are_same<_Iter, typename _Container::pointer>::__value),
- _Container>::__type>& __i) _GLIBCXX_NOEXCEPT
+  (std::__are_same<_Iter, typename _Container::pointer>::__value),
+ _Container>::__type>& __i)
+#endif
 : _M_current(__i.base()) { }
 
   // Forward iterator requirements


[committed] libstdc++: Make move ctor noexcept for fully-dynamic string

2021-10-01 Thread Jonathan Wakely via Gcc-patches
The move constructor for the "fully-dynamic" COW string is not noexcept,
because it allocates a new empty string rep for the moved-from string.
However, there is no need to do that, because the moved-from string does
not have to be left empty. Instead, implement move construction for the
fully-dynamic case as a reference count increment, so the string is
shared.

Signed-off-by: Jonathan Wakely 

libstdc++-v3/ChangeLog:

* include/bits/cow_string.h [_GLIBCXX_FULLY_DYNAMIC_STRING]
(basic_string(basic_string&&)): Add noexcept and avoid
allocation, by sharing rep with the rvalue string.

Tested powerpc64le-linux. Committed to trunk.

commit 10b6d89baddd86139480ba902f491903fcb464a6
Author: Jonathan Wakely 
Date:   Fri Apr 30 15:04:34 2021

libstdc++: Make move ctor noexcept for fully-dynamic string

The move constructor for the "fully-dynamic" COW string is not noexcept,
because it allocates a new empty string rep for the moved-from string.
However, there is no need to do that, because the moved-from string does
not have to be left empty. Instead, implement move construction for the
fully-dynamic case as a reference count increment, so the string is
shared.

Signed-off-by: Jonathan Wakely 

libstdc++-v3/ChangeLog:

* include/bits/cow_string.h [_GLIBCXX_FULLY_DYNAMIC_STRING]
(basic_string(basic_string&&)): Add noexcept and avoid
allocation, by sharing rep with the rvalue string.

diff --git a/libstdc++-v3/include/bits/cow_string.h 
b/libstdc++-v3/include/bits/cow_string.h
index 61edaa85484..ba4a8cc2e98 100644
--- a/libstdc++-v3/include/bits/cow_string.h
+++ b/libstdc++-v3/include/bits/cow_string.h
@@ -620,18 +620,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  The newly-created string contains the exact contents of @a __str.
*  @a __str is a valid, but unspecified string.
*/
-  basic_string(basic_string&& __str)
+  basic_string(basic_string&& __str) noexcept
 #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
-  noexcept // FIXME C++11: should always be noexcept.
-#endif
   : _M_dataplus(std::move(__str._M_dataplus))
   {
-#if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
__str._M_data(_S_empty_rep()._M_refdata());
-#else
-   __str._M_data(_S_construct(size_type(), _CharT(), get_allocator()));
-#endif
   }
+#else
+  : _M_dataplus(__str._M_rep())
+  {
+   // Rather than allocate an empty string for the rvalue string,
+   // just share ownership with it by incrementing the reference count.
+   // If the rvalue string was "leaked" then it was the unique owner,
+   // so need an extra increment to indicate shared ownership.
+   if (_M_rep()->_M_is_leaked())
+ __gnu_cxx::__atomic_add_dispatch(&_M_rep()->_M_refcount, 2);
+   else
+ __gnu_cxx::__atomic_add_dispatch(&_M_rep()->_M_refcount, 1);
+  }
+#endif
 
   /**
*  @brief  Construct string from an initializer %list.


[committed] libstdc++: Add noexcept to common_iterator proxy operators

2021-10-01 Thread Jonathan Wakely via Gcc-patches
Signed-off-by: Jonathan Wakely 

libstdc++-v3/ChangeLog:

* include/bits/stl_iterator.h (common_iterator::__arrow_proxy)
(common_iterator::__postfix_proxy): Add noexcept.

Tested powerpc64le-linux. Committed to trunk.

commit ce709ad3dc0ed5d7ea48a116311d4441225446f0
Author: Jonathan Wakely 
Date:   Fri Apr 30 14:43:54 2021

libstdc++: Add noexcept to common_iterator proxy operators

Signed-off-by: Jonathan Wakely 

libstdc++-v3/ChangeLog:

* include/bits/stl_iterator.h (common_iterator::__arrow_proxy)
(common_iterator::__postfix_proxy): Add noexcept.

diff --git a/libstdc++-v3/include/bits/stl_iterator.h 
b/libstdc++-v3/include/bits/stl_iterator.h
index 4973f792b56..8517652a173 100644
--- a/libstdc++-v3/include/bits/stl_iterator.h
+++ b/libstdc++-v3/include/bits/stl_iterator.h
@@ -1813,7 +1813,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 public:
   const iter_value_t<_It>*
-  operator->() const
+  operator->() const noexcept
   { return std::__addressof(_M_keep); }
 };
 
@@ -1828,7 +1828,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 public:
   const iter_value_t<_It>&
-  operator*() const
+  operator*() const noexcept
   { return _M_keep; }
 };
 


[committed] libstdc++: Use conditional noexcept in std::reverse_iterator [PR 94418]

2021-10-01 Thread Jonathan Wakely via Gcc-patches
This adds a noexcept-specifier to each constructor and assignment
operator of std::reverse_iterator so that they are noexcept when the
corresponding operation on the underlying iterator is noexcept.

The std::reverse_iterator class template already requires that the
operations on the underlying type are valid, so we don't need to use the
std::is_nothrow_xxx traits to protect against errors when the expression
isn't even valid. We can just use a noexcept operator to test if the
expression can throw, without the overhead of redundantly checking if
the initialization/assignment would be valid.

Signed-off-by: Jonathan Wakely 

libstdc++-v3/ChangeLog:

PR libstdc++/94418
* include/bits/stl_iterator.h (reverse_iterator): Use
conditional noexcept on constructors and assignment operators.
* testsuite/24_iterators/reverse_iterator/noexcept.cc: New test.

Tested powerpc64le-linux. Committed to trunk.

commit d335d73889d897d073b987b4323db05317fccad3
Author: Jonathan Wakely 
Date:   Wed Apr 28 11:40:47 2021

libstdc++: Use conditional noexcept in std::reverse_iterator [PR 94418]

This adds a noexcept-specifier to each constructor and assignment
operator of std::reverse_iterator so that they are noexcept when the
corresponding operation on the underlying iterator is noexcept.

The std::reverse_iterator class template already requires that the
operations on the underlying type are valid, so we don't need to use the
std::is_nothrow_xxx traits to protect against errors when the expression
isn't even valid. We can just use a noexcept operator to test if the
expression can throw, without the overhead of redundantly checking if
the initialization/assignment would be valid.

Signed-off-by: Jonathan Wakely 

libstdc++-v3/ChangeLog:

PR libstdc++/94418
* include/bits/stl_iterator.h (reverse_iterator): Use
conditional noexcept on constructors and assignment operators.
* testsuite/24_iterators/reverse_iterator/noexcept.cc: New test.

diff --git a/libstdc++-v3/include/bits/stl_iterator.h 
b/libstdc++-v3/include/bits/stl_iterator.h
index 004d767224d..4973f792b56 100644
--- a/libstdc++-v3/include/bits/stl_iterator.h
+++ b/libstdc++-v3/include/bits/stl_iterator.h
@@ -174,20 +174,28 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // 235 No specification of default ctor for reverse_iterator
   // 1012. reverse_iterator default ctor should value initialize
   _GLIBCXX17_CONSTEXPR
-  reverse_iterator() : current() { }
+  reverse_iterator()
+  _GLIBCXX_NOEXCEPT_IF(noexcept(_Iterator()))
+  : current()
+  { }
 
   /**
*  This %iterator will move in the opposite direction that @p x does.
   */
   explicit _GLIBCXX17_CONSTEXPR
-  reverse_iterator(iterator_type __x) : current(__x) { }
+  reverse_iterator(iterator_type __x)
+  _GLIBCXX_NOEXCEPT_IF(noexcept(_Iterator(__x)))
+  : current(__x)
+  { }
 
   /**
*  The copy constructor is normal.
   */
   _GLIBCXX17_CONSTEXPR
   reverse_iterator(const reverse_iterator& __x)
-  : current(__x.current) { }
+  _GLIBCXX_NOEXCEPT_IF(noexcept(_Iterator(__x.current)))
+  : current(__x.current)
+  { }
 
 #if __cplusplus >= 201103L
   reverse_iterator& operator=(const reverse_iterator&) = default;
@@ -203,7 +211,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #endif
_GLIBCXX17_CONSTEXPR
 reverse_iterator(const reverse_iterator<_Iter>& __x)
-   : current(__x.current) { }
+   _GLIBCXX_NOEXCEPT_IF(noexcept(_Iterator(__x.current)))
+   : current(__x.current)
+   { }
 
 #if __cplusplus >= 201103L
   template
@@ -214,6 +224,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX17_CONSTEXPR
reverse_iterator&
operator=(const reverse_iterator<_Iter>& __x)
+   _GLIBCXX_NOEXCEPT_IF(noexcept(current = __x.current))
{
  current = __x.current;
  return *this;
@@ -226,6 +237,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   _GLIBCXX_NODISCARD
   _GLIBCXX17_CONSTEXPR iterator_type
   base() const
+  _GLIBCXX_NOEXCEPT_IF(noexcept(_Iterator(current)))
   { return current; }
 
   /**
diff --git a/libstdc++-v3/testsuite/24_iterators/reverse_iterator/noexcept.cc 
b/libstdc++-v3/testsuite/24_iterators/reverse_iterator/noexcept.cc
new file mode 100644
index 000..df4b1b0763d
--- /dev/null
+++ b/libstdc++-v3/testsuite/24_iterators/reverse_iterator/noexcept.cc
@@ -0,0 +1,92 @@
+// { dg-do compile { target c++11 } }
+
+#include 
+
+template
+struct bidi
+{
+  using value_type = T;
+  using pointer = T*;
+  using reference = T&;
+  using difference_type = std::ptrdiff_t;
+  using iterator_category = std::bidirectional_iterator_tag;
+
+  T* ptr;
+
+  bidi(T* ptr = nullptr) noexcept(Nothrow) : ptr(ptr) { }
+
+  bidi(const bidi& iter) noexcept(Nothrow) : ptr(iter.ptr) { }
+
+  template
+

[committed] libstdc++: Do not allocate a zero-size vector [PR 100153]

2021-10-01 Thread Jonathan Wakely via Gcc-patches
The vector::shrink_to_fit() implementation will allocate new
storage even if the vector is empty. That then leads to the
end-of-storage pointer being non-null and equal to the _M_start._M_p
pointer, which means that _M_end_addr() has undefined behaviour.

The fix is to stop doing a useless zero-sized allocation in
shrink_to_fit(), so that _M_start._M_p and _M_end_of_storage are both
null after an empty vector shrinks.

Signed-off-by: Jonathan Wakely 

libstdc++-v3/ChangeLog:

PR libstdc++/100153
* include/bits/vector.tcc (vector::_M_shrink_to_fit()):
When size() is zero just deallocate and reset.

Tested powerpc64le-linux. Committed to trunk.

commit 681707ec28d56494fa61a80c62500724d55f8586
Author: Jonathan Wakely 
Date:   Tue Apr 20 16:16:13 2021

libstdc++: Do not allocate a zero-size vector [PR 100153]

The vector::shrink_to_fit() implementation will allocate new
storage even if the vector is empty. That then leads to the
end-of-storage pointer being non-null and equal to the _M_start._M_p
pointer, which means that _M_end_addr() has undefined behaviour.

The fix is to stop doing a useless zero-sized allocation in
shrink_to_fit(), so that _M_start._M_p and _M_end_of_storage are both
null after an empty vector shrinks.

Signed-off-by: Jonathan Wakely 

libstdc++-v3/ChangeLog:

PR libstdc++/100153
* include/bits/vector.tcc (vector::_M_shrink_to_fit()):
When size() is zero just deallocate and reset.

diff --git a/libstdc++-v3/include/bits/vector.tcc 
b/libstdc++-v3/include/bits/vector.tcc
index caee5cbfc2f..16366e03c86 100644
--- a/libstdc++-v3/include/bits/vector.tcc
+++ b/libstdc++-v3/include/bits/vector.tcc
@@ -944,7 +944,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
return false;
   __try
{
- _M_reallocate(size());
+ if (size_type __n = size())
+   _M_reallocate(__n);
+ else
+   {
+ this->_M_deallocate();
+ this->_M_impl._M_reset();
+   }
  return true;
}
   __catch(...)


[committed] libstdc++: Implement std::clamp with std::min and std::max [PR 96733]

2021-10-01 Thread Jonathan Wakely via Gcc-patches
The compiler doesn't know about the precondition of std::clamp that
(hi < lo) is false, and so can't optimize as well as we'd like. By using
std::min and std::max we help the compiler.

Signed-off-by: Jonathan Wakely 

libstdc++-v3/ChangeLog:

PR libstdc++/96733
* include/bits/stl_algo.h (clamp): Use std::min and std::max.

Tested powerpc64le-linux. Committed to trunk.

commit 741c7350c08b0884689466867b6c9e711c7b109e
Author: Jonathan Wakely 
Date:   Sat Apr 17 22:34:09 2021

libstdc++: Implement std::clamp with std::min and std::max [PR 96733]

The compiler doesn't know about the precondition of std::clamp that
(hi < lo) is false, and so can't optimize as well as we'd like. By using
std::min and std::max we help the compiler.

Signed-off-by: Jonathan Wakely 

libstdc++-v3/ChangeLog:

PR libstdc++/96733
* include/bits/stl_algo.h (clamp): Use std::min and std::max.

diff --git a/libstdc++-v3/include/bits/stl_algo.h 
b/libstdc++-v3/include/bits/stl_algo.h
index 5d12972ce2c..90f3162ff90 100644
--- a/libstdc++-v3/include/bits/stl_algo.h
+++ b/libstdc++-v3/include/bits/stl_algo.h
@@ -3621,7 +3621,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   __gnu_cxx::__ops::__iter_comp_iter(__pred));
 }
 
-#if __cplusplus > 201402L
+#if __cplusplus >= 201703L
 
 #define __cpp_lib_clamp 201603
 
@@ -3631,14 +3631,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  @param  __val  A value of arbitrary type.
*  @param  __lo   A lower limit of arbitrary type.
*  @param  __hi   An upper limit of arbitrary type.
-   *  @return max(__val, __lo) if __val < __hi or min(__val, __hi) otherwise.
+   *  @retval `__lo` if `__val < __lo`
+   *  @retval `__hi` if `__hi < __val`
+   *  @retval `__val` otherwise.
+   *  @pre `_Tp` is LessThanComparable and `(__hi < __lo)` is false.
*/
   template
 constexpr const _Tp&
 clamp(const _Tp& __val, const _Tp& __lo, const _Tp& __hi)
 {
   __glibcxx_assert(!(__hi < __lo));
-  return (__val < __lo) ? __lo : (__hi < __val) ? __hi : __val;
+  return std::min(std::max(__val, __lo), __hi);
 }
 
   /**
@@ -3648,15 +3651,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  @param  __loA lower limit of arbitrary type.
*  @param  __hiAn upper limit of arbitrary type.
*  @param  __comp  A comparison functor.
-   *  @return max(__val, __lo, __comp) if __comp(__val, __hi)
-   * or min(__val, __hi, __comp) otherwise.
+   *  @retval `__lo` if `__comp(__val, __lo)`
+   *  @retval `__hi` if `__comp(__hi, __val)`
+   *  @retval `__val` otherwise.
+   *  @pre `__comp(__hi, __lo)` is false.
*/
   template
 constexpr const _Tp&
 clamp(const _Tp& __val, const _Tp& __lo, const _Tp& __hi, _Compare __comp)
 {
   __glibcxx_assert(!__comp(__hi, __lo));
-  return __comp(__val, __lo) ? __lo : __comp(__hi, __val) ? __hi : __val;
+  return std::min(std::max(__val, __lo, __comp), __hi, __comp);
 }
 #endif // C++17
 #endif // C++14


[committed] libstdc++: Reduce header dependencies for C++20 std::erase [PR92546]

2021-10-01 Thread Jonathan Wakely via Gcc-patches
This reduces the preprocessed size of ,  and  by
not including  for std::remove and std::remove_if.

Also unwrap iterators using __niter_base, to avoid redundant debug mode
checks.

PR libstdc++/92546
* include/bits/erase_if.h (__erase_nodes_if): Use __niter_base to
unwrap debug iterators.
* include/bits/refwrap.h: Do not error if included in C++03.
* include/bits/stl_algo.h (__remove_if): Move to ...
* include/bits/stl_algobase.h (__remove_if): ... here.
* include/std/deque (erase, erase_if): Use __remove_if instead of
remove and remove_if.
* include/std/string (erase, erase_if): Likewise.
* include/std/vector (erase, erase_if): Likewise.

Tested powerpc64le-linux. Committed to trunk.

ff7793bea46
34e9407b3b4
b7e8fb5e482
6ccffeb56b9
e79bde6ada4
e5c093e515c
20751fad19e
9b790acc220
e3869a48fc2
44967af830a
dc1b29508d7
59ffa3e3dba
d71476c9df9
a09bb4a852f
cfb582f6279
c46ecb0112e
fb4d55ef61c
10b6d89badd
ce709ad3dc0
d335d73889d
681707ec28d
741c7350c08
commit acf3a21cbc26b39b73c0006300f35ff017ddd6cb
Author: Jonathan Wakely 
Date:   Fri Oct 1 20:37:02 2021

libstdc++: Reduce header dependencies for C++20 std::erase [PR92546]

This reduces the preprocessed size of ,  and  by
not including  for std::remove and std::remove_if.

Also unwrap iterators using __niter_base, to avoid redundant debug mode
checks.

PR libstdc++/92546
* include/bits/erase_if.h (__erase_nodes_if): Use __niter_base to
unwrap debug iterators.
* include/bits/refwrap.h: Do not error if included in C++03.
* include/bits/stl_algo.h (__remove_if): Move to ...
* include/bits/stl_algobase.h (__remove_if): ... here.
* include/std/deque (erase, erase_if): Use __remove_if instead of
remove and remove_if.
* include/std/string (erase, erase_if): Likewise.
* include/std/vector (erase, erase_if): Likewise.

diff --git a/libstdc++-v3/include/bits/erase_if.h 
b/libstdc++-v3/include/bits/erase_if.h
index 8d1d23168fa..7716e1a953c 100644
--- a/libstdc++-v3/include/bits/erase_if.h
+++ b/libstdc++-v3/include/bits/erase_if.h
@@ -51,7 +51,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   __erase_nodes_if(_Container& __cont, _Predicate __pred)
   {
typename _Container::size_type __num = 0;
-   for (auto __iter = __cont.begin(), __last = __cont.end();
+   for (auto __iter = std::__niter_base(__cont.begin()),
+__last = std::__niter_base(__cont.end());
 __iter != __last;)
  {
if (__pred(*__iter))
diff --git a/libstdc++-v3/include/bits/refwrap.h 
b/libstdc++-v3/include/bits/refwrap.h
index adfbe214693..a549efbce9a 100644
--- a/libstdc++-v3/include/bits/refwrap.h
+++ b/libstdc++-v3/include/bits/refwrap.h
@@ -32,9 +32,7 @@
 
 #pragma GCC system_header
 
-#if __cplusplus < 201103L
-# include 
-#else
+#if __cplusplus >= 201103L
 
 #include 
 #include 
diff --git a/libstdc++-v3/include/bits/stl_algo.h 
b/libstdc++-v3/include/bits/stl_algo.h
index 90f3162ff90..bc611a95ef4 100644
--- a/libstdc++-v3/include/bits/stl_algo.h
+++ b/libstdc++-v3/include/bits/stl_algo.h
@@ -810,26 +810,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 }
 #endif // C++11
 
-  template
-_GLIBCXX20_CONSTEXPR
-_ForwardIterator
-__remove_if(_ForwardIterator __first, _ForwardIterator __last,
-   _Predicate __pred)
-{
-  __first = std::__find_if(__first, __last, __pred);
-  if (__first == __last)
-   return __first;
-  _ForwardIterator __result = __first;
-  ++__first;
-  for (; __first != __last; ++__first)
-   if (!__pred(__first))
- {
-   *__result = _GLIBCXX_MOVE(*__first);
-   ++__result;
- }
-  return __result;
-}
-
   /**
*  @brief Remove elements from a sequence.
*  @ingroup mutating_algorithms
diff --git a/libstdc++-v3/include/bits/stl_algobase.h 
b/libstdc++-v3/include/bits/stl_algobase.h
index 8627d59b589..0e0586836a6 100644
--- a/libstdc++-v3/include/bits/stl_algobase.h
+++ b/libstdc++-v3/include/bits/stl_algobase.h
@@ -2125,6 +2125,26 @@ _GLIBCXX_END_NAMESPACE_ALGO
   return __n;
 }
 
+  template
+_GLIBCXX20_CONSTEXPR
+_ForwardIterator
+__remove_if(_ForwardIterator __first, _ForwardIterator __last,
+   _Predicate __pred)
+{
+  __first = std::__find_if(__first, __last, __pred);
+  if (__first == __last)
+   return __first;
+  _ForwardIterator __result = __first;
+  ++__first;
+  for (; __first != __last; ++__first)
+   if (!__pred(__first))
+ {
+   *__result = _GLIBCXX_MOVE(*__first);
+   ++__result;
+ }
+  return __result;
+}
+
 #if __cplusplus >= 201103L
   template
diff --git a/libstdc++-v3/include/std/deque b/libstdc++-v3/include/std/deque
index c9a82110ad7..b2a7cee483a 100644
--- 

Re: [Patch] Fortran: Avoid var initialization in interfaces [PR54753]

2021-10-01 Thread Harald Anlauf via Gcc-patches

[Resending as I did not see it show up in the MLs]

Hi Tobias,

Am 29.09.21 um 10:53 schrieb Tobias Burnus:

Found when looking at F2018:C839 / PR54753.

For INTENT(OUT) the dummy variable (might) also be default initialized
or deallocated. However, with assumed rank, that causes issues, which
C839 prevents. In the current GCC implementation, missing C839 constraint
diagnostic, but also rejects-valid/ice-on-valid appears.

There are three issues, this patch solves the first:

* reject-valid issue due to adding the initializer also to a dummy
   argument which is in an INTERFACE block. Having initializers in
   INTERFACE blocks is pointless and causes for the attached testcase
   the bogus error:
   "Assumed-rank variable y at (1) may only be used as actual argument"


ACK.


(Except for wasting resources and this error, they should be ignored
in trans*.c and usually do not cause any further harm.)


I think Sandra has a nearly ready patch to do the C839 constraint
diagnostic, which needs the attached patch to do the checks.

The third issue is that GCC currently gives either an ICE or the
above error message when declaring a procedure with a valid
assumed-rank intent(out) dummy. This has still to be solved as well.
But first I wanted to unblock Sandra's C839 work with this patch :-)


Regarding the patch, '!= IFSRC_IFBODY' has to be used; "== IFSRC_DECL"
won't work as the the generatedy ENTRY master function has IFSRC_UNKNOWN.


I have to admit that the code touched is hard to understand for me.
The conditions involved are unfortunately already dense, long lists.

(There are PRs related to *missing* default initializations (e.g.
PR100440), which I looked at before in that area until I got lost...
Of course this needs to be addressed elsewhere.)


OK for mainline?


No objections here; the patch seems to work.  The commit message has
a non-ASCII character (hyphen).  Not sure whether that was intended.

You may nevertheless want a second opinion.

Thanks for the patch!

Harald


Tobias

PS: Some patch reviews are that fast that it is impossible to send the OK;
at least, I did not manage to do for Harald's last two - for the last one
I was at least 4min too late. ;-)

-
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





Re: [PING^2][PATCH] libgcc, emutls: Allow building weak definitions of the emutls functions.

2021-10-01 Thread Iain Sandoe
Hi,

So let’s ignore the questions for now - OK for the non-Darwin parts of the
patch ?

> On 24 Sep 2021, at 17:57, Iain Sandoe  wrote:
> 

> as noted below the non-Darwin parts of this are trivial (and a no-OP).
> I’d like to apply this to start work towards solving Darwin’s libgcc issues,

>> On 20 Sep 2021, at 09:25, Iain Sandoe  wrote:
>> 

>> The non-Darwin part of this patch is trivial but raises a couple of questions
>> 
>> A/
>> We define builtins to support emulated TLS.
>> These are defined with void * pointers
>> The implementation (in libgcc) uses the correct type (struct __emutls_object 
>> *)
>> in both a forward declaration of the functions and in thier eventual 
>> implementation.
>> 
>> This leads to a (long-standing, nothing new) complaint at build-time about
>> the mismatch in the builtin/implementation decls.
>> 
>> AFAICT, there’s no way to fix that unless we introduce struct 
>> __emutls_object *
>> as a built-in type?
>> 
>> B/ 
>> It seems that a consequence of the mismatch in decls means that if I apply
>> attributes to the decl (in the implementation file), they are ignored and I 
>> have
>> to apply them to the definition in order for this to work.
>> 
>> This (B) is what the patch below does.
>> 
>> tested on powerpc,i686,x86_64-darwin, x86_64-linux
>> OK for master?
>> thanks,
>> Iain
>> 
>> If the current situation is that A or B indicates “there’s a bug”, please 
>> could that
>> be considered as distinct from the current patch (which doesn’t alter this 
>> in any
>> way) so that we can make progress on fixing Darwin libgcc issues.
>> 
>> = commit log
>> 
>> In order to better support use of the emulated TLS between objects with
>> DSO dependencies and static-linked libgcc, allow a target to make weak
>> definitions.
>> 
>> Signed-off-by: Iain Sandoe 
>> 
>> libgcc/ChangeLog:
>> 
>>  * config.host: Add weak-defined emutls crt.
>>  * config/t-darwin: Build weak-defined emutls objects.
>>  * emutls.c (__emutls_get_address): Add optional attributes.
>>  (__emutls_register_common): Likewise.
>>  (EMUTLS_ATTR): New.
>> ---
>> libgcc/config.host |  2 +-
>> libgcc/config/t-darwin | 13 +
>> libgcc/emutls.c| 17 +++--
>> 3 files changed, 29 insertions(+), 3 deletions(-)
>> 
>> diff --git a/libgcc/config.host b/libgcc/config.host
>> index 6c34b13d611..a447ac7ae30 100644
>> --- a/libgcc/config.host
>> +++ b/libgcc/config.host
>> @@ -215,7 +215,7 @@ case ${host} in
>> *-*-darwin*)
>>  asm_hidden_op=.private_extern
>>  tmake_file="$tmake_file t-darwin ${cpu_type}/t-darwin t-libgcc-pic 
>> t-slibgcc-darwin"
>> -  extra_parts="crt3.o libd10-uwfef.a crttms.o crttme.o"
>> +  extra_parts="crt3.o libd10-uwfef.a crttms.o crttme.o libemutls_w.a"
>>  ;;
>> *-*-dragonfly*)
>>  tmake_file="$tmake_file t-crtstuff-pic t-libgcc-pic t-eh-dw2-dip"
>> diff --git a/libgcc/config/t-darwin b/libgcc/config/t-darwin
>> index 14ae6b35a4e..d6f688d66d5 100644
>> --- a/libgcc/config/t-darwin
>> +++ b/libgcc/config/t-darwin
>> @@ -15,6 +15,19 @@ crttme.o: $(srcdir)/config/darwin-crt-tm.c
>> LIB2ADDEH = $(srcdir)/unwind-dw2.c $(srcdir)/config/unwind-dw2-fde-darwin.c \
>>  $(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c
>> 
>> +# Make emutls weak so that we can deal with -static-libgcc, override the
>> +# hidden visibility when this is present in libgcc_eh.
>> +emutls.o: HOST_LIBGCC2_CFLAGS += \
>> +  -DEMUTLS_ATTR='__attribute__((__weak__,__visibility__("default")))'
>> +emutls_s.o: HOST_LIBGCC2_CFLAGS += \
>> +  -DEMUTLS_ATTR='__attribute__((__weak__,__visibility__("default")))'
>> +
>> +# Make the emutls crt as a convenience lib so that it can be linked
>> +# optionally, use the shared version so that we can link with DSO.
>> +libemutls_w.a: emutls_s.o
>> +$(AR_CREATE_FOR_TARGET) $@ $<
>> +$(RANLIB_FOR_TARGET) $@
>> +
>> # Patch to __Unwind_Find_Enclosing_Function for Darwin10.
>> d10-uwfef.o: $(srcdir)/config/darwin10-unwind-find-enc-func.c
>>  $(crt_compile) -mmacosx-version-min=10.6 -c $<
>> diff --git a/libgcc/emutls.c b/libgcc/emutls.c
>> index ed2658170f5..d553a74728f 100644
>> --- a/libgcc/emutls.c
>> +++ b/libgcc/emutls.c
>> @@ -50,7 +50,16 @@ struct __emutls_array
>>  void **data[];
>> };
>> 
>> +/* EMUTLS_ATTR is provided to allow targets to build the emulated tls
>> +   routines as weak definitions, for example.
>> +   If there is no definition, fall back to the default.  */
>> +#ifndef EMUTLS_ATTR
>> +#  define EMUTLS_ATTR
>> +#endif
>> +
>> +EMUTLS_ATTR
>> void *__emutls_get_address (struct __emutls_object *);
>> +EMUTLS_ATTR
>> void __emutls_register_common (struct __emutls_object *, word, word, void *);
>> 
>> #ifdef __GTHREADS
>> @@ -123,7 +132,11 @@ emutls_alloc (struct __emutls_object *obj)
>>  return ret;
>> }
>> 
>> -void *
>> +/* Despite applying the attribute to the declaration, in this case the mis-
>> +   match between the builtin's declaration [void * (*)(void *)] and the
>> +   implementation here, causes the decl. 

Re: PING #2 [PATCH] warn for more impossible null pointer tests [PR102103]

2021-10-01 Thread Martin Sebor via Gcc-patches

On 9/30/21 1:35 PM, Joseph Myers wrote:

On Thu, 30 Sep 2021, Martin Sebor via Gcc-patches wrote:


Jason, since you approved the C++ changes, would you mind looking
over the C bits and if they look good to you giving me the green
light to commit the patch?

https://gcc.gnu.org/pipermail/gcc-patches/2021-September/579693.html


The C changes are OK, with two instances of "for the address %qE will
never be NULL" fixed to refer to the address *of* %qE as elsewhere (those
are for IMAGPART_EXPR and REALPART_EXPR; C++ also has one "the address %qE
will never be NULL"), and the "pr??" in the tests filled in with an
actual PR number for the XFAILed cases.


Thanks for the careful review and the approval!

I remember having a reason for dropping the "of" in the two instances
in the C FE but after double-checking the output I see you're right
that it should be there.  Good catch!

I believe the C++ instance is correct.  It's issued for the address
of a member, as in the former of the two below:

  struct S { int i; };

  bool f ()
  {
return ::i == 0;   // the address ‘::i’
  }

  bool g (S *p)
  {
return >i == 0;   // the address of ‘S::i’
  }

z.c: In function ‘bool f()’:
z.c:5:16: warning: the address ‘::i’ will never be NULL [-Waddress]
5 |   return ::i == 0;
  |  ~~^~~~
z.c: In function ‘bool g(S*)’:
z.c:10:16: warning: the address of ‘S::i’ will never be NULL [-Waddress]
   10 |   return >i == 0;
  |  ~~^~~~
z.c:1:16: note: ‘S::i’ declared here
1 | struct S { int i; };
  |^

I've beefed up the tests to verify the expected wording.

Thanks also for prompting me to open bugs for the xfailed tests,
something I tend to forget to do when it depends on the patch I'm
developing.  I've raised pr102555 for the C FE folding defeating
the warning.  The C++ bug that tracks the xfails in the C++ tests
is pr102378.

I've pushed the updated patch in r12-4059 after retesting the whole
thing on x86_64-linux.

Martin


[committed] hppa: Default to dwarf version 4 on hppa64-hpux

2021-10-01 Thread John David Anglin
DWARF5 is not supported by gdb on hpux, so we need to to limit version to 4.

Tested on hppa64-hp-hpux11.11.  Committed to trunk and gcc-11.

Dave
---

Default to dwarf version 4 on hppa64-hpux

2021-10-01  John David Anglin  

gcc/ChangeLog:

PR debug/102373
* config/pa/pa.c (pa_option_override): Default to dwarf version 4
on hppa64-hpux.

diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
index 06143023b46..5b3ffd48f4e 100644
--- a/gcc/config/pa/pa.c
+++ b/gcc/config/pa/pa.c
@@ -541,6 +541,16 @@ pa_option_override (void)
   write_symbols = NO_DEBUG;
 }
 
+  if (TARGET_64BIT && TARGET_HPUX)
+{
+  /* DWARF5 is not supported by gdb.  Don't emit DWARF5 unless
+specifically selected.  */
+  if (!global_options_set.x_dwarf_strict)
+   dwarf_strict = 1;
+  if (!global_options_set.x_dwarf_version)
+   dwarf_version = 4;
+}
+
   /* We only support the "big PIC" model now.  And we always generate PIC
  code when in 64bit mode.  */
   if (flag_pic == 1 || TARGET_64BIT)



Re: [PATCH] libiberty: testsuite: add missing format on d-demangle-expected

2021-10-01 Thread Luís Ferreira
Noted.

On Fri, 2021-10-01 at 11:28 -0600, Jeff Law wrote:
>  
>  
> On 9/29/2021 6:50 PM, Luís Ferreira wrote:
>  
> > This patch adds a missing format parameter that prevents d-
> > demangle-expected
> > test collection from running successfully.
> > 
> > Signed-off-by: Luís Ferreira 
>  THanks.  Pushed to the trunk.
>  
>  Can you please start including ChangeLog entries so that I don't
> have
> to write them for you.
>  
>  Thanks,
>  Jeff
>  
>  

-- 
Sincerely,
Luís Ferreira @ lsferreira.net



signature.asc
Description: This is a digitally signed message part


Re: [PATCH] c++: unifying equal NONTYPE_ARGUMENT_PACKs [PR102547]

2021-10-01 Thread Patrick Palka via Gcc-patches
On Fri, 1 Oct 2021, Jason Merrill wrote:

> On 10/1/21 10:26, Patrick Palka wrote:
> > On Fri, 1 Oct 2021, Jason Merrill wrote:
> > 
> > > On 10/1/21 09:46, Patrick Palka wrote:
> > > > Here during partial ordering of the two partial specializations we end
> > > > up in unify with parm=arg=NONTYPE_ARGUMENT_PACK, and crash
> > > > shortly
> > > > thereafter because uses_template_parms calls
> > > > potential_constant_expression
> > > > which doesn't handle NONTYPE_ARGUMENT_PACK.
> > > > 
> > > > This patch fixes this by checking dependent_template_arg_p instead of
> > > > uses_template_parms when parm==arg, which does handle
> > > > NONTYPE_ARGUMENT_PACK.
> > > > We could also perhaps fix uses_template_parms / inst_dep_expr_p to
> > > > better
> > > > handle NONTYPE_ARGUMENT_PACK,
> > > 
> > > Please.
> > 
> > Sounds good, like the following then?  Passes light testing, bootstrap
> > and regtest on progress.
> > 
> > -- >8 --
> > 
> > PR c++/102547
> > 
> > gcc/cp/ChangeLog:
> > 
> > * pt.c (instantiation_dependent_expression_p): Sidestep checking
> > potential_constant_expression on NONTYPE_ARGUMENT_PACK.
> > 
> > gcc/testsuite/ChangeLog:
> > 
> > * g++.dg/cpp0x/variadic-partial2.C: New test.
> > * g++.dg/cpp0x/variadic-partial2a.C: New test.
> > ---
> >   gcc/cp/pt.c   |  4 +++-
> >   .../g++.dg/cpp0x/variadic-partial2.C  | 16 ++
> >   .../g++.dg/cpp0x/variadic-partial2a.C | 22 +++
> >   3 files changed, 41 insertions(+), 1 deletion(-)
> >   create mode 100644 gcc/testsuite/g++.dg/cpp0x/variadic-partial2.C
> >   create mode 100644 gcc/testsuite/g++.dg/cpp0x/variadic-partial2a.C
> > 
> > diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
> > index 1dcdffe322a..643204103c5 100644
> > --- a/gcc/cp/pt.c
> > +++ b/gcc/cp/pt.c
> > @@ -27705,7 +27705,9 @@ instantiation_dependent_expression_p (tree
> > expression)
> >   {
> > return (instantiation_dependent_uneval_expression_p (expression)
> >   || (processing_template_decl
> > - && potential_constant_expression (expression)
> > + && expression != NULL_TREE
> > + && (TREE_CODE (expression) == NONTYPE_ARGUMENT_PACK
> > + || potential_constant_expression (expression))
> 
> I'd prefer to loop over the elements of the pack, either here or (probably
> better) in potential_constant_expression.

Ah, makes sense.  Like so?  Bootstrapped and regtested on
x86_64-pc-linux-gnu.

-- >8 --

Subject: [PATCH] c++: unifying equal NONTYPE_ARGUMENT_PACKs [PR102547]

Here during partial ordering of the two partial specializations we end
up in unify with parm=arg=NONTYPE_ARGUMENT_PACK, and crash shortly
thereafter because uses_template_parms(parms) calls potential_const_expr
which doesn't handle NONTYPE_ARGUMENT_PACK.

This patch fixes this by extending potential_constant_expression to handle
NONTYPE_ARGUMENT_PACK appropriately.

Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
trunk/11?

PR c++/102547

gcc/cp/ChangeLog:

* constexpr.c (potential_constant_expression_1): Handle
NONTYPE_ARGUMENT_PACK.

gcc/testsuite/ChangeLog:

* g++.dg/cpp0x/variadic-partial2.C: New test.
* g++.dg/cpp0x/variadic-partial2a.C: New test.
---
 gcc/cp/constexpr.c| 10 +
 .../g++.dg/cpp0x/variadic-partial2.C  | 16 ++
 .../g++.dg/cpp0x/variadic-partial2a.C | 22 +++
 3 files changed, 48 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/variadic-partial2.C
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/variadic-partial2a.C

diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 18d9d117a48..e95ff00774f 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -9043,6 +9043,16 @@ potential_constant_expression_1 (tree t, bool want_rval, 
bool strict, bool now,
 case CO_RETURN_EXPR:
   return false;
 
+case NONTYPE_ARGUMENT_PACK:
+  {
+   tree args = ARGUMENT_PACK_ARGS (t);
+   int len = TREE_VEC_LENGTH (args);
+   for (int i = 0; i < len; ++i)
+ if (!RECUR (TREE_VEC_ELT (args, i), any))
+   return false;
+   return true;
+  }
+
 default:
   if (objc_non_constant_expr_p (t))
return false;
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-partial2.C 
b/gcc/testsuite/g++.dg/cpp0x/variadic-partial2.C
new file mode 100644
index 000..df61f26a3c1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic-partial2.C
@@ -0,0 +1,16 @@
+// PR c++/102547
+// { dg-do compile { target c++11 } }
+
+template
+struct vals { };
+
+template
+struct vals_client { };
+
+template
+struct vals_client, T> { };
+
+template
+struct vals_client, void> { };
+
+template struct vals_client, void>; //- "sorry, unimplemented..., 
ICE"
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-partial2a.C 
b/gcc/testsuite/g++.dg/cpp0x/variadic-partial2a.C
new file mode 100644
index 

Re: [PATCH] libiberty: testsuite: add missing format on d-demangle-expected

2021-10-01 Thread Jeff Law via Gcc-patches




On 9/29/2021 6:50 PM, Luís Ferreira wrote:

This patch adds a missing format parameter that prevents d-demangle-expected
test collection from running successfully.

Signed-off-by: Luís Ferreira

THanks.  Pushed to the trunk.

Can you please start including ChangeLog entries so that I don't have to 
write them for you.


Thanks,
Jeff



Re: [PATCH 05/11] OpenMP/OpenACC: Hoist struct sibling list handling in gimplification

2021-10-01 Thread Julian Brown
Oops, editing:

On Fri, 1 Oct 2021 10:09:03 -0700
Julian Brown  wrote:

> Secondly, it means that in the first pass gathering up sibling lists
> from parsed OpenMP/OpenACC clauses, we don't need to worry about
> gimplifying: that means we can see struct bases & components we need
> to sort sibling lists properly, even when we're using a non-DECL_P
> struct base.  Gimplification proper still happens

...in the main loop in gimplify_scan_omp_clauses.




[PATCH 11/11] OpenMP/OpenACC: [WIP] Add gcc_unreachable to apparently-dead path in build_struct_comp_nodes

2021-10-01 Thread Julian Brown
The previous "not for committing" taxonomy patch shows that the path
handling "extra nodes" in build_struct_comp_nodes is probably now dead,
at least across the current testsuite.  This patch adds gcc_unreachable
on that path: this passes testing, which suggests that the extra node
handling can probably be removed completely.  (Otherwise we need test
coverage for that path, ideally!)

This is mostly posted as an FYI: a real patch would probably just remove
the unused code path, if it really isn't needed any more.

Thanks,

Julian

2021-09-29  Julian Brown  

gcc/
* gimplify.c (build_struct_comp_nodes): Add gcc_unreachable on code
path that appears to now be unused.
---
 gcc/gimplify.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index d9fda21413d..3d444d1836f 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -8625,6 +8625,9 @@ build_struct_comp_nodes (enum tree_code code, tree 
grp_start, tree grp_end,
   OMP_CLAUSE_SIZE (c3) = TYPE_SIZE_UNIT (ptr_type_node);
   OMP_CLAUSE_CHAIN (c3) = NULL_TREE;
 
+  /* Apparently?  */
+  gcc_unreachable ();
+
   *extra_node = c3;
 }
   else
-- 
2.29.2



[PATCH 10/11] Not for committing: noisy mapping-group taxonomy

2021-10-01 Thread Julian Brown
As a possible aid to review, this is code that can be used to enumerate
all the mapping group forms currently in use across the GCC/libgomp
testsuites for OpenMP/OpenACC.  These groups have been added somewhat
organically, so there might be a couple of surprises: see e.g. the patch
following this one.

It's not meant for committing.
---
 gcc/gimplify.c | 327 +
 1 file changed, 327 insertions(+)

diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index ffb6eda5490..d9fda21413d 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -72,6 +72,7 @@ along with GCC; see the file COPYING3.  If not see
 
 //#define NOISY_TOPOSORT
 //#define NOISY_SIBLING_LISTS
+//#define NOISY_TAXONOMY
 
 /* Hash set of poisoned variables in a bind expr.  */
 static hash_set *asan_poisoned_variables = NULL;
@@ -9010,6 +9011,326 @@ omp_gather_mapping_groups (tree *list_p)
 }
 }
 
+#ifdef NOISY_TAXONOMY
+
+static void
+omp_mapping_group_taxonomy (vec *groups)
+{
+  int num = 0;
+
+  for (auto  : *groups)
+{
+  tree node, grp_start = *it.grp_start, grp_end = it.grp_end;
+  gomp_map_kind kind0 = OMP_CLAUSE_MAP_KIND (grp_start), kind1, kind2,
+   kind3;
+  int count = 1;
+  node = grp_start;
+  if (node != grp_end)
+   {
+ node = OMP_CLAUSE_CHAIN (node);
+ kind1 = OMP_CLAUSE_MAP_KIND (node);
+ count++;
+ if (node != grp_end)
+   {
+ node = OMP_CLAUSE_CHAIN (node);
+ kind2 = OMP_CLAUSE_MAP_KIND (node);
+ count++;
+ if (node != grp_end)
+   {
+ node = OMP_CLAUSE_CHAIN (node);
+ kind3 = OMP_CLAUSE_MAP_KIND (node);
+ count++;
+ gcc_assert (node == grp_end);
+   }
+   }
+   }
+
+  fprintf (stderr, "group %d: ", num);
+
+  switch (count)
+   {
+   case 1:
+ if (kind0 == GOMP_MAP_TO
+ || kind0 == GOMP_MAP_FROM
+ || kind0 == GOMP_MAP_TOFROM)
+   fprintf (stderr, "scalar to/from\n");
+ else if (kind0 == GOMP_MAP_ALLOC)
+   fprintf (stderr, "alloc\n");
+ else if (kind0 == GOMP_MAP_POINTER)
+   fprintf (stderr, "pointer (by itself)\n");
+ else if (kind0 == GOMP_MAP_TO_PSET)
+   fprintf (stderr, "map-to-pset (by itself)\n");
+ else if (kind0 == GOMP_MAP_FORCE_PRESENT)
+   fprintf (stderr, "force present\n");
+ else if (kind0 == GOMP_MAP_DELETE)
+   fprintf (stderr, "delete\n");
+ else if (kind0 == GOMP_MAP_FORCE_DEVICEPTR)
+   fprintf (stderr, "force deviceptr\n");
+ else if (kind0 == GOMP_MAP_DEVICE_RESIDENT)
+   fprintf (stderr, "device resident\n");
+ else if (kind0 == GOMP_MAP_LINK)
+   fprintf (stderr, "link\n");
+ else if (kind0 == GOMP_MAP_IF_PRESENT)
+   fprintf (stderr, "if present\n");
+ else if (kind0 == GOMP_MAP_FIRSTPRIVATE)
+   fprintf (stderr, "firstprivate (by itself)\n");
+ else if (kind0 == GOMP_MAP_FIRSTPRIVATE_INT)
+   fprintf (stderr, "firstprivate_int (by itself)\n");
+ else if (kind0 == GOMP_MAP_USE_DEVICE_PTR)
+   fprintf (stderr, "use device ptr\n");
+ else if (kind0 == GOMP_MAP_ZERO_LEN_ARRAY_SECTION)
+   fprintf (stderr, "zero-length array section (by itself)\n");
+ else if (kind0 == GOMP_MAP_FORCE_ALLOC)
+   fprintf (stderr, "force alloc\n");
+ else if (kind0 == GOMP_MAP_FORCE_TO
+  || kind0 == GOMP_MAP_FORCE_FROM
+  || kind0 == GOMP_MAP_FORCE_TOFROM)
+   fprintf (stderr, "force to/from (scalar)\n");
+ else if (kind0 == GOMP_MAP_USE_DEVICE_PTR_IF_PRESENT)
+   fprintf (stderr, "use device ptr if present\n");
+ else if (kind0 == GOMP_MAP_ALWAYS_TO
+  || kind0 == GOMP_MAP_ALWAYS_FROM
+  || kind0 == GOMP_MAP_ALWAYS_TOFROM)
+   fprintf (stderr, "always to/from (scalar)\n");
+ else if (kind0 == GOMP_MAP_STRUCT)
+   fprintf (stderr, "struct\n");
+ else if (kind0 == GOMP_MAP_ALWAYS_POINTER)
+   fprintf (stderr, "always pointer (by itself)\n");
+ else if (kind0 == GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION)
+   fprintf (stderr, "ptr to 0-length array section (by itself)\n");
+ else if (kind0 == GOMP_MAP_RELEASE)
+   fprintf (stderr, "release\n");
+ else if (kind0 == GOMP_MAP_ATTACH)
+   fprintf (stderr, "attach\n");
+ else if (kind0 == GOMP_MAP_DETACH)
+   fprintf (stderr, "detach\n");
+ else if (kind0 == GOMP_MAP_FORCE_DETACH)
+   fprintf (stderr, "force detach\n");
+ else if (kind0 == GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION)
+   fprintf (stderr, "attach 0-length array section\n");
+ else if (kind0 == GOMP_MAP_FIRSTPRIVATE_POINTER)
+  

[PATCH 09/11] Not for committing: noisy sibling-list handling output

2021-10-01 Thread Julian Brown
As a possible aid to review, this is my "printf-style" debugging cruft for
the sibling list handling hoist/rework.  It's not meant for committing.
---
 gcc/gimplify.c | 131 +
 1 file changed, 131 insertions(+)

diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 2ec83bf273b..ffb6eda5490 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -71,6 +71,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-nested.h"
 
 //#define NOISY_TOPOSORT
+//#define NOISY_SIBLING_LISTS
 
 /* Hash set of poisoned variables in a bind expr.  */
 static hash_set *asan_poisoned_variables = NULL;
@@ -9895,6 +9896,11 @@ build_struct_group (enum omp_region_type region_type, 
enum tree_code code,
   bool openmp = !(region_type & ORT_ACC);
   tree *continue_at = NULL;
 
+#ifdef NOISY_SIBLING_LISTS
+  fprintf (stderr, "DECL starts out as:\n");
+  debug_generic_expr (ocd);
+#endif
+
   while (TREE_CODE (ocd) == ARRAY_REF)
 ocd = TREE_OPERAND (ocd, 0);
 
@@ -9903,6 +9909,11 @@ build_struct_group (enum omp_region_type region_type, 
enum tree_code code,
 
   tree base = extract_base_bit_offset (ocd, , );
 
+#ifdef NOISY_SIBLING_LISTS
+  fprintf (stderr, "BASE after extraction is (%p):\n", (void *) base);
+  debug_generic_expr (base);
+#endif
+
   bool ptr = (OMP_CLAUSE_MAP_KIND (grp_end) == GOMP_MAP_ALWAYS_POINTER);
   bool attach_detach = ((OMP_CLAUSE_MAP_KIND (grp_end)
 == GOMP_MAP_ATTACH_DETACH)
@@ -9917,6 +9928,25 @@ build_struct_group (enum omp_region_type region_type, 
enum tree_code code,
   if (openmp && attach_detach)
 return NULL;
 
+#ifdef NOISY_SIBLING_LISTS
+  if (struct_map_to_clause)
+{
+  fprintf (stderr, "s_m_t_c->get (base) = ");
+  debug_generic_expr (base);
+  tree *r = struct_map_to_clause->get (base);
+  fprintf (stderr, "returns: ");
+  if (r)
+   {
+ tree tmp = OMP_CLAUSE_CHAIN (*r);
+ OMP_CLAUSE_CHAIN (*r) = NULL_TREE;
+ debug_generic_expr (*r);
+ OMP_CLAUSE_CHAIN (*r) = tmp;
+   }
+  else
+   fprintf (stderr, "(nothing)\n");
+}
+#endif
+
   if (!struct_map_to_clause || struct_map_to_clause->get (base) == NULL)
 {
   tree l = build_omp_clause (OMP_CLAUSE_LOCATION (grp_end), 
OMP_CLAUSE_MAP);
@@ -10026,6 +10056,11 @@ build_struct_group (enum omp_region_type region_type, 
enum tree_code code,
 {
   tree *osc = struct_map_to_clause->get (base);
   tree *sc = NULL, *scp = NULL;
+#ifdef NOISY_SIBLING_LISTS
+  fprintf (stderr, "looked up osc %p for decl (%p)\n", (void *) osc,
+  (void *) base);
+  debug_generic_expr (base);
+#endif
   sc = _CLAUSE_CHAIN (*osc);
   /* The struct mapping might be immediately followed by a
 FIRSTPRIVATE_POINTER and/or FIRSTPRIVATE_REFERENCE -- if it's an
@@ -10098,6 +10133,17 @@ build_struct_group (enum omp_region_type region_type, 
enum tree_code code,
return NULL;
  }
  }
+#ifdef NOISY_SIBLING_LISTS
+   if (known_eq (coffset, offset) && known_eq (cbitpos, bitpos))
+ {
+   fprintf (stderr, "duplicate offset!\n");
+   tree o1 = OMP_CLAUSE_DECL (*sc);
+   tree o2 = OMP_CLAUSE_DECL (grp_end);
+   debug_generic_expr (o1);
+   debug_generic_expr (o2);
+ }
+   else
+#endif
if (maybe_lt (coffset, offset)
|| (known_eq (coffset, offset)
&& maybe_lt (cbitpos, bitpos)))
@@ -10174,6 +10220,13 @@ build_struct_group (enum omp_region_type region_type, 
enum tree_code code,
= cl ? move_concat_nodes_after (cl, tail_chain, grp_start_p,
grp_end, sc)
 : move_nodes_after (grp_start_p, grp_end, sc);
+#ifdef NOISY_SIBLING_LISTS
+ if (continue_at)
+   {
+ fprintf (stderr, "continue at (1):\n");
+ debug_generic_expr (*continue_at);
+   }
+#endif
}
   else if (*sc != grp_end)
{
@@ -10187,6 +10240,10 @@ build_struct_group (enum omp_region_type region_type, 
enum tree_code code,
 the correct position in the struct component list, which in this
 case is just SC.  */
  move_node_after (grp_end, grp_start_p, sc);
+#ifdef NOISY_SIBLING_LISTS
+ fprintf (stderr, "continue at (2):\n");
+ debug_generic_expr (*continue_at);
+#endif
}
 }
   return continue_at;
@@ -10218,6 +10275,16 @@ omp_build_struct_sibling_lists (enum tree_code code,
 
   new_next = NULL;
 
+#ifdef NOISY_SIBLING_LISTS
+  {
+   tree *tmp = grp->grp_start;
+   grp->grp_start = grp_start_p;
+   fprintf (stderr, "processing group %u:\n", i);
+   debug_mapping_group (grp);
+   grp->grp_start = tmp;
+  }
+#endif
+
   if (DECL_P (decl))
continue;
 
@@ -10252,6 +10319,11 @@ omp_build_struct_sibling_lists 

[PATCH 07/11] OpenMP: Fix non-zero attach/detach bias for struct dereferences

2021-10-01 Thread Julian Brown
This patch fixes attach/detach operations for OpenMP that have a non-zero
bias: these can occur if we have a mapping such as:

  #pragma omp target map(mystruct->a.b[idx].c[:arrsz])

i.e. where there is an offset between the attachment point ("mystruct"
here) and the pointed-to data.  (The "b" and "c" members would be array
types here, not pointers themselves).  In this example the difference
(thus bias encoded in the attach/detach node) will be something like:

  (uintptr_t) >a.b[idx].c[0] - (uintptr_t) >a

OK for mainline?

Thanks,

Julian

2021-09-29  Julian Brown  

gcc/c-family/
* c-common.h (c_omp_decompose_attachable_address): Add prototype.
* c-omp.c (c_omp_decompose_attachable_address): New function.

gcc/c/
* c-typeck.c (handle_omp_array_sections): Handle attach/detach for
struct dereferences with non-zero bias.

gcc/cp/
* semantics.c (handle_omp_array_section): Handle attach/detach for
struct dereferences with non-zero bias.

libgomp/
* testsuite/libgomp.c++/baseptrs-3.C: Add test (XFAILed for now).
* testsuite/libgomp.c-c++-common/baseptrs-1.c: Add test.
* testsuite/libgomp.c-c++-common/baseptrs-2.c: Add test.
---
 gcc/c-family/c-common.h   |   1 +
 gcc/c-family/c-omp.c  |  42 
 gcc/c/c-typeck.c  |  12 +-
 gcc/cp/semantics.c|  14 +-
 libgomp/testsuite/libgomp.c++/baseptrs-3.C| 182 ++
 .../libgomp.c-c++-common/baseptrs-1.c |  50 +
 .../libgomp.c-c++-common/baseptrs-2.c |  70 +++
 7 files changed, 364 insertions(+), 7 deletions(-)
 create mode 100644 libgomp/testsuite/libgomp.c++/baseptrs-3.C
 create mode 100644 libgomp/testsuite/libgomp.c-c++-common/baseptrs-1.c
 create mode 100644 libgomp/testsuite/libgomp.c-c++-common/baseptrs-2.c

diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 849cefab882..dab2dd33573 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -1249,6 +1249,7 @@ extern tree c_omp_check_context_selector (location_t, 
tree);
 extern void c_omp_mark_declare_variant (location_t, tree, tree);
 extern const char *c_omp_map_clause_name (tree, bool);
 extern void c_omp_adjust_map_clauses (tree, bool);
+extern tree c_omp_decompose_attachable_address (tree t, tree *virtbase);
 
 enum c_omp_directive_kind {
   C_OMP_DIR_STANDALONE,
diff --git a/gcc/c-family/c-omp.c b/gcc/c-family/c-omp.c
index 1f07a0a454b..fc50f57e768 100644
--- a/gcc/c-family/c-omp.c
+++ b/gcc/c-family/c-omp.c
@@ -3119,6 +3119,48 @@ c_omp_adjust_map_clauses (tree clauses, bool is_target)
 }
 }
 
+tree
+c_omp_decompose_attachable_address (tree t, tree *virtbase)
+{
+  *virtbase = t;
+
+  /* It's already a pointer.  Just use that.  */
+  if (POINTER_TYPE_P (TREE_TYPE (t)))
+return NULL_TREE;
+
+  /* Otherwise, look for a base pointer deeper within the expression.  */
+
+  while (TREE_CODE (t) == COMPONENT_REF
+&& (TREE_CODE (TREE_OPERAND (t, 0)) == COMPONENT_REF
+|| TREE_CODE (TREE_OPERAND (t, 0)) == ARRAY_REF))
+{
+  t = TREE_OPERAND (t, 0);
+  while (TREE_CODE (t) == ARRAY_REF)
+   t = TREE_OPERAND (t, 0);
+}
+
+
+  *virtbase = t;
+
+  if (TREE_CODE (t) != COMPONENT_REF)
+return NULL_TREE;
+
+  t = TREE_OPERAND (t, 0);
+
+  tree attach_pt = NULL_TREE;
+
+  if ((TREE_CODE (t) == INDIRECT_REF
+   || TREE_CODE (t) == MEM_REF)
+  && TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == POINTER_TYPE)
+{
+  attach_pt = TREE_OPERAND (t, 0);
+  if (TREE_CODE (attach_pt) == POINTER_PLUS_EXPR)
+   attach_pt = TREE_OPERAND (attach_pt, 0);
+}
+
+  return attach_pt;
+}
+
 static const struct c_omp_directive omp_directives[] = {
   /* Keep this alphabetically sorted by the first word.  Non-null second/third
  if any should precede null ones.  */
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index d0494cadf05..d1fd8be8e57 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -13696,9 +13696,15 @@ handle_omp_array_sections (tree c, enum 
c_omp_region_type ort)
   if (size)
size = c_fully_fold (size, false, NULL);
   OMP_CLAUSE_SIZE (c) = size;
+  tree virtbase = t;
+  tree attach_pt
+   = ((ort != C_ORT_ACC)
+  ? c_omp_decompose_attachable_address (t, )
+  : NULL_TREE);
   if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP
  || (TREE_CODE (t) == COMPONENT_REF
- && TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE))
+ && TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
+ && !attach_pt))
return false;
   gcc_assert (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FORCE_DEVICEPTR);
   switch (OMP_CLAUSE_MAP_KIND (c))
@@ -13731,10 +13737,10 @@ handle_omp_array_sections (tree c, enum 
c_omp_region_type ort)
   if (OMP_CLAUSE_MAP_KIND (c2) != GOMP_MAP_FIRSTPRIVATE_POINTER
  && !c_mark_addressable (t))
return false;
-  

[PATCH 08/11] Not for committing: noisy topological sorting output

2021-10-01 Thread Julian Brown
As a possible aid to review, this is my "printf-style" debugging cruft for
the topological sorting implementation.

We might want to rework this into something that emits scannable output
into the gimple dump in order to write tests to make sure base pointer
dependencies are being found properly, but that hasn't been done yet.

This is not for committing.
---
 gcc/gimplify.c | 169 ++---
 1 file changed, 161 insertions(+), 8 deletions(-)

diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 31e2e4d9fe7..2ec83bf273b 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -70,6 +70,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "context.h"
 #include "tree-nested.h"
 
+//#define NOISY_TOPOSORT
+
 /* Hash set of poisoned variables in a bind expr.  */
 static hash_set *asan_poisoned_variables = NULL;
 
@@ -8957,6 +8959,10 @@ omp_gather_mapping_groups (tree *list_p)
 {
   vec *groups = new vec ();
 
+#ifdef NOISY_TOPOSORT
+  fprintf (stderr, "GATHER MAPPING GROUPS\n");
+#endif
+
   for (tree *cp = list_p; *cp; cp = _CLAUSE_CHAIN (*cp))
 {
   if (OMP_CLAUSE_CODE (*cp) != OMP_CLAUSE_MAP)
@@ -8965,6 +8971,25 @@ omp_gather_mapping_groups (tree *list_p)
   tree *grp_last_p = omp_group_last (cp);
   omp_mapping_group grp;
 
+#ifdef NOISY_TOPOSORT
+  if (cp == grp_last_p)
+   {
+ tree tmp = OMP_CLAUSE_CHAIN (*cp);
+ OMP_CLAUSE_CHAIN (*cp) = NULL_TREE;
+ fprintf (stderr, "found singleton clause:\n");
+ debug_generic_expr (*cp);
+ OMP_CLAUSE_CHAIN (*cp) = tmp;
+   }
+  else
+   {
+ tree tmp = OMP_CLAUSE_CHAIN (*grp_last_p);
+ OMP_CLAUSE_CHAIN (*grp_last_p) = NULL_TREE;
+ fprintf (stderr, "found group:\n");
+ debug_generic_expr (*cp);
+ OMP_CLAUSE_CHAIN (*grp_last_p) = tmp;
+   }
+#endif
+
   grp.grp_start = cp;
   grp.grp_end = *grp_last_p;
   grp.mark = UNVISITED;
@@ -9129,14 +9154,44 @@ omp_index_mapping_groups (vec 
*groups)
   omp_mapping_group *grp;
   unsigned int i;
 
+#ifdef NOISY_TOPOSORT
+  fprintf (stderr, "INDEX MAPPING GROUPS\n");
+#endif
+
   FOR_EACH_VEC_ELT (*groups, i, grp)
 {
+#ifdef NOISY_TOPOSORT
+  debug_mapping_group (grp);
+#endif
+
   tree fpp;
   unsigned int chained;
   tree node = omp_group_base (grp, , );
 
   if (node == error_mark_node || (!node && !fpp))
-   continue;
+   {
+#ifdef NOISY_TOPOSORT
+ fprintf (stderr, " -- NULL base, not indexing.\n");
+#endif
+ continue;
+   }
+
+#ifdef NOISY_TOPOSORT
+  if (node)
+   {
+ fprintf (stderr, "base%s: ", chained > 1 ? " list" : "");
+
+ tree walk = node;
+ for (unsigned j = 0; j < chained; walk = OMP_CLAUSE_CHAIN (walk), j++)
+   debug_generic_expr (OMP_CLAUSE_DECL (walk));
+   }
+
+  if (fpp)
+   {
+ fprintf (stderr, "firstprivate pointer/reference: ");
+ debug_generic_expr (fpp);
+   }
+#endif
 
   for (unsigned j = 0;
   node && j < chained;
@@ -9156,7 +9211,11 @@ omp_index_mapping_groups (vec *groups)
  omp_mapping_group **prev = grpmap->get (decl);
 
  if (prev && *prev == grp)
-   /* Empty.  */;
+   {
+#ifdef NOISY_TOPOSORT
+ fprintf (stderr, " -- same node\n");
+#endif
+   }
  else if (prev)
{
  /* Mapping the same thing twice is normally diagnosed as an error,
@@ -9171,9 +9230,17 @@ omp_index_mapping_groups (vec *groups)
 
  grp->sibling = (*prev)->sibling;
  (*prev)->sibling = grp;
+#ifdef NOISY_TOPOSORT
+ fprintf (stderr, " -- index as sibling\n");
+#endif
}
  else
-   grpmap->put (decl, grp);
+   {
+#ifdef NOISY_TOPOSORT
+ fprintf (stderr, " -- index as new decl\n");
+#endif
+ grpmap->put (decl, grp);
+   }
}
 
   if (!fpp)
@@ -9184,9 +9251,17 @@ omp_index_mapping_groups (vec *groups)
{
  grp->sibling = (*prev)->sibling;
  (*prev)->sibling = grp;
+#ifdef NOISY_TOPOSORT
+ fprintf (stderr, " -- index fpp as sibling\n");
+#endif
}
   else
-   grpmap->put (fpp, grp);
+   {
+#ifdef NOISY_TOPOSORT
+ fprintf (stderr, " -- index fpp as new decl\n");
+#endif
+ grpmap->put (fpp, grp);
+   }
 }
   return grpmap;
 }
@@ -9233,6 +9308,11 @@ omp_tsort_mapping_groups_1 (omp_mapping_group ***outlist,
  *grpmap,
omp_mapping_group *grp)
 {
+#ifdef NOISY_TOPOSORT
+  fprintf (stderr, "processing node/group:\n");
+  debug_mapping_group (grp);
+#endif
+
   if (grp->mark == PERMANENT)
 return true;
   if (grp->mark == TEMPORARY)
@@ -9253,11 +9333,26 @@ omp_tsort_mapping_groups_1 (omp_mapping_group 
***outlist,
   if (basep)
{
  gcc_assert (*basep != grp);
+#ifdef NOISY_TOPOSORT
+ 

[PATCH 06/11] OpenMP: Allow array ref components for C & C++

2021-10-01 Thread Julian Brown
This patch fixes parsing for struct components that are array references
in OMP clauses in both the C and C++ front ends.

OK for mainline?

Thanks,

Julian

2021-09-29  Julian Brown  

gcc/c/
* c-typeck.c (c_finish_omp_clauses): Allow ARRAY_REF components.

gcc/cp/
* semantics.c (finish_omp_clauses): Allow ARRAY_REF components.
---
 gcc/c/c-typeck.c   | 3 ++-
 gcc/cp/semantics.c | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index e10e6aa8439..d0494cadf05 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -14815,7 +14815,8 @@ c_finish_omp_clauses (tree clauses, enum 
c_omp_region_type ort)
{
  t = TREE_OPERAND (t, 0);
  if (TREE_CODE (t) == MEM_REF
- || TREE_CODE (t) == INDIRECT_REF)
+ || TREE_CODE (t) == INDIRECT_REF
+ || TREE_CODE (t) == ARRAY_REF)
{
  t = TREE_OPERAND (t, 0);
  STRIP_NOPS (t);
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 6e954ca06a6..53bd8d236bb 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -7849,7 +7849,8 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type 
ort)
  if (REFERENCE_REF_P (t))
t = TREE_OPERAND (t, 0);
  if (TREE_CODE (t) == MEM_REF
- || TREE_CODE (t) == INDIRECT_REF)
+ || TREE_CODE (t) == INDIRECT_REF
+ || TREE_CODE (t) == ARRAY_REF)
{
  t = TREE_OPERAND (t, 0);
  STRIP_NOPS (t);
-- 
2.29.2



[PATCH 05/11] OpenMP/OpenACC: Hoist struct sibling list handling in gimplification

2021-10-01 Thread Julian Brown
This patch lifts struct sibling-list handling out of the main loop in
gimplify_scan_omp_clauses.  The reasons for this are several: first,
it means that we can subject created sibling list groups to topological
sorting (see previous patch) so base-pointer data dependencies are
handled correctly.

Secondly, it means that in the first pass gathering up sibling lists
from parsed OpenMP/OpenACC clauses, we don't need to worry about
gimplifying: that means we can see struct bases & components we need
to sort sibling lists properly, even when we're using a non-DECL_P
struct base.  Gimplification proper still happens

Thirdly, because we use more than one pass through the clause list and
gather appropriate data, we can tell if we're mapping a whole struct
in a different node, and avoid building struct sibling lists for that
struct appropriately.

Fourthly, we can re-use the node grouping functions from the
previous patch, and thus mostly avoid the "prev_list_p" handling in
gimplify_scan_omp_clauses that tracks the first node in such groups
at present.

Some redundant code has been removed and code paths for OpenACC/OpenMP are
now shared where appropriate, though OpenACC doesn't do the topological
sorting of nodes (yet?).

OK for mainline?

Thanks,

Julian

2021-09-29  Julian Brown  

gcc/
* gimplify.c (gimplify_omp_var_data): Remove GOVD_MAP_HAS_ATTACHMENTS.
(extract_base_bit_offset): Remove OFFSETP parameter.
(strip_components_and_deref): Extend with POINTER_PLUS_EXPR and
COMPOUND_EXPR handling.
(aggregate_base_p): Remove.
(omp_group_last, omp_group_base): Add GOMP_MAP_STRUCT handling.
(build_struct_group): Remove CTX, DECL, PD, COMPONENT_REF_P, FLAGS,
STRUCT_SEEN_CLAUSE, PRE_P, CONT parameters.  Replace PREV_LIST_P and C
parameters with GRP_START_P and GRP_END.  Add INNER.  Update calls to
extract_base_bit_offset.  Remove gimplification of clauses for OpenMP.
Rework inner struct handling for OpenACC.  Don't use context's
variables splay tree.
(omp_build_struct_sibling_lists): New function, extracted from
gimplify_scan_omp_clauses and refactored.
(gimplify_scan_omp_clauses): Call above function to handle struct
sibling lists.  Remove STRUCT_MAP_TO_CLAUSE, STRUCT_SEEN_CLAUSE,
STRUCT_DEREF_SET.  Rework flag handling, adding decl for struct
variables.
(gimplify_adjust_omp_clauses_1): Remove GOVD_MAP_HAS_ATTACHMENTS
handling, unused now.

gcc/testsuite/
* g++.dg/goacc/member-array-acc.C: Update expected output.
* g++.dg/gomp/target-3.C: Likewise.
* g++.dg/gomp/target-lambda-1.C: Likewise.
* g++.dg/gomp/target-this-2.C: Likewise.
* g++.dg/gomp/target-this-4.C: Likewise.
---
 gcc/gimplify.c| 943 --
 gcc/testsuite/g++.dg/goacc/member-array-acc.C |   2 +-
 gcc/testsuite/g++.dg/gomp/target-3.C  |   4 +-
 gcc/testsuite/g++.dg/gomp/target-lambda-1.C   |   2 +-
 gcc/testsuite/g++.dg/gomp/target-this-2.C |   2 +-
 gcc/testsuite/g++.dg/gomp/target-this-4.C |   4 +-
 6 files changed, 410 insertions(+), 547 deletions(-)

diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index c10a3e8842a..31e2e4d9fe7 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -125,10 +125,6 @@ enum gimplify_omp_var_data
   /* Flag for GOVD_REDUCTION: inscan seen in {in,ex}clusive clause.  */
   GOVD_REDUCTION_INSCAN = 0x200,
 
-  /* Flag for GOVD_MAP: (struct) vars that have pointer attachments for
- fields.  */
-  GOVD_MAP_HAS_ATTACHMENTS = 0x400,
-
   /* Flag for GOVD_FIRSTPRIVATE: OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT.  */
   GOVD_FIRSTPRIVATE_IMPLICIT = 0x800,
 
@@ -8642,7 +8638,7 @@ build_struct_comp_nodes (enum tree_code code, tree 
grp_start, tree grp_end,
 
 static tree
 extract_base_bit_offset (tree base, poly_int64 *bitposp,
-poly_offset_int *poffsetp, tree *offsetp)
+poly_offset_int *poffsetp)
 {
   tree offset;
   poly_int64 bitsize, bitpos;
@@ -8670,7 +8666,6 @@ extract_base_bit_offset (tree base, poly_int64 *bitposp,
 
   *bitposp = bitpos;
   *poffsetp = poffset;
-  *offsetp = offset;
 
   return base;
 }
@@ -8683,8 +8678,15 @@ strip_components_and_deref (tree expr)
   while (TREE_CODE (expr) == COMPONENT_REF
 || TREE_CODE (expr) == INDIRECT_REF
 || (TREE_CODE (expr) == MEM_REF
-&& integer_zerop (TREE_OPERAND (expr, 1
-expr = TREE_OPERAND (expr, 0);
+&& integer_zerop (TREE_OPERAND (expr, 1)))
+|| TREE_CODE (expr) == POINTER_PLUS_EXPR
+|| TREE_CODE (expr) == COMPOUND_EXPR)
+  if (TREE_CODE (expr) == COMPOUND_EXPR)
+   expr = TREE_OPERAND (expr, 1);
+  else
+   expr = TREE_OPERAND (expr, 0);
+
+  STRIP_NOPS (expr);
 
   return expr;
 }
@@ -8700,34 +8702,6 @@ strip_indirections (tree expr)
   return expr;
 }
 
-/* Return TRUE if EXPR is something we 

[PATCH 04/11] Remove omp_target_reorder_clauses

2021-10-01 Thread Julian Brown
This patch has been split out from the previous one to avoid a
confusingly-interleaved diff.  The two patches should probably be
committed squashed together.

2021-10-01  Julian Brown  

gcc/
* gimplify.c (omp_target_reorder_clauses): Delete.
---
 gcc/gimplify.c | 183 -
 1 file changed, 183 deletions(-)

diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index d3346fc8d35..c10a3e8842a 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -8728,189 +8728,6 @@ aggregate_base_p (tree expr)
   return false;
 }
 
-#if 0
-/* Implement OpenMP 5.x map ordering rules for target directives. There are
-   several rules, and with some level of ambiguity, hopefully we can at least
-   collect the complexity here in one place.  */
-
-static void
-omp_target_reorder_clauses (tree *list_p)
-{
-  /* Collect refs to alloc/release/delete maps.  */
-  auto_vec ard;
-  tree *cp = list_p;
-  while (*cp != NULL_TREE)
-if (OMP_CLAUSE_CODE (*cp) == OMP_CLAUSE_MAP
-   && (OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_ALLOC
-   || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_RELEASE
-   || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_DELETE))
-  {
-   /* Unlink cp and push to ard.  */
-   tree c = *cp;
-   tree nc = OMP_CLAUSE_CHAIN (c);
-   *cp = nc;
-   ard.safe_push (c);
-
-   /* Any associated pointer type maps should also move along.  */
-   while (*cp != NULL_TREE
-  && OMP_CLAUSE_CODE (*cp) == OMP_CLAUSE_MAP
-  && (OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
-  || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_FIRSTPRIVATE_POINTER
-  || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_ATTACH_DETACH
-  || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_POINTER
-  || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_ALWAYS_POINTER
-  || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_TO_PSET))
- {
-   c = *cp;
-   nc = OMP_CLAUSE_CHAIN (c);
-   *cp = nc;
-   ard.safe_push (c);
- }
-  }
-else
-  cp = _CLAUSE_CHAIN (*cp);
-
-  /* Link alloc/release/delete maps to the end of list.  */
-  for (unsigned int i = 0; i < ard.length (); i++)
-{
-  *cp = ard[i];
-  cp = _CLAUSE_CHAIN (ard[i]);
-}
-  *cp = NULL_TREE;
-
-  /* OpenMP 5.0 requires that pointer variables are mapped before
- its use as a base-pointer.  */
-  auto_vec atf;
-  for (tree *cp = list_p; *cp; cp = _CLAUSE_CHAIN (*cp))
-if (OMP_CLAUSE_CODE (*cp) == OMP_CLAUSE_MAP)
-  {
-   /* Collect alloc, to, from, to/from clause tree pointers.  */
-   gomp_map_kind k = OMP_CLAUSE_MAP_KIND (*cp);
-   if (k == GOMP_MAP_ALLOC
-   || k == GOMP_MAP_TO
-   || k == GOMP_MAP_FROM
-   || k == GOMP_MAP_TOFROM
-   || k == GOMP_MAP_ALWAYS_TO
-   || k == GOMP_MAP_ALWAYS_FROM
-   || k == GOMP_MAP_ALWAYS_TOFROM)
- atf.safe_push (cp);
-  }
-
-  for (unsigned int i = 0; i < atf.length (); i++)
-if (atf[i])
-  {
-   tree *cp = atf[i];
-   tree decl = OMP_CLAUSE_DECL (*cp);
-   if (TREE_CODE (decl) == INDIRECT_REF || TREE_CODE (decl) == MEM_REF)
- {
-   tree base_ptr = TREE_OPERAND (decl, 0);
-   STRIP_TYPE_NOPS (base_ptr);
-   for (unsigned int j = i + 1; j < atf.length (); j++)
- if (atf[j])
-   {
- tree *cp2 = atf[j];
- tree decl2 = OMP_CLAUSE_DECL (*cp2);
-
- decl2 = OMP_CLAUSE_DECL (*cp2);
- if (is_or_contains_p (decl2, base_ptr))
-   {
- /* Move *cp2 to before *cp.  */
- tree c = *cp2;
- *cp2 = OMP_CLAUSE_CHAIN (c);
- OMP_CLAUSE_CHAIN (c) = *cp;
- *cp = c;
-
- if (*cp2 != NULL_TREE
- && OMP_CLAUSE_CODE (*cp2) == OMP_CLAUSE_MAP
- && OMP_CLAUSE_MAP_KIND (*cp2) == 
GOMP_MAP_ALWAYS_POINTER)
-   {
- tree c2 = *cp2;
- *cp2 = OMP_CLAUSE_CHAIN (c2);
- OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (c);
- OMP_CLAUSE_CHAIN (c) = c2;
-   }
-
- atf[j] = NULL;
- }
-   }
- }
-  }
-
-  /* For attach_detach map clauses, if there is another map that maps the
- attached/detached pointer, make sure that map is ordered before the
- attach_detach.  */
-  atf.truncate (0);
-  for (tree *cp = list_p; *cp; cp = _CLAUSE_CHAIN (*cp))
-if (OMP_CLAUSE_CODE (*cp) == OMP_CLAUSE_MAP)
-  {
-   /* Collect alloc, to, from, to/from clauses, and
-  always_pointer/attach_detach clauses.  */
-   gomp_map_kind k = OMP_CLAUSE_MAP_KIND (*cp);
-   if (k == GOMP_MAP_ALLOC
-   || k 

[PATCH 03/11] OpenMP 5.0: Clause ordering for OpenMP 5.0 (topological sorting by base pointer)

2021-10-01 Thread Julian Brown
This patch reimplements the omp_target_reorder_clauses function in
anticipation of supporting "deeper" struct mappings (that is, with
several structure dereference operators, or similar).

The idea is that in place of the (possibly quadratic) algorithm in
omp_target_reorder_clauses that greedily moves clauses containing
addresses that are subexpressions of other addresses before those other
addresses, we employ a topological sort algorithm to calculate a proper
order for map clauses. This should run in linear time, and hopefully
handles degenerate cases where multiple "levels" of indirect accesses
are present on a given directive.

The new method also takes care to keep clause groups together, addressing
the concerns raised in:

  https://gcc.gnu.org/pipermail/gcc-patches/2021-May/570501.html

To figure out if some given clause depends on a base pointer in another
clause, we strip off the outer layers of the address expression, and check
(via a tree_operand_hash hash table we have built) if the result is a
"base pointer" as defined in OpenMP 5.0 (1.2.6 Data Terminology). There
are some subtleties involved, however:

 - We must treat MEM_REF with zero offset the same as INDIRECT_REF.
   This should probably be fixed in the front ends instead so we always
   use a canonical form (probably INDIRECT_REF). The following patch
   shows one instance of the problem, but there may be others:

   https://gcc.gnu.org/pipermail/gcc-patches/2021-May/571382.html

 - Mapping a whole struct implies mapping each of that struct's
   elements, which may be base pointers. Because those base pointers
   aren't necessarily explicitly referenced in the directive in question,
   we treat the whole-struct mapping as a dependency instead.

This version of the patch is significantly improved over the version
posted previously in order to support the subsequent patches in this
series.

OK for mainline?

Thanks,

Julian

2021-09-29  Julian Brown  

gcc/
* gimplify.c (is_or_contains_p, omp_target_reorder_clauses): Delete
functions.
(omp_tsort_mark): Add enum.
(omp_mapping_group): Add struct.
(omp_get_base_pointer, omp_get_attachment, omp_group_last,
omp_gather_mapping_groups, omp_group_base,
omp_index_mapping_groups, omp_containing_struct,
omp_tsort_mapping_groups_1,
omp_tsort_mapping_groups, omp_segregate_mapping_groups,
omp_reorder_mapping_groups): New functions.
(gimplify_scan_omp_clauses): Call above functions instead of
omp_target_reorder_clauses, unless we've seen an error.
* omp-low.c (scan_sharing_clauses): Avoid strict test if we haven't
sorted mapping groups.

gcc/testsuite/
* g++.dg/gomp/target-lambda-1.C: Adjust expected output.
* g++.dg/gomp/target-this-3.C: Likewise.
* g++.dg/gomp/target-this-4.C: Likewise.
---
 gcc/gimplify.c  | 804 +++-
 gcc/omp-low.c   |   7 +-
 gcc/testsuite/g++.dg/gomp/target-lambda-1.C |   6 +-
 gcc/testsuite/g++.dg/gomp/target-this-3.C   |   4 +-
 gcc/testsuite/g++.dg/gomp/target-this-4.C   |   4 +-
 5 files changed, 788 insertions(+), 37 deletions(-)

diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index ece22b7a4ae..d3346fc8d35 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -8675,29 +8675,6 @@ extract_base_bit_offset (tree base, poly_int64 *bitposp,
   return base;
 }
 
-/* Returns true if EXPR is or contains (as a sub-component) BASE_PTR.  */
-
-static bool
-is_or_contains_p (tree expr, tree base_ptr)
-{
-  if ((TREE_CODE (expr) == INDIRECT_REF && TREE_CODE (base_ptr) == MEM_REF)
-  || (TREE_CODE (expr) == MEM_REF && TREE_CODE (base_ptr) == INDIRECT_REF))
-return operand_equal_p (TREE_OPERAND (expr, 0),
-   TREE_OPERAND (base_ptr, 0));
-  while (!operand_equal_p (expr, base_ptr))
-{
-  if (TREE_CODE (base_ptr) == COMPOUND_EXPR)
-   base_ptr = TREE_OPERAND (base_ptr, 1);
-  if (TREE_CODE (base_ptr) == COMPONENT_REF
- || TREE_CODE (base_ptr) == POINTER_PLUS_EXPR
- || TREE_CODE (base_ptr) == SAVE_EXPR)
-   base_ptr = TREE_OPERAND (base_ptr, 0);
-  else
-   break;
-}
-  return operand_equal_p (expr, base_ptr);
-}
-
 /* Remove COMPONENT_REFS and indirections from EXPR.  */
 
 static tree
@@ -8751,6 +8728,7 @@ aggregate_base_p (tree expr)
   return false;
 }
 
+#if 0
 /* Implement OpenMP 5.x map ordering rules for target directives. There are
several rules, and with some level of ambiguity, hopefully we can at least
collect the complexity here in one place.  */
@@ -8930,6 +8908,758 @@ omp_target_reorder_clauses (tree *list_p)
}
   }
 }
+#endif
+
+
+enum omp_tsort_mark {
+  UNVISITED,
+  TEMPORARY,
+  PERMANENT
+};
+
+struct omp_mapping_group {
+  tree *grp_start;
+  tree grp_end;
+  omp_tsort_mark mark;
+  struct omp_mapping_group *sibling;
+  struct omp_mapping_group *next;
+};
+

[PATCH 02/11] Remove base_ind/base_ref handling from extract_base_bit_offset

2021-10-01 Thread Julian Brown
In preparation for follow-up patches extending struct dereference
handling for OpenMP, this patch removes base_ind/base_ref handling from
gimplify.c:extract_base_bit_offset. This arguably simplifies some of the
code around the callers of the function also, though subsequent patches
modify those parts further.

OK for mainline?

Thanks,

Julian

2021-09-29  Julian Brown  

gcc/
* gimplify.c (extract_base_bit_offset): Remove BASE_IND, BASE_REF and
OPENMP parameters.
(strip_indirections): New function.
(build_struct_group): Update calls to extract_base_bit_offset.
Rearrange indirect/reference handling accordingly.  Use extracted base
instead of passed-in decl when grouping component accesses together.
---
 gcc/gimplify.c | 109 ++---
 1 file changed, 57 insertions(+), 52 deletions(-)

diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 92f8a7b4073..ece22b7a4ae 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -8641,9 +8641,8 @@ build_struct_comp_nodes (enum tree_code code, tree 
grp_start, tree grp_end,
has array type, else return NULL.  */
 
 static tree
-extract_base_bit_offset (tree base, tree *base_ind, tree *base_ref,
-poly_int64 *bitposp, poly_offset_int *poffsetp,
-tree *offsetp, bool openmp)
+extract_base_bit_offset (tree base, poly_int64 *bitposp,
+poly_offset_int *poffsetp, tree *offsetp)
 {
   tree offset;
   poly_int64 bitsize, bitpos;
@@ -8651,38 +8650,12 @@ extract_base_bit_offset (tree base, tree *base_ind, 
tree *base_ref,
   int unsignedp, reversep, volatilep = 0;
   poly_offset_int poffset;
 
-  if (base_ind)
-*base_ind = NULL_TREE;
-
-  if (base_ref)
-*base_ref = NULL_TREE;
+  STRIP_NOPS (base);
 
   base = get_inner_reference (base, , , , ,
  , , );
 
-  if (!openmp
-  && (TREE_CODE (base) == INDIRECT_REF
- || (TREE_CODE (base) == MEM_REF
- && integer_zerop (TREE_OPERAND (base, 1
-  && TREE_CODE (TREE_TYPE (TREE_OPERAND (base, 0))) == POINTER_TYPE)
-{
-  if (base_ind)
-   *base_ind = base;
-  base = TREE_OPERAND (base, 0);
-}
-  if ((TREE_CODE (base) == INDIRECT_REF
-   || (TREE_CODE (base) == MEM_REF
-  && integer_zerop (TREE_OPERAND (base, 1
-  && DECL_P (TREE_OPERAND (base, 0))
-  && TREE_CODE (TREE_TYPE (TREE_OPERAND (base, 0))) == REFERENCE_TYPE)
-{
-  if (base_ref)
-   *base_ref = base;
-  base = TREE_OPERAND (base, 0);
-}
-
-  if (!openmp)
-STRIP_NOPS (base);
+  STRIP_NOPS (base);
 
   if (offset && poly_int_tree_p (offset))
 {
@@ -8739,6 +8712,17 @@ strip_components_and_deref (tree expr)
   return expr;
 }
 
+static tree
+strip_indirections (tree expr)
+{
+  while (TREE_CODE (expr) == INDIRECT_REF
+|| (TREE_CODE (expr) == MEM_REF
+&& integer_zerop (TREE_OPERAND (expr, 1
+expr = TREE_OPERAND (expr, 0);
+
+  return expr;
+}
+
 /* Return TRUE if EXPR is something we will use as the base of an aggregate
access, either:
 
@@ -9232,7 +9216,7 @@ build_struct_group (struct gimplify_omp_ctx *ctx,
 {
   poly_offset_int coffset;
   poly_int64 cbitpos;
-  tree base_ind, base_ref, tree_coffset;
+  tree tree_coffset;
   tree ocd = OMP_CLAUSE_DECL (c);
   bool openmp = !(region_type & ORT_ACC);
 
@@ -9242,10 +9226,25 @@ build_struct_group (struct gimplify_omp_ctx *ctx,
   if (TREE_CODE (ocd) == INDIRECT_REF)
 ocd = TREE_OPERAND (ocd, 0);
 
-  tree base = extract_base_bit_offset (ocd, _ind, _ref, ,
-  , _coffset, openmp);
+  tree base = extract_base_bit_offset (ocd, , , _coffset);
+  tree sbase;
 
-  bool do_map_struct = (base == decl && !tree_coffset);
+  if (openmp)
+{
+  if (TREE_CODE (base) == INDIRECT_REF
+ && TREE_CODE (TREE_TYPE (TREE_OPERAND (base, 0))) == REFERENCE_TYPE)
+   sbase = strip_indirections (base);
+  else
+   sbase = base;
+}
+  else
+{
+  sbase = strip_indirections (base);
+
+  STRIP_NOPS (sbase);
+}
+
+  bool do_map_struct = (sbase == decl && !tree_coffset);
 
   /* Here, DECL is usually a DECL_P, unless we have chained indirect member
  accesses, e.g. mystruct->a->b.  In that case it'll be the "mystruct->a"
@@ -9305,19 +9304,12 @@ build_struct_group (struct gimplify_omp_ctx *ctx,
 
   OMP_CLAUSE_SET_MAP_KIND (l, k);
 
-  if (!openmp && base_ind)
-   OMP_CLAUSE_DECL (l) = unshare_expr (base_ind);
-  else if (base_ref)
-   OMP_CLAUSE_DECL (l) = unshare_expr (base_ref);
-  else
-   {
- OMP_CLAUSE_DECL (l) = unshare_expr (decl);
- if (openmp
- && !DECL_P (OMP_CLAUSE_DECL (l))
- && (gimplify_expr (_CLAUSE_DECL (l), pre_p, NULL,
-is_gimple_lvalue, fb_lvalue) == GS_ERROR))
-   return error_mark_node;
-   }
+  OMP_CLAUSE_DECL (l) = 

[PATCH 01/11] libgomp: Release device lock on cbuf error path

2021-10-01 Thread Julian Brown
This patch releases the device lock on a sanity-checking error path in
transfer combining (cbuf) handling in libgomp:target.c.  This shouldn't
happen when handling well-formed mapping clauses, but erroneous clauses
can currently cause a hang if the condition triggers.

Tested with offloading to NVPTX. OK?

2021-09-29  Julian Brown  

libgomp/
* target.c (gomp_copy_host2dev): Release device lock on cbuf
error path.
---
 libgomp/target.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/libgomp/target.c b/libgomp/target.c
index 65bb40100e5..84c6fdf2c47 100644
--- a/libgomp/target.c
+++ b/libgomp/target.c
@@ -385,7 +385,10 @@ gomp_copy_host2dev (struct gomp_device_descr *devicep,
  else if (cbuf->chunks[middle].start <= doff)
{
  if (doff + sz > cbuf->chunks[middle].end)
-   gomp_fatal ("internal libgomp cbuf error");
+   {
+ gomp_mutex_unlock (>lock);
+ gomp_fatal ("internal libgomp cbuf error");
+   }
  memcpy ((char *) cbuf->buf + (doff - cbuf->chunks[0].start),
  h, sz);
  return;
-- 
2.29.2



[PATCH 00/11] OpenMP: Deep struct dereferences

2021-10-01 Thread Julian Brown
This is a series of patches to support deep struct dereferences for
OpenMP 5.0 (i.e. with multiple arrow operators,
"a->b[foo]->c[lo:hi]"). Apart from a couple of general bug fixes, the
main parts of this comprise:

  1. Topological sorting of OMP clauses by base pointer dependencies.

  2. Hoisting of struct sibling list handling out of
 gimplify_scan_omp_clauses.

These patches replace and continue from the last part of the
previously-posted series:

  https://gcc.gnu.org/pipermail/gcc-patches/2021-August/577219.html

and (still) depend on the parts of 1 through 7 of that series.

The patches have been bootstrapped & regression tested individually with
offloading to NVPTX (though some prior to the most recent rebase).

OK?

Thanks,

Julian

Julian Brown (11):
  libgomp: Release device lock on cbuf error path
  Remove base_ind/base_ref handling from extract_base_bit_offset
  OpenMP 5.0: Clause ordering for OpenMP 5.0 (topological sorting by
base pointer)
  Remove omp_target_reorder_clauses
  OpenMP/OpenACC: Hoist struct sibling list handling in gimplification
  OpenMP: Allow array ref components for C & C++
  OpenMP: Fix non-zero attach/detach bias for struct dereferences
  Not for committing: noisy topological sorting output
  Not for committing: noisy sibling-list handling output
  Not for committing: noisy mapping-group taxonomy
  OpenMP/OpenACC: [WIP] Add gcc_unreachable to apparently-dead path in
build_struct_comp_nodes

 gcc/c-family/c-common.h   |1 +
 gcc/c-family/c-omp.c  |   42 +
 gcc/c/c-typeck.c  |   15 +-
 gcc/cp/semantics.c|   17 +-
 gcc/gimplify.c| 2479 -
 gcc/omp-low.c |7 +-
 gcc/testsuite/g++.dg/goacc/member-array-acc.C |2 +-
 gcc/testsuite/g++.dg/gomp/target-3.C  |4 +-
 gcc/testsuite/g++.dg/gomp/target-lambda-1.C   |6 +-
 gcc/testsuite/g++.dg/gomp/target-this-2.C |2 +-
 gcc/testsuite/g++.dg/gomp/target-this-3.C |4 +-
 gcc/testsuite/g++.dg/gomp/target-this-4.C |4 +-
 libgomp/target.c  |5 +-
 libgomp/testsuite/libgomp.c++/baseptrs-3.C|  182 ++
 .../libgomp.c-c++-common/baseptrs-1.c |   50 +
 .../libgomp.c-c++-common/baseptrs-2.c |   70 +
 16 files changed, 2151 insertions(+), 739 deletions(-)
 create mode 100644 libgomp/testsuite/libgomp.c++/baseptrs-3.C
 create mode 100644 libgomp/testsuite/libgomp.c-c++-common/baseptrs-1.c
 create mode 100644 libgomp/testsuite/libgomp.c-c++-common/baseptrs-2.c

-- 
2.29.2



Re: [RFC][Patch][middle-end/PR102359]Not add initialization for READONLY variables with -ftrivial-auto-var-init

2021-10-01 Thread Qing Zhao via Gcc-patches


> On Oct 1, 2021, at 10:33 AM, Jason Merrill  wrote:
> 
> On 10/1/21 10:54, Qing Zhao wrote:
>>> On Sep 30, 2021, at 2:31 PM, Jason Merrill  wrote:
>>> 
>>> On 9/30/21 11:42, Qing Zhao wrote:
> On Sep 30, 2021, at 1:54 AM, Richard Biener  wrote:
> 
> On Thu, 30 Sep 2021, Jason Merrill wrote:
> 
>> On 9/29/21 17:30, Qing Zhao wrote:
>>> Hi,
>>> 
>>> PR102359 (ICE gimplification failed since  r12-3433-ga25e0b5e6ac8a77a)
>>> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102359
>>> 
>>> Is due to -ftrivial-auto-var-init adding initialization for READONLY
>>> variable “this” in the following routine: (t.cpp.005t.original)
>>> 
>>> ===
>>> 
>>> ;; Function A::foo():: (null)
>>> ;; enabled by -tree-original
>>> 
>>> {
>>>  const struct A * const this [value-expr: &__closure->__this];
>>>const struct A * const this [value-expr: &__closure->__this];
>>>  return  = (double) ((const struct A *) this)->a;
>>> }
>>> ===
>>> 
>>> However, in the above routine, “this” is NOT marked as READONLY, but its
>>> value-expr "&__closure->__this” is marked as READONLY.
>>> 
>>> There are two major issues:
>>> 
>>> 1. In the routine “is_var_need_auto_init”, we should exclude “decl” 
>>> that is
>>> marked as READONLY;
>>> 2. In the C++ FE, “this” should be marked as READONLY.
>>> 
>>> The idea solution will be:
>>> 
>>> 1. Fix “is_var_need_auto_init” to exclude TREE_READONLY (decl);
>>> 2. Fix C++ FE to mark “this” as TREE_READONLY (decl)==true;
>>> 
>>> Not sure whether it’s hard for C++ FE to fix the 2nd issue or not?
>>> 
>>> In the case it’s not a quick fix in C++FE, I proposed the following fix 
>>> in
>>> middle end:
>>> 
>>> Let me know your comments or suggestions on this.
>>> 
>>> Thanks a lot for the help.
>> 
>> I'd think is_var_need_auto_init should be false for any variable with
>> DECL_HAS_VALUE_EXPR_P, as they aren't really variables, just ways of 
>> naming
>> objects that are initialized elsewhere.
> 
> IIRC handing variables with DECL_HAS_VALUE_EXPR_P is necessary to
> auto-init VLAs, otherwise I tend to agree - would we handle those
> when we see a DECL_EXPR then?
 The current implementation is:
 gimplify_decl_expr:
 For each DECL_EXPR “decl”
If (VAR_P (decl) && !DECL_EXTERNAL (decl))
  {
if (is_vla (decl))
   gimplify_vla_decl (decl, …);  /* existing handling: create a 
 VALUE_EXPR for this vla decl*/
…
if (has_explicit_init (decl))
  {
   …; /* existing handling.  */
  }
else if (is_var_need_auto_init (decl))  /*. New code. */
  {
gimple_add_init_for_auto_var (….);   /*  new code.  */
...
  }
  }
 Since the “DECL_VALUE_EXPR (decl)” is NOT a DECL_EXPR, it will not be 
 scanned and added initialization.
 if we do not add initialization for a decl that has DECL_VALUE_EXPR, then 
 the “DECL_VALUE_EXPR (decl)” will not be added an initialization either.  
 We will miss adding initializations for these decls.
 So, I think that the current implementation is correct.
 And if C++ FE will not mark “this” as READONLY, only mark 
 DECL_VALUE_EXPR(this) as READONLY, the proposed fix is correct too.
 Let me know your opinion on this.
>>> 
>>> The problem with this test is not whether the 'this' proxy is marked 
>>> READONLY, the problem is that you're trying to initialize lambda capture 
>>> proxies at all; the lambda capture objects were already initialized when 
>>> forming the closure object.  So this test currently aborts with 
>>> -ftrivial-auto-var-init=zero because you "initialize" the i capture field 
>>> to 0 after it was previously initialized to 42:
>>> 
>>> int main()
>>> {
>>>  int i = 42;
>>>  auto l = [=]() mutable { return i; };
>>>  if (l() != i)
>>>__builtin_abort ();
>>> }
>>> 
>>> I believe the same issue applies to the proxy variables in coroutines that 
>>> work much like lambdas.
> 
>> So, how should the middle end determine that a variable is “proxy variable”?
> 
> In the front end, is_capture_proxy will identify a lambda capture proxy 
> variable.  But that won't be true for the similar proxies used by coroutines.

Does this mean that in middle end, especially in gimplification phase, there is 
Not a simple way to determine whether a variable is a proxy variable?
> 
>> Have all “proxy variables” been initialized by C++ FE already?
> 
> Yes.
> 
>>> You can't just assume that a VAR_DECL with DECL_VALUE_EXPR is uninitialized.
>> So, all the VAR_DECLs with DECL_VALUE_EXPR (except the ones created by 
>> “gimplify_decl_expr”) are initialized by FE already?
> 
> In general I'd expect them to refer to previously created objects which may 
> or may not have been 

Re: [PATCH] c++: Suppress error when cv-qualified reference is introduced by typedef [PR101783]

2021-10-01 Thread Jason Merrill via Gcc-patches

On 10/1/21 11:10, Nick Huang wrote:

gcc-verify still fails with this version:


ERR: line should start with a tab: "PR c++/101783"
ERR: line should start with a tab: "* tree.c (cp_build_qualified_type_real): 
Excluding typedef from error"
ERR: line should start with a tab: "PR c++/101783"
ERR: line should start with a tab: "* g++.dg/parse/pr101783.C: New test."



It might work better to attach the output of git format-patch.

Sorry for my clumsy copy/paste from git commit message. I now attach
git format-patch output
file as attachment. Also maybe for a little convenience of your work,
I also attach the original
commit message file when I do git commit -F.


Thanks, but that isn't necessary; it should be the same in the 
format-patch output, except...



From e592a475030d99647de736d294cb3c6a7588af49 Mon Sep 17 00:00:00 2001
From: qingzhe huang 
Date: Fri, 1 Oct 2021 10:46:35 -0400
Subject: [PATCH] The root cause of this bug is that it considers reference
 with cv-qualifiers as an error by generating value for variable "bad_quals".
 However, this is not correct for case of typedef. Here I quote spec
 [dcl.ref]/1 : "Cv-qualified references are ill-formed except when the
 cv-qualifiers are introduced through the use of a typedef-name
 ([dcl.typedef], [temp.param]) or decltype-specifier ([dcl.type.decltype]), in
 which case the cv-qualifiers are ignored."


...the subject line for the commit should be the first line of the 
commit message, followed by a blank line, followed by the description of 
the patch; without the subject line, git format-patch thought your whole 
description was the subject of the patch.


I've corrected this and pushed the patch, thanks!

Jason



Re: [PATCH] libiberty: testsuite: add missing format on d-demangle-expected

2021-10-01 Thread H.J. Lu via Gcc-patches
On Wed, Sep 29, 2021 at 5:51 PM Luís Ferreira  wrote:
>
> This patch adds a missing format parameter that prevents d-demangle-expected
> test collection from running successfully.
>
> Signed-off-by: Luís Ferreira 
> ---
>  libiberty/testsuite/d-demangle-expected | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/libiberty/testsuite/d-demangle-expected 
> b/libiberty/testsuite/d-demangle-expected
> index 799f4724b72..44a3649c429 100644
> --- a/libiberty/testsuite/d-demangle-expected
> +++ b/libiberty/testsuite/d-demangle-expected
> @@ -991,6 +991,7 @@ _D88
>  _D5__T1aZv
>  _D5__T1aZv
>  #
> +--format=dlang
>  _D00
>  _D00
>  #
> --
> 2.33.0
>

This counts as an obvious fix.  Please check it in.

Thanks.

-- 
H.J.


Re: [PATCH] c++: Implement C++20 -Wdeprecated-array-compare [PR97573]

2021-10-01 Thread Marek Polacek via Gcc-patches
On Fri, Oct 01, 2021 at 09:16:53AM -0600, Martin Sebor wrote:
> On 9/30/21 8:50 AM, Marek Polacek via Gcc-patches wrote:
> > This patch addresses one of my leftovers from GCC 11.  C++20 introduced
> > [depr.array.comp]:
> > "Equality and relational comparisons between two operands of array type are
> > deprecated."
> > so this patch adds -Wdeprecated-array-compare (enabled by default in C++20).
> 
> A warning like this would be useful in C as well even though there
> array equality is not deprecated (though relational expressions
> involving distinct objects are undefined).  Recently, while working
> on my -Waddress enhancement to "warn for more impossible null
> pointer tests​, I noticed Clang warns for some of these equality
> tests in both languages (it issues -Wtautological-compare).

I'll look into adding this warning to the C FE; it should be trivial.
 
> Rather that referring to deprecation, if one is necessary, I would
> suggest to choose a name for the option that reflects the problem
> the warning (and presumably the deprecation in C++) tries to prevent.
> That said, since GCC already has both -Waddress and -Wtautological-
> compare for these problems, the warning could be issued under either
> of these.

In my previous email I suggested -Warray-compare -- I wanted to avoid
the "deprecated" part outside C++20.

I also noticed the -Wtautological warning clang emits but I don't have
time to look into it.  It probably won't warn for arrays declared with
__attribute__((weak)) so -Warray-compare still makes sense.

> > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
> > 
> > PR c++/97573
> > 
> > gcc/c-family/ChangeLog:
> > 
> > * c-opts.c (c_common_post_options): In C++20, turn on
> > -Wdeprecated-array-compare.
> > * c.opt (Wdeprecated-array-compare): New option.
> > 
> > gcc/cp/ChangeLog:
> > 
> > * typeck.c (do_warn_deprecated_array_compare): New.
> > (cp_build_binary_op): Call it for equality and relational comparisons.
> > 
> > gcc/ChangeLog:
> > 
> > * doc/invoke.texi: Document -Wdeprecated-array-compare.
> > 
> > gcc/testsuite/ChangeLog:
> > 
> > * g++.dg/tree-ssa/pr15791-1.C: Add dg-warning.
> > * g++.dg/cpp2a/array-comp1.C: New test.
> > * g++.dg/cpp2a/array-comp2.C: New test.
> > * g++.dg/cpp2a/array-comp3.C: New test.
> > ---
> >   gcc/c-family/c-opts.c |  5 
> >   gcc/c-family/c.opt|  4 +++
> >   gcc/cp/typeck.c   | 28 +++
> >   gcc/doc/invoke.texi   | 19 -
> >   gcc/testsuite/g++.dg/cpp2a/array-comp1.C  | 34 +++
> >   gcc/testsuite/g++.dg/cpp2a/array-comp2.C  | 31 +
> >   gcc/testsuite/g++.dg/cpp2a/array-comp3.C  | 29 +++
> >   gcc/testsuite/g++.dg/tree-ssa/pr15791-1.C |  2 +-
> >   8 files changed, 150 insertions(+), 2 deletions(-)
> >   create mode 100644 gcc/testsuite/g++.dg/cpp2a/array-comp1.C
> >   create mode 100644 gcc/testsuite/g++.dg/cpp2a/array-comp2.C
> >   create mode 100644 gcc/testsuite/g++.dg/cpp2a/array-comp3.C
> > 
> > diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c
> > index 3eaab5e1530..00b52cc5e12 100644
> > --- a/gcc/c-family/c-opts.c
> > +++ b/gcc/c-family/c-opts.c
> > @@ -962,6 +962,11 @@ c_common_post_options (const char **pfilename)
> >warn_deprecated_enum_float_conv,
> >cxx_dialect >= cxx20 && warn_deprecated);
> > +  /* -Wdeprecated-array-compare is enabled by default in C++20.  */
> > +  SET_OPTION_IF_UNSET (_options, _options_set,
> > +  warn_deprecated_array_compare,
> > +  cxx_dialect >= cxx20 && warn_deprecated);
> > +
> > /* Declone C++ 'structors if -Os.  */
> > if (flag_declone_ctor_dtor == -1)
> >   flag_declone_ctor_dtor = optimize_size;
> > diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
> > index 9c151d19870..a4f0ea68594 100644
> > --- a/gcc/c-family/c.opt
> > +++ b/gcc/c-family/c.opt
> > @@ -540,6 +540,10 @@ Wdeprecated
> >   C C++ ObjC ObjC++ CPP(cpp_warn_deprecated) CppReason(CPP_W_DEPRECATED)
> >   ; Documented in common.opt
> > +Wdeprecated-array-compare
> > +C++ ObjC++ Var(warn_deprecated_array_compare) Warning
> > +Warn about deprecated comparisons between two operands of array type.
> > +
> >   Wdeprecated-copy
> >   C++ ObjC++ Var(warn_deprecated_copy) Warning LangEnabledBy(C++ ObjC++, 
> > Wextra)
> >   Mark implicitly-declared copy operations as deprecated if the class has a
> > diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
> > index a2398dbe660..1e3a41104d6 100644
> > --- a/gcc/cp/typeck.c
> > +++ b/gcc/cp/typeck.c
> > @@ -40,6 +40,7 @@ along with GCC; see the file COPYING3.  If not see
> >   #include "attribs.h"
> >   #include "asan.h"
> >   #include "gimplify.h"
> > +#include "tree-pretty-print.h"
> >   static tree cp_build_addr_expr_strict (tree, tsubst_flags_t);
> >   static tree cp_build_function_call 

Re: [PATCH] c++: unifying equal NONTYPE_ARGUMENT_PACKs [PR102547]

2021-10-01 Thread Jason Merrill via Gcc-patches

On 10/1/21 10:26, Patrick Palka wrote:

On Fri, 1 Oct 2021, Jason Merrill wrote:


On 10/1/21 09:46, Patrick Palka wrote:

Here during partial ordering of the two partial specializations we end
up in unify with parm=arg=NONTYPE_ARGUMENT_PACK, and crash shortly
thereafter because uses_template_parms calls potential_constant_expression
which doesn't handle NONTYPE_ARGUMENT_PACK.

This patch fixes this by checking dependent_template_arg_p instead of
uses_template_parms when parm==arg, which does handle NONTYPE_ARGUMENT_PACK.
We could also perhaps fix uses_template_parms / inst_dep_expr_p to better
handle NONTYPE_ARGUMENT_PACK,


Please.


Sounds good, like the following then?  Passes light testing, bootstrap
and regtest on progress.

-- >8 --

PR c++/102547

gcc/cp/ChangeLog:

* pt.c (instantiation_dependent_expression_p): Sidestep checking
potential_constant_expression on NONTYPE_ARGUMENT_PACK.

gcc/testsuite/ChangeLog:

* g++.dg/cpp0x/variadic-partial2.C: New test.
* g++.dg/cpp0x/variadic-partial2a.C: New test.
---
  gcc/cp/pt.c   |  4 +++-
  .../g++.dg/cpp0x/variadic-partial2.C  | 16 ++
  .../g++.dg/cpp0x/variadic-partial2a.C | 22 +++
  3 files changed, 41 insertions(+), 1 deletion(-)
  create mode 100644 gcc/testsuite/g++.dg/cpp0x/variadic-partial2.C
  create mode 100644 gcc/testsuite/g++.dg/cpp0x/variadic-partial2a.C

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 1dcdffe322a..643204103c5 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -27705,7 +27705,9 @@ instantiation_dependent_expression_p (tree expression)
  {
return (instantiation_dependent_uneval_expression_p (expression)
  || (processing_template_decl
- && potential_constant_expression (expression)
+ && expression != NULL_TREE
+ && (TREE_CODE (expression) == NONTYPE_ARGUMENT_PACK
+ || potential_constant_expression (expression))


I'd prefer to loop over the elements of the pack, either here or 
(probably better) in potential_constant_expression.



  && value_dependent_expression_p (expression)));
  }
  
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-partial2.C b/gcc/testsuite/g++.dg/cpp0x/variadic-partial2.C

new file mode 100644
index 000..df61f26a3c1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic-partial2.C
@@ -0,0 +1,16 @@
+// PR c++/102547
+// { dg-do compile { target c++11 } }
+
+template
+struct vals { };
+
+template
+struct vals_client { };
+
+template
+struct vals_client, T> { };
+
+template
+struct vals_client, void> { };
+
+template struct vals_client, void>; //- "sorry, unimplemented..., 
ICE"
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-partial2a.C 
b/gcc/testsuite/g++.dg/cpp0x/variadic-partial2a.C
new file mode 100644
index 000..cc0ea488ad3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic-partial2a.C
@@ -0,0 +1,22 @@
+// PR c++/102547
+// { dg-do compile { target c++11 } }
+// A version of variadic-partial2.C where the partial ordering is performed
+// on function templates instead of class templates.
+
+template
+struct vals { };
+
+template
+void f(V, T) { };
+
+template
+void f(vals, T) { };
+
+template
+void f(vals, char) { };
+
+template void f(vals<1, 2>, char); //- "sorry, unimplemented..., ICE"
+
+int main() {
+  f(vals<1, 3>{}, 'a'); //- "sorry, unimplemented..., ICE"
+}





[PATCH 2/4] libsanitizer: Apply local patches

2021-10-01 Thread H.J. Lu via Gcc-patches
---
 libsanitizer/asan/asan_globals.cpp| 19 --
 libsanitizer/asan/asan_interceptors.h |  7 ++-
 libsanitizer/asan/asan_mapping.h  |  2 +-
 .../sanitizer_linux_libcdep.cpp   |  4 
 .../sanitizer_common/sanitizer_mac.cpp| 12 +--
 libsanitizer/sanitizer_common/sanitizer_mac.h | 20 +++
 .../sanitizer_platform_limits_linux.cpp   |  5 -
 .../sanitizer_platform_limits_posix.h |  2 +-
 .../sanitizer_common/sanitizer_stacktrace.cpp | 17 +++-
 libsanitizer/tsan/tsan_rtl_ppc64.S|  1 +
 libsanitizer/ubsan/ubsan_flags.cpp|  1 +
 libsanitizer/ubsan/ubsan_handlers.cpp | 15 ++
 libsanitizer/ubsan/ubsan_handlers.h   |  8 
 libsanitizer/ubsan/ubsan_platform.h   |  2 ++
 14 files changed, 85 insertions(+), 30 deletions(-)

diff --git a/libsanitizer/asan/asan_globals.cpp 
b/libsanitizer/asan/asan_globals.cpp
index 9bf378f6207..763d3c6d2c0 100644
--- a/libsanitizer/asan/asan_globals.cpp
+++ b/libsanitizer/asan/asan_globals.cpp
@@ -154,23 +154,6 @@ static void CheckODRViolationViaIndicator(const Global *g) 
{
   }
 }
 
-// Check ODR violation for given global G by checking if it's already poisoned.
-// We use this method in case compiler doesn't use private aliases for global
-// variables.
-static void CheckODRViolationViaPoisoning(const Global *g) {
-  if (__asan_region_is_poisoned(g->beg, g->size_with_redzone)) {
-// This check may not be enough: if the first global is much larger
-// the entire redzone of the second global may be within the first global.
-for (ListOfGlobals *l = list_of_all_globals; l; l = l->next) {
-  if (g->beg == l->g->beg &&
-  (flags()->detect_odr_violation >= 2 || g->size != l->g->size) &&
-  !IsODRViolationSuppressed(g->name))
-ReportODRViolation(g, FindRegistrationSite(g),
-   l->g, FindRegistrationSite(l->g));
-}
-  }
-}
-
 // Clang provides two different ways for global variables protection:
 // it can poison the global itself or its private alias. In former
 // case we may poison same symbol multiple times, that can help us to
@@ -216,8 +199,6 @@ static void RegisterGlobal(const Global *g) {
 // where two globals with the same name are defined in different modules.
 if (UseODRIndicator(g))
   CheckODRViolationViaIndicator(g);
-else
-  CheckODRViolationViaPoisoning(g);
   }
   if (CanPoisonMemory())
 PoisonRedZones(*g);
diff --git a/libsanitizer/asan/asan_interceptors.h 
b/libsanitizer/asan/asan_interceptors.h
index 047b044c8bf..105c672cc24 100644
--- a/libsanitizer/asan/asan_interceptors.h
+++ b/libsanitizer/asan/asan_interceptors.h
@@ -81,7 +81,12 @@ void InitializePlatformInterceptors();
 #if ASAN_HAS_EXCEPTIONS && !SANITIZER_WINDOWS && !SANITIZER_SOLARIS && \
 !SANITIZER_NETBSD
 # define ASAN_INTERCEPT___CXA_THROW 1
-# define ASAN_INTERCEPT___CXA_RETHROW_PRIMARY_EXCEPTION 1
+# if ! defined(ASAN_HAS_CXA_RETHROW_PRIMARY_EXCEPTION) \
+ || ASAN_HAS_CXA_RETHROW_PRIMARY_EXCEPTION
+#   define ASAN_INTERCEPT___CXA_RETHROW_PRIMARY_EXCEPTION 1
+# else
+#   define ASAN_INTERCEPT___CXA_RETHROW_PRIMARY_EXCEPTION 0
+# endif
 # if defined(_GLIBCXX_SJLJ_EXCEPTIONS) || (SANITIZER_IOS && defined(__arm__))
 #  define ASAN_INTERCEPT__UNWIND_SJLJ_RAISEEXCEPTION 1
 # else
diff --git a/libsanitizer/asan/asan_mapping.h b/libsanitizer/asan/asan_mapping.h
index e5a7f2007ae..4b0037fced3 100644
--- a/libsanitizer/asan/asan_mapping.h
+++ b/libsanitizer/asan/asan_mapping.h
@@ -165,7 +165,7 @@ static const u64 kAArch64_ShadowOffset64 = 1ULL << 36;
 static const u64 kRiscv64_ShadowOffset64 = 0xd;
 static const u64 kMIPS32_ShadowOffset32 = 0x0aaa;
 static const u64 kMIPS64_ShadowOffset64 = 1ULL << 37;
-static const u64 kPPC64_ShadowOffset64 = 1ULL << 44;
+static const u64 kPPC64_ShadowOffset64 = 1ULL << 41;
 static const u64 kSystemZ_ShadowOffset64 = 1ULL << 52;
 static const u64 kSPARC64_ShadowOffset64 = 1ULL << 43;  // 0x800
 static const u64 kFreeBSD_ShadowOffset32 = 1ULL << 30;  // 0x4000
diff --git a/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp 
b/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp
index 7ce9e25da34..fc5619e4b37 100644
--- a/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp
+++ b/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp
@@ -759,9 +759,13 @@ u32 GetNumberOfCPUs() {
 #elif SANITIZER_SOLARIS
   return sysconf(_SC_NPROCESSORS_ONLN);
 #else
+#if defined(CPU_COUNT)
   cpu_set_t CPUs;
   CHECK_EQ(sched_getaffinity(0, sizeof(cpu_set_t), ), 0);
   return CPU_COUNT();
+#else
+  return 1;
+#endif
 #endif
 }
 
diff --git a/libsanitizer/sanitizer_common/sanitizer_mac.cpp 
b/libsanitizer/sanitizer_common/sanitizer_mac.cpp
index b8839f197d2..fa077a129c2 100644
--- a/libsanitizer/sanitizer_common/sanitizer_mac.cpp
+++ 

[PATCH 0/4] libsanitizer: Merge with upstream commit 1c2e5fd66ea

2021-10-01 Thread H.J. Lu via Gcc-patches
Merge with upstream commit:

commit 1c2e5fd66ea27d0c51360ba4e22099124a915562
Author: peter klausler 
Date:   Wed Sep 15 08:28:48 2021 -0700

[flang] Enforce constraint: defined ass't in WHERE must be elemental

A defined assignment subroutine invoked in the context of a WHERE
statement or construct must necessarily be elemental (C1032).

Differential Revision: https://reviews.llvm.org/D109932

H.J. Lu (4):
  libsanitizer: Merge with upstream
  libsanitizer: Apply local patches
  libsanitizer: Bump asan/tsan versions
  Update c-c++-common/tsan/atomic_stack.c

 .../c-c++-common/tsan/atomic_stack.c  |3 +-
 libsanitizer/MERGE|2 +-
 libsanitizer/asan/asan_fuchsia.cpp|   35 +-
 libsanitizer/asan/asan_globals.cpp|   14 +-
 libsanitizer/asan/asan_interceptors.cpp   |   18 +-
 libsanitizer/asan/asan_interceptors.h |   45 +-
 libsanitizer/asan/asan_report.cpp |   10 +-
 libsanitizer/asan/asan_rtl.cpp|   18 +-
 libsanitizer/asan/asan_stats.cpp  |   10 +-
 libsanitizer/asan/asan_thread.cpp |4 +-
 libsanitizer/asan/libtool-version |2 +-
 libsanitizer/hwasan/Makefile.am   |3 +-
 libsanitizer/hwasan/Makefile.in   |   12 +-
 libsanitizer/hwasan/hwasan.cpp|3 +-
 libsanitizer/hwasan/hwasan.h  |   25 +-
 .../hwasan/hwasan_allocation_functions.cpp|   24 +
 libsanitizer/hwasan/hwasan_allocator.cpp  |   58 +-
 libsanitizer/hwasan/hwasan_dynamic_shadow.cpp |9 +
 libsanitizer/hwasan/hwasan_fuchsia.cpp|   23 +
 libsanitizer/hwasan/hwasan_interceptors.cpp   |   70 +-
 .../hwasan/hwasan_interface_internal.h|   48 -
 libsanitizer/hwasan/hwasan_linux.cpp  |  147 +-
 libsanitizer/hwasan/hwasan_report.cpp |   82 +-
 ...wasan_setjmp.S => hwasan_setjmp_aarch64.S} |   21 +-
 libsanitizer/hwasan/hwasan_setjmp_x86_64.S|   80 +
 libsanitizer/hwasan/hwasan_thread.cpp |2 +-
 libsanitizer/hwasan/hwasan_type_test.cpp  |2 +-
 .../include/sanitizer/asan_interface.h|2 +-
 .../include/sanitizer/common_interface_defs.h |2 +-
 .../include/sanitizer/dfsan_interface.h   |3 +-
 .../include/sanitizer/linux_syscall_hooks.h   | 2120 +
 .../include/sanitizer/tsan_interface.h|3 +
 .../interception/interception_win.cpp |   48 +-
 libsanitizer/lsan/lsan_allocator.h|2 +-
 libsanitizer/lsan/lsan_common.cpp |   12 +-
 .../sanitizer_common/sancov_flags.inc |2 +-
 .../sanitizer_common/sanitizer_addrhashmap.h  |2 +-
 .../sanitizer_allocator_primary64.h   |   14 +-
 .../sanitizer_allocator_size_class_map.h  |8 +-
 libsanitizer/sanitizer_common/sanitizer_asm.h |4 +-
 .../sanitizer_atomic_clang_mips.h |2 +-
 .../sanitizer_common/sanitizer_common.h   |   20 +-
 .../sanitizer_common_interceptors.inc |  652 ++---
 .../sanitizer_common_interceptors_format.inc  |   10 +-
 ...izer_common_interceptors_netbsd_compat.inc |4 +-
 .../sanitizer_common_nolibc.cpp   |1 +
 .../sanitizer_common_syscalls.inc | 1559 +++-
 .../sanitizer_coverage_fuchsia.cpp|8 +-
 .../sanitizer_coverage_libcdep_new.cpp|   65 +-
 .../sanitizer_common/sanitizer_file.cpp   |   15 +
 .../sanitizer_common/sanitizer_file.h |2 +
 .../sanitizer_common/sanitizer_flag_parser.h  |2 +-
 .../sanitizer_common/sanitizer_flags.inc  |4 +
 .../sanitizer_common/sanitizer_fuchsia.cpp|   41 -
 .../sanitizer_interceptors_ioctl_netbsd.inc   |2 +-
 .../sanitizer_interface_internal.h|7 +-
 .../sanitizer_internal_defs.h |   46 +-
 .../sanitizer_common/sanitizer_libc.cpp   |   12 +
 .../sanitizer_common/sanitizer_libc.h |5 +-
 .../sanitizer_common/sanitizer_libignore.cpp  |   33 +-
 .../sanitizer_common/sanitizer_libignore.h|   37 +-
 .../sanitizer_common/sanitizer_linux.cpp  |   83 +-
 .../sanitizer_local_address_space_view.h  |2 +-
 .../sanitizer_common/sanitizer_mac.cpp|   29 +-
 .../sanitizer_common/sanitizer_mutex.cpp  |  186 ++
 .../sanitizer_common/sanitizer_mutex.h|  325 +--
 .../sanitizer_common/sanitizer_platform.h |   25 +-
 .../sanitizer_platform_interceptors.h |   27 +-
 .../sanitizer_platform_limits_freebsd.cpp |4 +
 .../sanitizer_platform_limits_freebsd.h   |  164 +-
 .../sanitizer_platform_limits_linux.cpp   |   56 +-
 .../sanitizer_platform_limits_netbsd.cpp  |1 +
 .../sanitizer_platform_limits_netbsd.h|1 +
 .../sanitizer_platform_limits_posix.cpp   |   25 +-
 .../sanitizer_platform_limits_posix.h |   30 +-
 .../sanitizer_platform_limits_solaris.cpp |1 +
 .../sanitizer_platform_limits_solaris.h   |1 +
 

[PATCH 1/4] libsanitizer: Merge with upstream

2021-10-01 Thread H.J. Lu via Gcc-patches
Merged revision: 1c2e5fd66ea27d0c51360ba4e22099124a915562
---
 libsanitizer/MERGE|2 +-
 libsanitizer/asan/asan_fuchsia.cpp|   35 +-
 libsanitizer/asan/asan_globals.cpp|   33 +-
 libsanitizer/asan/asan_interceptors.cpp   |   18 +-
 libsanitizer/asan/asan_interceptors.h |   52 +-
 libsanitizer/asan/asan_mapping.h  |2 +-
 libsanitizer/asan/asan_report.cpp |   10 +-
 libsanitizer/asan/asan_rtl.cpp|   18 +-
 libsanitizer/asan/asan_stats.cpp  |   10 +-
 libsanitizer/asan/asan_thread.cpp |4 +-
 libsanitizer/hwasan/Makefile.am   |3 +-
 libsanitizer/hwasan/Makefile.in   |   12 +-
 libsanitizer/hwasan/hwasan.cpp|3 +-
 libsanitizer/hwasan/hwasan.h  |   25 +-
 .../hwasan/hwasan_allocation_functions.cpp|   24 +
 libsanitizer/hwasan/hwasan_allocator.cpp  |   58 +-
 libsanitizer/hwasan/hwasan_dynamic_shadow.cpp |9 +
 libsanitizer/hwasan/hwasan_fuchsia.cpp|   23 +
 libsanitizer/hwasan/hwasan_interceptors.cpp   |   70 +-
 .../hwasan/hwasan_interface_internal.h|   48 -
 libsanitizer/hwasan/hwasan_linux.cpp  |  147 +-
 libsanitizer/hwasan/hwasan_report.cpp |   82 +-
 ...wasan_setjmp.S => hwasan_setjmp_aarch64.S} |   21 +-
 libsanitizer/hwasan/hwasan_setjmp_x86_64.S|   80 +
 libsanitizer/hwasan/hwasan_thread.cpp |2 +-
 libsanitizer/hwasan/hwasan_type_test.cpp  |2 +-
 .../include/sanitizer/asan_interface.h|2 +-
 .../include/sanitizer/common_interface_defs.h |2 +-
 .../include/sanitizer/dfsan_interface.h   |3 +-
 .../include/sanitizer/linux_syscall_hooks.h   | 2120 +
 .../include/sanitizer/tsan_interface.h|3 +
 .../interception/interception_win.cpp |   48 +-
 libsanitizer/lsan/lsan_allocator.h|2 +-
 libsanitizer/lsan/lsan_common.cpp |   12 +-
 .../sanitizer_common/sancov_flags.inc |2 +-
 .../sanitizer_common/sanitizer_addrhashmap.h  |2 +-
 .../sanitizer_allocator_primary64.h   |   14 +-
 .../sanitizer_allocator_size_class_map.h  |8 +-
 libsanitizer/sanitizer_common/sanitizer_asm.h |4 +-
 .../sanitizer_atomic_clang_mips.h |2 +-
 .../sanitizer_common/sanitizer_common.h   |   20 +-
 .../sanitizer_common_interceptors.inc |  652 ++---
 .../sanitizer_common_interceptors_format.inc  |   10 +-
 ...izer_common_interceptors_netbsd_compat.inc |4 +-
 .../sanitizer_common_nolibc.cpp   |1 +
 .../sanitizer_common_syscalls.inc | 1559 +++-
 .../sanitizer_coverage_fuchsia.cpp|8 +-
 .../sanitizer_coverage_libcdep_new.cpp|   65 +-
 .../sanitizer_common/sanitizer_file.cpp   |   15 +
 .../sanitizer_common/sanitizer_file.h |2 +
 .../sanitizer_common/sanitizer_flag_parser.h  |2 +-
 .../sanitizer_common/sanitizer_flags.inc  |4 +
 .../sanitizer_common/sanitizer_fuchsia.cpp|   41 -
 .../sanitizer_interceptors_ioctl_netbsd.inc   |2 +-
 .../sanitizer_interface_internal.h|7 +-
 .../sanitizer_internal_defs.h |   46 +-
 .../sanitizer_common/sanitizer_libc.cpp   |   12 +
 .../sanitizer_common/sanitizer_libc.h |5 +-
 .../sanitizer_common/sanitizer_libignore.cpp  |   33 +-
 .../sanitizer_common/sanitizer_libignore.h|   37 +-
 .../sanitizer_common/sanitizer_linux.cpp  |   83 +-
 .../sanitizer_linux_libcdep.cpp   |4 -
 .../sanitizer_local_address_space_view.h  |2 +-
 .../sanitizer_common/sanitizer_mac.cpp|   41 +-
 libsanitizer/sanitizer_common/sanitizer_mac.h |   20 -
 .../sanitizer_common/sanitizer_mutex.cpp  |  186 ++
 .../sanitizer_common/sanitizer_mutex.h|  325 +--
 .../sanitizer_common/sanitizer_platform.h |   25 +-
 .../sanitizer_platform_interceptors.h |   27 +-
 .../sanitizer_platform_limits_freebsd.cpp |4 +
 .../sanitizer_platform_limits_freebsd.h   |  164 +-
 .../sanitizer_platform_limits_linux.cpp   |   61 +-
 .../sanitizer_platform_limits_netbsd.cpp  |1 +
 .../sanitizer_platform_limits_netbsd.h|1 +
 .../sanitizer_platform_limits_posix.cpp   |   25 +-
 .../sanitizer_platform_limits_posix.h |   32 +-
 .../sanitizer_platform_limits_solaris.cpp |1 +
 .../sanitizer_platform_limits_solaris.h   |1 +
 .../sanitizer_common/sanitizer_posix.h|7 +-
 .../sanitizer_posix_libcdep.cpp   |2 +
 .../sanitizer_common/sanitizer_printf.cpp |   37 +-
 .../sanitizer_signal_interceptors.inc |   12 +-
 .../sanitizer_common/sanitizer_solaris.cpp|   22 -
 .../sanitizer_common/sanitizer_stacktrace.cpp |   22 +-
 .../sanitizer_stacktrace_libcdep.cpp  |2 +-
 .../sanitizer_stacktrace_printer.cpp  |   11 +-
 

[PATCH 3/4] libsanitizer: Bump asan/tsan versions

2021-10-01 Thread H.J. Lu via Gcc-patches
Bump asan/tsan versions for upstream commits:

commit f1bb30a4956f83e46406d6082e5d376ce65391e0
Author: Vitaly Buka 
Date:   Thu Aug 26 10:25:09 2021 -0700

[sanitizer] No THREADLOCAL in qsort and bsearch

qsort can reuse qsort_r if available.
bsearch always passes key as the first comparator argument, so we
can use it to wrap the original comparator.

Differential Revision: https://reviews.llvm.org/D108751

commit d77b476c1953bcb0a608b2d6a4f2dd9fe0b43967
Author: Dmitry Vyukov 
Date:   Mon Aug 2 16:52:53 2021 +0200

tsan: avoid extra call indirection in unaligned access functions

Currently unaligned access functions are defined in tsan_interface.cpp
and do a real call to MemoryAccess. This means we have a real call
and no read/write constant propagation.

Unaligned memory access can be quite hot for some programs
(observed on some compression algorithms with ~90% of unaligned accesses).

Move them to tsan_interface_inl.h to avoid the additional call
and enable constant propagation.
Also reorder the actual store and memory access handling for
__sanitizer_unaligned_store callbacks to enable tail calling
in MemoryAccess.

Depends on D107282.

Reviewed By: vitalybuka, melver

commit 97795be22f634667ce7a022398c59ccc9f7440eb
Author: Dmitry Vyukov 
Date:   Fri Jul 30 08:35:11 2021 +0200

tsan: optimize test-only barrier

The updated lots_of_threads.c test with 300 threads
started running for too long on machines with low
hardware parallelism (e.g. taskset -c 0-1).
On lots of CPUs it finishes in ~2 secs. But with
taskset -c 0-1 it runs for hundreds of seconds
effectively spinning in the barrier in the sleep loop.

We now have the handy futex API in sanitizer_common.
Use it instead of the passive spin loop.
It makes the test run only faster with taskset -c 0-1,
it runs for ~1.5 secs, while with full parallelism
it still runs for ~2 secs (but consumes less CPU time).

Depends on D107131.

Reviewed By: vitalybuka
---
 libsanitizer/asan/libtool-version | 2 +-
 libsanitizer/tsan/libtool-version | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/libsanitizer/asan/libtool-version 
b/libsanitizer/asan/libtool-version
index 2cd4546d1b9..7a2a23f2b56 100644
--- a/libsanitizer/asan/libtool-version
+++ b/libsanitizer/asan/libtool-version
@@ -3,4 +3,4 @@
 # a separate file so that version updates don't involve re-running
 # automake.
 # CURRENT:REVISION:AGE
-7:0:0
+8:0:0
diff --git a/libsanitizer/tsan/libtool-version 
b/libsanitizer/tsan/libtool-version
index 79dfeeea15f..6fa8162dd20 100644
--- a/libsanitizer/tsan/libtool-version
+++ b/libsanitizer/tsan/libtool-version
@@ -3,4 +3,4 @@
 # a separate file so that version updates don't involve re-running
 # automake.
 # CURRENT:REVISION:AGE
-1:0:0
+2:0:0
-- 
2.31.1



[PATCH 4/4] Update c-c++-common/tsan/atomic_stack.c

2021-10-01 Thread H.J. Lu via Gcc-patches
Print out from __tsan_atomic32_fetch_add was removed by

commit da7a5c09c86c3f639c63ce8843d6f21c915ae1c6
Author: Dmitry Vyukov 
Date:   Wed Jul 28 16:57:39 2021 +0200

tsan: don't print __tsan_atomic* functions in report stacks

Currently __tsan_atomic* functions do FuncEntry/Exit using caller PC
and then use current PC (pointing to __tsan_atomic* itself) during
memory access handling. As the result the top function in reports
involving atomics is __tsan_atomic* and the next frame points to user code.

Remove FuncEntry/Exit in atomic functions and use caller PC
during memory access handling. This removes __tsan_atomic*
from the top of report stacks, so that they point right to user code.

The motivation for this is performance.
Some atomic operations are very hot (mostly loads),
so removing FuncEntry/Exit is beneficial.
This also reduces thread trace consumption (1 event instead of 3).

__tsan_atomic* at the top of the stack is not necessary
and does not add any new information. We already say
"atomic write of size 4", "__tsan_atomic32_store" does not add
anything new.

It also makes reports consistent between atomic and non-atomic
accesses. For normal accesses we say "previous write" and point
to user code; for atomics we say "previous atomic write" and now
also point to user code.

Reviewed By: vitalybuka

Differential Revision: https://reviews.llvm.org/D106966

* c-c++-common/tsan/atomic_stack.c: Don't expect print out from
__tsan_atomic32_fetch_add.
---
 gcc/testsuite/c-c++-common/tsan/atomic_stack.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/gcc/testsuite/c-c++-common/tsan/atomic_stack.c 
b/gcc/testsuite/c-c++-common/tsan/atomic_stack.c
index 746afa7b466..09ac7c72245 100644
--- a/gcc/testsuite/c-c++-common/tsan/atomic_stack.c
+++ b/gcc/testsuite/c-c++-common/tsan/atomic_stack.c
@@ -31,5 +31,4 @@ int main() {
 
 /* { dg-output "WARNING: ThreadSanitizer: data race.*(\n|\r\n|\r)" } */
 /* { dg-output "  Atomic write of size 4.*" } */
-/* { dg-output "#0 __tsan_atomic32_fetch_add.*" } */
-/* { dg-output "#1 Thread1.*" } */
+/* { dg-output "#0 Thread1.*" } */
-- 
2.31.1



Re: [RFC][Patch][middle-end/PR102359]Not add initialization for READONLY variables with -ftrivial-auto-var-init

2021-10-01 Thread Jason Merrill via Gcc-patches

On 10/1/21 10:54, Qing Zhao wrote:




On Sep 30, 2021, at 2:31 PM, Jason Merrill  wrote:

On 9/30/21 11:42, Qing Zhao wrote:

On Sep 30, 2021, at 1:54 AM, Richard Biener  wrote:

On Thu, 30 Sep 2021, Jason Merrill wrote:


On 9/29/21 17:30, Qing Zhao wrote:

Hi,

PR102359 (ICE gimplification failed since  r12-3433-ga25e0b5e6ac8a77a)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102359

Is due to -ftrivial-auto-var-init adding initialization for READONLY
variable “this” in the following routine: (t.cpp.005t.original)

===

;; Function A::foo():: (null)
;; enabled by -tree-original

{
  const struct A * const this [value-expr: &__closure->__this];
const struct A * const this [value-expr: &__closure->__this];
  return  = (double) ((const struct A *) this)->a;
}
===

However, in the above routine, “this” is NOT marked as READONLY, but its
value-expr "&__closure->__this” is marked as READONLY.

There are two major issues:

1. In the routine “is_var_need_auto_init”, we should exclude “decl” that is
marked as READONLY;
2. In the C++ FE, “this” should be marked as READONLY.

The idea solution will be:

1. Fix “is_var_need_auto_init” to exclude TREE_READONLY (decl);
2. Fix C++ FE to mark “this” as TREE_READONLY (decl)==true;

Not sure whether it’s hard for C++ FE to fix the 2nd issue or not?

In the case it’s not a quick fix in C++FE, I proposed the following fix in
middle end:

Let me know your comments or suggestions on this.

Thanks a lot for the help.


I'd think is_var_need_auto_init should be false for any variable with
DECL_HAS_VALUE_EXPR_P, as they aren't really variables, just ways of naming
objects that are initialized elsewhere.


IIRC handing variables with DECL_HAS_VALUE_EXPR_P is necessary to
auto-init VLAs, otherwise I tend to agree - would we handle those
when we see a DECL_EXPR then?

The current implementation is:
gimplify_decl_expr:
For each DECL_EXPR “decl”
If (VAR_P (decl) && !DECL_EXTERNAL (decl))
  {
if (is_vla (decl))
   gimplify_vla_decl (decl, …);  /* existing handling: create a 
VALUE_EXPR for this vla decl*/
…
if (has_explicit_init (decl))
  {
   …; /* existing handling.  */
  }
else if (is_var_need_auto_init (decl))  /*. New code. */
  {
gimple_add_init_for_auto_var (….);   /*  new code.  */
...
  }
  }
Since the “DECL_VALUE_EXPR (decl)” is NOT a DECL_EXPR, it will not be scanned 
and added initialization.
if we do not add initialization for a decl that has DECL_VALUE_EXPR, then the 
“DECL_VALUE_EXPR (decl)” will not be added an initialization either.  We will 
miss adding initializations for these decls.
So, I think that the current implementation is correct.
And if C++ FE will not mark “this” as READONLY, only mark DECL_VALUE_EXPR(this) 
as READONLY, the proposed fix is correct too.
Let me know your opinion on this.


The problem with this test is not whether the 'this' proxy is marked READONLY, the 
problem is that you're trying to initialize lambda capture proxies at all; the lambda 
capture objects were already initialized when forming the closure object.  So this test 
currently aborts with -ftrivial-auto-var-init=zero because you "initialize" the 
i capture field to 0 after it was previously initialized to 42:

int main()
{
  int i = 42;
  auto l = [=]() mutable { return i; };
  if (l() != i)
__builtin_abort ();
}

I believe the same issue applies to the proxy variables in coroutines that work 
much like lambdas.



So, how should the middle end determine that a variable is “proxy variable”?


In the front end, is_capture_proxy will identify a lambda capture proxy 
variable.  But that won't be true for the similar proxies used by 
coroutines.



Have all “proxy variables” been initialized by C++ FE already?


Yes.


You can't just assume that a VAR_DECL with DECL_VALUE_EXPR is uninitialized.


So, all the VAR_DECLs with DECL_VALUE_EXPR (except the ones created by 
“gimplify_decl_expr”) are initialized by FE already?


In general I'd expect them to refer to previously created objects which 
may or may not have been initialized, but if they haven't been, the 
place to deal with that is at their previous creation.



Since there's already VLA handling in gimplify_decl_expr, you could remember 
whether you added DECL_VALUE_EXPR in that function, and only then do the 
initialization.


Yes, if we can guarantee that all the VAR_DECLs with DECL_VALUE_EXPR created 
from FEs have been initialized already by FE, we can fix this issue as this way.


Or more generally, check whether the argument to gimplify_decl_expr has 
DECL_VALUE_EXPR when we enter the function, and don't do the 
initialization in that case.


Jason



PING^4 [PATCH] x86: Update memcpy/memset inline strategies for -mtune=generic

2021-10-01 Thread H.J. Lu via Gcc-patches
On Mon, Sep 20, 2021 at 10:06 AM H.J. Lu  wrote:
>
> On Mon, Sep 13, 2021 at 6:38 AM H.J. Lu  wrote:
> >
> > On Tue, Sep 7, 2021 at 8:01 PM H.J. Lu  wrote:
> > >
> > > On Sun, Aug 22, 2021 at 8:28 AM H.J. Lu  wrote:
> > > >
> > > > On Tue, Mar 23, 2021 at 09:19:38AM +0100, Richard Biener wrote:
> > > > > On Tue, Mar 23, 2021 at 3:41 AM Hongyu Wang  
> > > > > wrote:
> > > > > >
> > > > > > > Hongyue, please collect code size differences on SPEC CPU 2017 and
> > > > > > > eembc.
> > > > > >
> > > > > > Here is code size difference for this patch
> > > > >
> > > > > Thanks, nothing too bad although slightly larger impacts than 
> > > > > envisioned.
> > > > >
> > > >
> > > > PING.
> > > >
> > > > OK for master branch?
> > > >
> > > > Thanks.
> > > >
> > > > H.J.
> > > >  ---
> > > > Simplify memcpy and memset inline strategies to avoid branches for
> > > > -mtune=generic:
> > > >
> > > > 1. With MOVE_RATIO and CLEAR_RATIO == 17, GCC will use integer/vector
> > > >load and store for up to 16 * 16 (256) bytes when the data size is
> > > >fixed and known.
> > > > 2. Inline only if data size is known to be <= 256.
> > > >a. Use "rep movsb/stosb" with simple code sequence if the data size
> > > >   is a constant.
> > > >b. Use loop if data size is not a constant.
> > > > 3. Use memcpy/memset libray function if data size is unknown or > 256.
> > > >
> > >
> > > PING:
> > >
> > > https://gcc.gnu.org/pipermail/gcc-patches/2021-August/577889.html
> > >
> >
> > PING.  This should fix:
> >
> > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102294
> >
>
> PING.
>

Any comments or objections to this patch?


-- 
H.J.


Re: [PATCH] c++: Implement C++20 -Wdeprecated-array-compare [PR97573]

2021-10-01 Thread Martin Sebor via Gcc-patches

On 9/30/21 8:50 AM, Marek Polacek via Gcc-patches wrote:

This patch addresses one of my leftovers from GCC 11.  C++20 introduced
[depr.array.comp]:
"Equality and relational comparisons between two operands of array type are
deprecated."
so this patch adds -Wdeprecated-array-compare (enabled by default in C++20).


A warning like this would be useful in C as well even though there
array equality is not deprecated (though relational expressions
involving distinct objects are undefined).  Recently, while working
on my -Waddress enhancement to "warn for more impossible null
pointer tests​, I noticed Clang warns for some of these equality
tests in both languages (it issues -Wtautological-compare).

Rather that referring to deprecation, if one is necessary, I would
suggest to choose a name for the option that reflects the problem
the warning (and presumably the deprecation in C++) tries to prevent.
That said, since GCC already has both -Waddress and -Wtautological-
compare for these problems, the warning could be issued under either
of these.

Martin



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

PR c++/97573

gcc/c-family/ChangeLog:

* c-opts.c (c_common_post_options): In C++20, turn on
-Wdeprecated-array-compare.
* c.opt (Wdeprecated-array-compare): New option.

gcc/cp/ChangeLog:

* typeck.c (do_warn_deprecated_array_compare): New.
(cp_build_binary_op): Call it for equality and relational comparisons.

gcc/ChangeLog:

* doc/invoke.texi: Document -Wdeprecated-array-compare.

gcc/testsuite/ChangeLog:

* g++.dg/tree-ssa/pr15791-1.C: Add dg-warning.
* g++.dg/cpp2a/array-comp1.C: New test.
* g++.dg/cpp2a/array-comp2.C: New test.
* g++.dg/cpp2a/array-comp3.C: New test.
---
  gcc/c-family/c-opts.c |  5 
  gcc/c-family/c.opt|  4 +++
  gcc/cp/typeck.c   | 28 +++
  gcc/doc/invoke.texi   | 19 -
  gcc/testsuite/g++.dg/cpp2a/array-comp1.C  | 34 +++
  gcc/testsuite/g++.dg/cpp2a/array-comp2.C  | 31 +
  gcc/testsuite/g++.dg/cpp2a/array-comp3.C  | 29 +++
  gcc/testsuite/g++.dg/tree-ssa/pr15791-1.C |  2 +-
  8 files changed, 150 insertions(+), 2 deletions(-)
  create mode 100644 gcc/testsuite/g++.dg/cpp2a/array-comp1.C
  create mode 100644 gcc/testsuite/g++.dg/cpp2a/array-comp2.C
  create mode 100644 gcc/testsuite/g++.dg/cpp2a/array-comp3.C

diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c
index 3eaab5e1530..00b52cc5e12 100644
--- a/gcc/c-family/c-opts.c
+++ b/gcc/c-family/c-opts.c
@@ -962,6 +962,11 @@ c_common_post_options (const char **pfilename)
   warn_deprecated_enum_float_conv,
   cxx_dialect >= cxx20 && warn_deprecated);
  
+  /* -Wdeprecated-array-compare is enabled by default in C++20.  */

+  SET_OPTION_IF_UNSET (_options, _options_set,
+  warn_deprecated_array_compare,
+  cxx_dialect >= cxx20 && warn_deprecated);
+
/* Declone C++ 'structors if -Os.  */
if (flag_declone_ctor_dtor == -1)
  flag_declone_ctor_dtor = optimize_size;
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 9c151d19870..a4f0ea68594 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -540,6 +540,10 @@ Wdeprecated
  C C++ ObjC ObjC++ CPP(cpp_warn_deprecated) CppReason(CPP_W_DEPRECATED)
  ; Documented in common.opt
  
+Wdeprecated-array-compare

+C++ ObjC++ Var(warn_deprecated_array_compare) Warning
+Warn about deprecated comparisons between two operands of array type.
+
  Wdeprecated-copy
  C++ ObjC++ Var(warn_deprecated_copy) Warning LangEnabledBy(C++ ObjC++, Wextra)
  Mark implicitly-declared copy operations as deprecated if the class has a
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index a2398dbe660..1e3a41104d6 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -40,6 +40,7 @@ along with GCC; see the file COPYING3.  If not see
  #include "attribs.h"
  #include "asan.h"
  #include "gimplify.h"
+#include "tree-pretty-print.h"
  
  static tree cp_build_addr_expr_strict (tree, tsubst_flags_t);

  static tree cp_build_function_call (tree, tree, tsubst_flags_t);
@@ -4725,6 +4726,21 @@ do_warn_enum_conversions (location_t loc, enum tree_code 
code, tree type0,
  }
  }
  
+/* Warn about C++20 [depr.array.comp] array comparisons: "Equality

+   and relational comparisons between two operands of array type are
+   deprecated."  */
+
+static inline void
+do_warn_deprecated_array_compare (location_t location, tree_code code,
+ tree op0, tree op1)
+{
+  if (warning_at (location, OPT_Wdeprecated_array_compare,
+ "comparison between two arrays is deprecated"))
+inform (location, "use unary %<+%> which decays operands to pointers "
+   "or %<&%D[0] %s &%D[0]%> to compare the addresses",
+  

Re: [PATCH] c++: Suppress error when cv-qualified reference is introduced by typedef [PR101783]

2021-10-01 Thread Nick Huang via Gcc-patches
> gcc-verify still fails with this version:
>
> > ERR: line should start with a tab: "PR c++/101783"
> > ERR: line should start with a tab: "* tree.c 
> > (cp_build_qualified_type_real): Excluding typedef from error"
> > ERR: line should start with a tab: "PR c++/101783"
> > ERR: line should start with a tab: "* g++.dg/parse/pr101783.C: New 
> > test."

> It might work better to attach the output of git format-patch.
Sorry for my clumsy copy/paste from git commit message. I now attach
git format-patch output
file as attachment. Also maybe for a little convenience of your work,
I also attach the original
commit message file when I do git commit -F.

> Also, your commit subject line is too long, at 83 characters: It must be
> under 75 characters, and preferably closer to 50.  I might shorten it to

Please go ahead. I will pay attention to this next time. Thank you!

> A change description in the ChangeLog should use present tense
> ("Exclude"), have a period at the end, and line wrap at 75 characters
> like the rest of the commit message.  So,
>
> * tree.c (cp_build_qualified_type_real): Exclude typedef from
> error.
>

Modified as suggested.

> > + ([dcl.type.decltype]),in which case the cv-qualifiers are ignored.
> > +  */
>
> We usually don't put */ on its own line.

Adjusted.

Once again I thank you for your patience and really appreciate it.

On Fri, Oct 1, 2021 at 9:29 AM Jason Merrill via Gcc-patches
 wrote:
>
> On 9/30/21 14:24, nick huang wrote:
> >>> You may need to run contrib/gcc-git-customization.sh to get the git
> >>> gcc-verify command.
> > I re-setup and can use git gcc-verify. Now I can see it rejects because I 
> > forgot to add a
> > description of modified file. Now that it passes gcc-verify and I attach 
> > the changelog
> > as attachment.
> >
> > Thank you again for your patient explanation and help!
>
> You're welcome, thanks for your patience as well!  Unfortunately, git
> gcc-verify still fails with this version:
>
> > ERR: line should start with a tab: "PR c++/101783"
> > ERR: line should start with a tab: "* tree.c 
> > (cp_build_qualified_type_real): Excluding typedef from error"
> > ERR: line should start with a tab: "PR c++/101783"
> > ERR: line should start with a tab: "* g++.dg/parse/pr101783.C: New 
> > test."
>
> It might work better to attach the output of git format-patch.
>
> Also, your commit subject line is too long, at 83 characters: It must be
> under 75 characters, and preferably closer to 50.  I might shorten it to
>
> c++: cv-qualified ref introduced by typedef [PR101783]
>
> > * tree.c (cp_build_qualified_type_real): Excluding typedef from error
>
> A change description in the ChangeLog should use present tense
> ("Exclude"), have a period at the end, and line wrap at 75 characters
> like the rest of the commit message.  So,
>
> * tree.c (cp_build_qualified_type_real): Exclude typedef from
> error.
>
> > + ([dcl.type.decltype]),in which case the cv-qualifiers are ignored.
> > +  */
>
> We usually don't put */ on its own line.
>
> Jason
>


-- 
nick huang/qingzhe huang
http://www.staroceans.com
http://www.staroceans.com/english.htm
The root cause of this bug is that it considers reference with
cv-qualifiers as an error by generating value for variable "bad_quals".
However, this is not correct for case of typedef. Here I quote spec
[dcl.ref]/1 :
"Cv-qualified references are ill-formed except when the cv-qualifiers
are introduced through the use of a typedef-name ([dcl.typedef],
[temp.param]) or decltype-specifier ([dcl.type.decltype]),
in which case the cv-qualifiers are ignored."

2021-09-30  qingzhe huang  

gcc/cp/ChangeLog:
PR c++/101783
* tree.c (cp_build_qualified_type_real): Exclude typedef from 
error.

gcc/testsuite/ChangeLog:
PR c++/101783
* g++.dg/parse/pr101783.C: New test.

From e592a475030d99647de736d294cb3c6a7588af49 Mon Sep 17 00:00:00 2001
From: qingzhe huang 
Date: Fri, 1 Oct 2021 10:46:35 -0400
Subject: [PATCH] The root cause of this bug is that it considers reference
 with cv-qualifiers as an error by generating value for variable "bad_quals".
 However, this is not correct for case of typedef. Here I quote spec
 [dcl.ref]/1 : "Cv-qualified references are ill-formed except when the
 cv-qualifiers are introduced through the use of a typedef-name
 ([dcl.typedef], [temp.param]) or decltype-specifier ([dcl.type.decltype]), in
 which case the cv-qualifiers are ignored."

2021-09-30  qingzhe huang  

gcc/cp/ChangeLog:
	PR c++/101783
	* tree.c (cp_build_qualified_type_real): Exclude typedef from
	error.

gcc/testsuite/ChangeLog:
	PR c++/101783
	* g++.dg/parse/pr101783.C: New test.
---
 gcc/cp/tree.c | 9 -
 gcc/testsuite/g++.dg/parse/pr101783.C | 5 +
 2 files changed, 13 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/parse/pr101783.C

diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c

[PATCH, v4] c++: Fix up synthetization of defaulted comparison operators on classes with bitfields [PR102490]

2021-10-01 Thread Jakub Jelinek via Gcc-patches
On Thu, Sep 30, 2021 at 03:01:49PM -0400, Jason Merrill wrote:
> > After fixing the incomplete std::strong_ordering spaceship-synth8.C is now
> > accepted, but I'm afraid I'm getting lost in this - clang++ rejects that
> > testcase instead complaining that D has <=> operator, but has it pure 
> > virtual.
> 
> Ah, I think we need to add LOOKUP_NO_VIRTUAL to the flags variable, as we do
> in do_build_copy_assign.  I suppose it wouldn't hurt to add LOOKUP_DEFAULTED
> as well.

I've tried that (see patch below), but neither in build_comparison_op, nor
in genericize_spaceship those changes made any difference for
spaceship-synth8.C, it is still accepted instead of rejected.

> > +  if (special_function_p (fn) == sfk_comparison)
> > +   {
> > + tree lhs = DECL_ARGUMENTS (fn);
> > + if (is_this_parameter (lhs))
> > +   lhs = cp_build_fold_indirect_ref (lhs);
> > + else
> > +   lhs = convert_from_reference (lhs);
> > + tree ctype = TYPE_MAIN_VARIANT (TREE_TYPE (lhs));
> > + /* If the comparison type is still incomplete, don't synthesize the
> > +method, just see if it is not implicitly deleted.  */
> > + if (!COMPLETE_TYPE_P (ctype))
> > +   {
> > + push_deferring_access_checks (dk_no_deferred);
> > + build_comparison_op (fn, false, tf_none);
> > + pop_deferring_access_checks ();
> > + return !DECL_MAYBE_DELETED (fn);
> > +   }
> > +   }
> > +
> > ++function_depth;
> > synthesize_method (fn);
> > --function_depth;
> 
> Let's factor this (from the added code to here) into a
> maybe_synthesize_method in method.c.  That way build_comparison_op can stay
> static.

Ok, done.
In addition, I've added the testcases from PR98712 to the patch.
I'm still worried about maybe_synthesize_method, if done e.g. from
maybe_instantiate_noexcept before the class is COMPLETE_TYPE_P, could
end up deducing a wrong return type, one that e.g. doesn't take into account
base classes.  Tried that with spaceship-synth13.C testcase, but there
maybe_instantiate_noexcept isn't called early, and I'm out of ideas how to do
that.  Also, do maybe_instantiate_noexcept callers care just about the
return type of the method or also about whether something in the body could
throw?

2021-10-01  Jakub Jelinek  

PR c++/98712
PR c++/102490
* cp-tree.h (maybe_synthesize_method): Declare.
* method.c (genericize_spaceship): Use
LOOKUP_NORMAL | LOOKUP_NONVIRTUAL | LOOKUP_DEFAULTED instead of
LOOKUP_NORMAL for flags.
(comp_info): Remove defining member.
(comp_info::comp_info): Remove complain argument, don't initialize
defining.
(build_comparison_op): Add defining argument. Adjust comp_info
construction.  Use defining instead of info.defining.  Assert that if
defining, ctype is a complete type.  Use
LOOKUP_NORMAL | LOOKUP_NONVIRTUAL | LOOKUP_DEFAULTED instead of
LOOKUP_NORMAL for flags.
(synthesize_method, maybe_explain_implicit_delete,
explain_implicit_non_constexpr): Adjust build_comparison_op callers.
(maybe_synthesize_method): New function.
* class.c (check_bases_and_members): Don't call defaulted_late_check
for sfk_comparison.
(finish_struct_1): Call it here instead after class has been completed.
* pt.c (maybe_instantiate_noexcept): Call maybe_synthesize_method
instead of synthesize_method.

* g++.dg/cpp2a/spaceship-synth8.C (std::strong_ordering): Provide more
complete definition.
(std::strong_ordering::less, std::strong_ordering::equal,
std::strong_ordering::greater): Define.
* g++.dg/cpp2a/spaceship-synth12.C: New test.
* g++.dg/cpp2a/spaceship-synth13.C: New test.
* g++.dg/cpp2a/spaceship-eq11.C: New test.
* g++.dg/cpp2a/spaceship-eq12.C: New test.
* g++.dg/cpp2a/spaceship-eq13.C: New test.

--- gcc/cp/cp-tree.h.jj 2021-10-01 10:24:37.500266902 +0200
+++ gcc/cp/cp-tree.h2021-10-01 16:40:08.880795343 +0200
@@ -7013,6 +7013,7 @@ extern void explain_implicit_non_constex
 extern bool deduce_inheriting_ctor (tree);
 extern bool decl_remember_implicit_trigger_p   (tree);
 extern void synthesize_method  (tree);
+extern void maybe_synthesize_method(tree);
 extern tree lazily_declare_fn  (special_function_kind,
 tree);
 extern tree skip_artificial_parms_for  (const_tree, tree);
--- gcc/cp/method.c.jj  2021-10-01 10:24:58.312971997 +0200
+++ gcc/cp/method.c 2021-10-01 16:46:18.018588835 +0200
@@ -1098,7 +1098,7 @@ genericize_spaceship (location_t loc, tr
 
   tree gt = lookup_comparison_result (tag, type, 1);
 
-  int flags = LOOKUP_NORMAL;
+  int flags = LOOKUP_NORMAL | LOOKUP_NONVIRTUAL | LOOKUP_DEFAULTED;
   tsubst_flags_t complain = tf_none;
   tree comp;
 
@@ -1288,21 +1288,16 @@ struct 

Re: [RFC][Patch][middle-end/PR102359]Not add initialization for READONLY variables with -ftrivial-auto-var-init

2021-10-01 Thread Qing Zhao via Gcc-patches


> On Sep 30, 2021, at 2:31 PM, Jason Merrill  wrote:
> 
> On 9/30/21 11:42, Qing Zhao wrote:
>>> On Sep 30, 2021, at 1:54 AM, Richard Biener  wrote:
>>> 
>>> On Thu, 30 Sep 2021, Jason Merrill wrote:
>>> 
 On 9/29/21 17:30, Qing Zhao wrote:
> Hi,
> 
> PR102359 (ICE gimplification failed since  r12-3433-ga25e0b5e6ac8a77a)
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102359
> 
> Is due to -ftrivial-auto-var-init adding initialization for READONLY
> variable “this” in the following routine: (t.cpp.005t.original)
> 
> ===
> 
> ;; Function A::foo():: (null)
> ;; enabled by -tree-original
> 
> {
>  const struct A * const this [value-expr: &__closure->__this];
>const struct A * const this [value-expr: &__closure->__this];
>  return  = (double) ((const struct A *) this)->a;
> }
> ===
> 
> However, in the above routine, “this” is NOT marked as READONLY, but its
> value-expr "&__closure->__this” is marked as READONLY.
> 
> There are two major issues:
> 
> 1. In the routine “is_var_need_auto_init”, we should exclude “decl” that 
> is
> marked as READONLY;
> 2. In the C++ FE, “this” should be marked as READONLY.
> 
> The idea solution will be:
> 
> 1. Fix “is_var_need_auto_init” to exclude TREE_READONLY (decl);
> 2. Fix C++ FE to mark “this” as TREE_READONLY (decl)==true;
> 
> Not sure whether it’s hard for C++ FE to fix the 2nd issue or not?
> 
> In the case it’s not a quick fix in C++FE, I proposed the following fix in
> middle end:
> 
> Let me know your comments or suggestions on this.
> 
> Thanks a lot for the help.
 
 I'd think is_var_need_auto_init should be false for any variable with
 DECL_HAS_VALUE_EXPR_P, as they aren't really variables, just ways of naming
 objects that are initialized elsewhere.
>>> 
>>> IIRC handing variables with DECL_HAS_VALUE_EXPR_P is necessary to
>>> auto-init VLAs, otherwise I tend to agree - would we handle those
>>> when we see a DECL_EXPR then?
>> The current implementation is:
>> gimplify_decl_expr:
>> For each DECL_EXPR “decl”
>>If (VAR_P (decl) && !DECL_EXTERNAL (decl))
>>  {
>>  if (is_vla (decl))
>>   gimplify_vla_decl (decl, …);  /* existing handling: create a 
>> VALUE_EXPR for this vla decl*/
>>  …
>>  if (has_explicit_init (decl))
>>{
>> …; /* existing handling.  */
>>}
>>  else if (is_var_need_auto_init (decl))  /*. New code. */
>>{
>>  gimple_add_init_for_auto_var (….);   /*  new code.  */
>>  ...
>>}
>>  }
>> Since the “DECL_VALUE_EXPR (decl)” is NOT a DECL_EXPR, it will not be 
>> scanned and added initialization.
>> if we do not add initialization for a decl that has DECL_VALUE_EXPR, then 
>> the “DECL_VALUE_EXPR (decl)” will not be added an initialization either.  We 
>> will miss adding initializations for these decls.
>> So, I think that the current implementation is correct.
>> And if C++ FE will not mark “this” as READONLY, only mark 
>> DECL_VALUE_EXPR(this) as READONLY, the proposed fix is correct too.
>> Let me know your opinion on this.
> 
> The problem with this test is not whether the 'this' proxy is marked 
> READONLY, the problem is that you're trying to initialize lambda capture 
> proxies at all; the lambda capture objects were already initialized when 
> forming the closure object.  So this test currently aborts with 
> -ftrivial-auto-var-init=zero because you "initialize" the i capture field to 
> 0 after it was previously initialized to 42:
> 
> int main()
> {
>  int i = 42;
>  auto l = [=]() mutable { return i; };
>  if (l() != i)
>__builtin_abort ();
> }
> 
> I believe the same issue applies to the proxy variables in coroutines that 
> work much like lambdas.
So, how should the middle end determine that a variable is “proxy variable”?
Have all “proxy variables” been initialized by C++ FE already?
> 
> You can't just assume that a VAR_DECL with DECL_VALUE_EXPR is uninitialized.

So, all the VAR_DECLs with DECL_VALUE_EXPR (except the ones created by 
“gimplify_decl_expr”) are initialized by FE already?

> 
> Since there's already VLA handling in gimplify_decl_expr, you could remember 
> whether you added DECL_VALUE_EXPR in that function, and only then do the 
> initialization.

Yes, if we can guarantee that all the VAR_DECLs with DECL_VALUE_EXPR created 
from FEs have been initialized already by FE, we can fix this issue as this way.

thanks.

Qing
> 
> Jason
> 



Re: [PATCH] Handle EQ_EXPR relation for operator_lshift.

2021-10-01 Thread Aldy Hernandez via Gcc-patches
Well, after talking with Andrew it seems that X << Y being non-zero
also implies X is non-zero.  So we don't even need relationals here.

So, I leave gori relationals in his capable hands, while I test this
much simpler patch which fixes the PR with no additional
infrastructure ;-).

Will push pending tests.
Aldy

On Fri, Oct 1, 2021 at 2:43 PM Aldy Hernandez  wrote:
>
> Knowing that X << X is non-zero means X is also non-zero.  This patch
> teaches this this to range-ops.
>
> As usual, the big twiddling experts could come up with all sorts of
> fancy enhancements in this area, and we welcome all patches :).
>
> I will push this pending tests.
>
> gcc/ChangeLog:
>
> PR tree-optimization/102546
> * range-op.cc (operator_lshift::op1_range): Handle EQ_EXPR
> relation.
> ---
>  gcc/range-op.cc  | 19 ---
>  gcc/testsuite/gcc.dg/tree-ssa/pr102546.c | 23 +++
>  2 files changed, 39 insertions(+), 3 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr102546.c
>
> diff --git a/gcc/range-op.cc b/gcc/range-op.cc
> index 5e37133026d..53f3be4266e 100644
> --- a/gcc/range-op.cc
> +++ b/gcc/range-op.cc
> @@ -2075,9 +2075,14 @@ operator_lshift::op1_range (irange ,
> tree type,
> const irange ,
> const irange ,
> -   relation_kind rel ATTRIBUTE_UNUSED) const
> +   relation_kind rel) const
>  {
>tree shift_amount;
> +  int_range<2> adjust (type);
> +
> +  if (rel == EQ_EXPR && !lhs.contains_p (build_zero_cst (type)))
> +adjust.set_nonzero (type);
> +
>if (op2.singleton_p (_amount))
>  {
>wide_int shift = wi::to_wide (shift_amount);
> @@ -2086,10 +2091,11 @@ operator_lshift::op1_range (irange ,
>if (wi::ge_p (shift, wi::uhwi (TYPE_PRECISION (type),
>  TYPE_PRECISION (op2.type ())),
> UNSIGNED))
> -   return false;
> +   goto done;
>if (shift == 0)
> {
>   r = lhs;
> + r.intersect (adjust);
>   return true;
> }
>
> @@ -2126,9 +2132,16 @@ operator_lshift::op1_range (irange ,
>
>if (utype != type)
> range_cast (r, type);
> +  r.intersect (adjust);
>return true;
>  }
> -  return false;
> +
> + done:
> +  if (adjust.varying_p ())
> +return false;
> +
> +  r = adjust;
> +  return true;
>  }
>
>  bool
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr102546.c 
> b/gcc/testsuite/gcc.dg/tree-ssa/pr102546.c
> new file mode 100644
> index 000..4bd98747732
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr102546.c
> @@ -0,0 +1,23 @@
> +// { dg-do compile }
> +// { dg-options "-O3 -fdump-tree-optimized" }
> +
> +static int a;
> +static char b, c, d;
> +void bar(void);
> +void foo(void);
> +
> +int main() {
> +int f = 0;
> +for (; f <= 5; f++) {
> +bar();
> +b = b && f;
> +d = f << f;
> +if (!(a >= d || f))
> +foo();
> +c = 1;
> +for (; c; c = 0)
> +;
> +}
> +}
> +
> +// { dg-final { scan-tree-dump-not "foo" "optimized" } }
> --
> 2.31.1
>
From fa11285b9ff1d75c877369c1df7760c3f76a4fe5 Mon Sep 17 00:00:00 2001
From: Aldy Hernandez 
Date: Fri, 1 Oct 2021 13:05:36 +0200
Subject: [PATCH] [PR102546] X << Y being non-zero implies X is also non-zero.

This patch teaches this to range-ops.

Tested on x86-64 Linux.

gcc/ChangeLog:

	PR tree-optimization/102546
	* range-op.cc (operator_lshift::op1_range): Teach range-ops that
	X << Y is non-zero implies X is also non-zero.
---
 gcc/range-op.cc  | 18 ++
 gcc/testsuite/gcc.dg/tree-ssa/pr102546.c | 23 +++
 2 files changed, 37 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr102546.c

diff --git a/gcc/range-op.cc b/gcc/range-op.cc
index 5e37133026d..2baca4a197f 100644
--- a/gcc/range-op.cc
+++ b/gcc/range-op.cc
@@ -2078,6 +2078,12 @@ operator_lshift::op1_range (irange ,
 			relation_kind rel ATTRIBUTE_UNUSED) const
 {
   tree shift_amount;
+
+  if (!lhs.contains_p (build_zero_cst (type)))
+r.set_nonzero (type);
+  else
+r.set_varying (type);
+
   if (op2.singleton_p (_amount))
 {
   wide_int shift = wi::to_wide (shift_amount);
@@ -2089,21 +2095,24 @@ operator_lshift::op1_range (irange ,
 	return false;
   if (shift == 0)
 	{
-	  r = lhs;
+	  r.intersect (lhs);
 	  return true;
 	}
 
   // Work completely in unsigned mode to start.
   tree utype = type;
+  int_range_max tmp_range;
   if (TYPE_SIGN (type) == SIGNED)
 	{
 	  int_range_max tmp = lhs;
 	  utype = unsigned_type_for (type);
 	  range_cast (tmp, utype);
-	  op_rshift.fold_range (r, utype, tmp, op2);
+	  op_rshift.fold_range (tmp_range, utype, tmp, op2);
 	}
   else
-	op_rshift.fold_range (r, utype, lhs, op2);
+	

Re: [PATCH] libiberty: prevent null dereferencing on dlang_type

2021-10-01 Thread Luís Ferreira via Gcc-patches
Hi,

Yes, I'm sorry, I forgot to add --format=dlang parameter. This patch
fixes it
https://gcc.gnu.org/pipermail/gcc-patches/2021-September/580544.html .

On Fri, 2021-10-01 at 07:23 -0700, H.J. Lu wrote:
> On Thu, Sep 23, 2021 at 8:55 AM Jeff Law via Gcc-patches
>  wrote:
> > 
> > 
> > 
> > On 9/23/2021 4:17 AM, ibuclaw--- via Gcc-patches wrote:
> > > > On 22/09/2021 03:31 Luís Ferreira  wrote:
> > > > 
> > > > 
> > > > This patch prevents dereferencing a null reference on a crafted
> > > > malformed magled name, often causing SIGSEGV to be raised.
> > > > 
> > > OK, seems reasonable to me.
> > I pushed this to the trunk.
> > 
> > Thanks,
> > jeff
> > 
> 
> This caused:
> 
> FAIL at line 997: unknown demangling style _D00
> FAIL at line 1001: unknown demangling style _D01_D
> FAIL at line 1005: unknown demangling style _D9223372036854775817
> FAIL at line 1009: unknown demangling style _D1az
> FAIL at line 1013: unknown demangling style _D1aN
> FAIL at line 1017: unknown demangling style _D1aF
> FAIL at line 1021: unknown demangling style _D1aM
> FAIL at line 1025: unknown demangling style _D1aFZNz
> FAIL at line 1029: unknown demangling style _D1aFNzZv
> FAIL at line 1033: unknown demangling style _D4testFDX
> FAIL at line 1037: unknown demangling style _D5__T0aZv
> FAIL at line 1041: unknown demangling style _D10__T4testYZv
> FAIL at line 1045: unknown demangling style _D4testFBaZv
> FAIL at line 1049: unknown demangling style _D8__T4test
> FAIL at line 1053: unknown demangling style _D10__T4testVi
> FAIL at line 1057: unknown demangling style _D10__T4testVai
> ...
> FAIL at line 1445: unknown demangling style
> _D3mod4funcFZ__T6nestedTiZQkMFNaNbNiNfZi
> FAIL at line 1449: unknown demangling style
> _D3mod4funcFZ__T6nestedTiZ4__S1QpMFNaNbNiNfZi
> FAIL at line 1452: unknown demangling style
> _D6mangle__T8fun21753VSQv6S21753S1f_DQBj10__lambda71MFNaNbNiNfZvZQCbQp
> ./test-demangle: 359 tests, 115 failures
> make[5]: *** [Makefile:55: check-d-demangle] Error 1
> 
> 

-- 
Sincerely,
Luís Ferreira @ lsferreira.net



signature.asc
Description: This is a digitally signed message part


Re: [PATCH] c++: unifying equal NONTYPE_ARGUMENT_PACKs [PR102547]

2021-10-01 Thread Patrick Palka via Gcc-patches
On Fri, 1 Oct 2021, Jason Merrill wrote:

> On 10/1/21 09:46, Patrick Palka wrote:
> > Here during partial ordering of the two partial specializations we end
> > up in unify with parm=arg=NONTYPE_ARGUMENT_PACK, and crash shortly
> > thereafter because uses_template_parms calls potential_constant_expression
> > which doesn't handle NONTYPE_ARGUMENT_PACK.
> > 
> > This patch fixes this by checking dependent_template_arg_p instead of
> > uses_template_parms when parm==arg, which does handle NONTYPE_ARGUMENT_PACK.
> > We could also perhaps fix uses_template_parms / inst_dep_expr_p to better
> > handle NONTYPE_ARGUMENT_PACK,
> 
> Please.

Sounds good, like the following then?  Passes light testing, bootstrap
and regtest on progress.

-- >8 --

PR c++/102547

gcc/cp/ChangeLog:

* pt.c (instantiation_dependent_expression_p): Sidestep checking
potential_constant_expression on NONTYPE_ARGUMENT_PACK.

gcc/testsuite/ChangeLog:

* g++.dg/cpp0x/variadic-partial2.C: New test.
* g++.dg/cpp0x/variadic-partial2a.C: New test.
---
 gcc/cp/pt.c   |  4 +++-
 .../g++.dg/cpp0x/variadic-partial2.C  | 16 ++
 .../g++.dg/cpp0x/variadic-partial2a.C | 22 +++
 3 files changed, 41 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/variadic-partial2.C
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/variadic-partial2a.C

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 1dcdffe322a..643204103c5 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -27705,7 +27705,9 @@ instantiation_dependent_expression_p (tree expression)
 {
   return (instantiation_dependent_uneval_expression_p (expression)
  || (processing_template_decl
- && potential_constant_expression (expression)
+ && expression != NULL_TREE
+ && (TREE_CODE (expression) == NONTYPE_ARGUMENT_PACK
+ || potential_constant_expression (expression))
  && value_dependent_expression_p (expression)));
 }
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-partial2.C 
b/gcc/testsuite/g++.dg/cpp0x/variadic-partial2.C
new file mode 100644
index 000..df61f26a3c1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic-partial2.C
@@ -0,0 +1,16 @@
+// PR c++/102547
+// { dg-do compile { target c++11 } }
+
+template
+struct vals { };
+
+template
+struct vals_client { };
+
+template
+struct vals_client, T> { };
+
+template
+struct vals_client, void> { };
+
+template struct vals_client, void>; //- "sorry, unimplemented..., 
ICE"
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-partial2a.C 
b/gcc/testsuite/g++.dg/cpp0x/variadic-partial2a.C
new file mode 100644
index 000..cc0ea488ad3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic-partial2a.C
@@ -0,0 +1,22 @@
+// PR c++/102547
+// { dg-do compile { target c++11 } }
+// A version of variadic-partial2.C where the partial ordering is performed
+// on function templates instead of class templates.
+
+template
+struct vals { };
+
+template
+void f(V, T) { };
+
+template
+void f(vals, T) { };
+
+template
+void f(vals, char) { };
+
+template void f(vals<1, 2>, char); //- "sorry, unimplemented..., ICE"
+
+int main() {
+  f(vals<1, 3>{}, 'a'); //- "sorry, unimplemented..., ICE"
+}
-- 
2.33.0.610.gcefe983a32



Re: [PATCH] libiberty: prevent null dereferencing on dlang_type

2021-10-01 Thread H.J. Lu via Gcc-patches
On Thu, Sep 23, 2021 at 8:55 AM Jeff Law via Gcc-patches
 wrote:
>
>
>
> On 9/23/2021 4:17 AM, ibuclaw--- via Gcc-patches wrote:
> >> On 22/09/2021 03:31 Luís Ferreira  wrote:
> >>
> >>
> >> This patch prevents dereferencing a null reference on a crafted
> >> malformed magled name, often causing SIGSEGV to be raised.
> >>
> > OK, seems reasonable to me.
> I pushed this to the trunk.
>
> Thanks,
> jeff
>

This caused:

FAIL at line 997: unknown demangling style _D00
FAIL at line 1001: unknown demangling style _D01_D
FAIL at line 1005: unknown demangling style _D9223372036854775817
FAIL at line 1009: unknown demangling style _D1az
FAIL at line 1013: unknown demangling style _D1aN
FAIL at line 1017: unknown demangling style _D1aF
FAIL at line 1021: unknown demangling style _D1aM
FAIL at line 1025: unknown demangling style _D1aFZNz
FAIL at line 1029: unknown demangling style _D1aFNzZv
FAIL at line 1033: unknown demangling style _D4testFDX
FAIL at line 1037: unknown demangling style _D5__T0aZv
FAIL at line 1041: unknown demangling style _D10__T4testYZv
FAIL at line 1045: unknown demangling style _D4testFBaZv
FAIL at line 1049: unknown demangling style _D8__T4test
FAIL at line 1053: unknown demangling style _D10__T4testVi
FAIL at line 1057: unknown demangling style _D10__T4testVai
...
FAIL at line 1445: unknown demangling style
_D3mod4funcFZ__T6nestedTiZQkMFNaNbNiNfZi
FAIL at line 1449: unknown demangling style
_D3mod4funcFZ__T6nestedTiZ4__S1QpMFNaNbNiNfZi
FAIL at line 1452: unknown demangling style
_D6mangle__T8fun21753VSQv6S21753S1f_DQBj10__lambda71MFNaNbNiNfZvZQCbQp
./test-demangle: 359 tests, 115 failures
make[5]: *** [Makefile:55: check-d-demangle] Error 1


-- 
H.J.


[committed] libstdc++: Define basic_regex::multiline for non-strict modes

2021-10-01 Thread Jonathan Wakely via Gcc-patches
The regex_constants::multiline constant is defined for non-strict C++11
and C++14 modes, on the basis that the feature is a DR (even though it
was really a new feature addition to C++17 and probably shouldn't have
gone through the issues list).

This makes the basic_regex::multiline constant defined consistently with
the regex_constants::multiline one.

For strict C++11 and C++14 mode we don't define them, because multiline
is not a reserved name in those standards.

libstdc++-v3/ChangeLog:

* include/bits/regex.h (basic_regex::multiline): Define for
non-strict C++11 and C++14 modes.
* include/bits/regex_constants.h (regex_constants::multiline):
Add _GLIBCXX_RESOLVE_LIB_DEFECTS comment.

Tested x86_64-linux. Committed to trunk.

commit 17374dab3eefd282977ad90743c9aff97f2e41ce
Author: Jonathan Wakely 
Date:   Fri Oct 1 14:06:42 2021

libstdc++: Define basic_regex::multiline for non-strict modes

The regex_constants::multiline constant is defined for non-strict C++11
and C++14 modes, on the basis that the feature is a DR (even though it
was really a new feature addition to C++17 and probably shouldn't have
gone through the issues list).

This makes the basic_regex::multiline constant defined consistently with
the regex_constants::multiline one.

For strict C++11 and C++14 mode we don't define them, because multiline
is not a reserved name in those standards.

libstdc++-v3/ChangeLog:

* include/bits/regex.h (basic_regex::multiline): Define for
non-strict C++11 and C++14 modes.
* include/bits/regex_constants.h (regex_constants::multiline):
Add _GLIBCXX_RESOLVE_LIB_DEFECTS comment.

diff --git a/libstdc++-v3/include/bits/regex.h 
b/libstdc++-v3/include/bits/regex.h
index 664944b0ef2..ff908da3e94 100644
--- a/libstdc++-v3/include/bits/regex.h
+++ b/libstdc++-v3/include/bits/regex.h
@@ -424,7 +424,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
   static constexpr flag_type awk = regex_constants::awk;
   static constexpr flag_type grep = regex_constants::grep;
   static constexpr flag_type egrep = regex_constants::egrep;
-#if __cplusplus >= 201703L
+#if __cplusplus >= 201703L || !defined __STRICT_ANSI__
   static constexpr flag_type multiline = regex_constants::multiline;
 #endif
   ///@}
diff --git a/libstdc++-v3/include/bits/regex_constants.h 
b/libstdc++-v3/include/bits/regex_constants.h
index af689ff93af..0fd2879c817 100644
--- a/libstdc++-v3/include/bits/regex_constants.h
+++ b/libstdc++-v3/include/bits/regex_constants.h
@@ -171,6 +171,8 @@ namespace regex_constants
 static_cast(1 << _S_egrep);
 
 #if __cplusplus >= 201703L || !defined __STRICT_ANSI__
+  // _GLIBCXX_RESOLVE_LIB_DEFECTS
+  // 2503. multiline option should be added to syntax_option_type
   /**
* Specifies that the `^` anchor matches at the beginning of a line,
* and the `$` anchor matches at the end of a line, not only at the


[committed] libstdc++: Add missing header to test

2021-10-01 Thread Jonathan Wakely via Gcc-patches
We need to include  (or one of the containers) to get a
definition for std::begin.

libstdc++-v3/ChangeLog:

* testsuite/25_algorithms/is_permutation/2.cc: Include .

Tested x86_64-linux. Committed to trunk.

commit 94311bf34704ebecf745043fe2df03df201052fe
Author: Jonathan Wakely 
Date:   Fri Oct 1 12:55:53 2021

libstdc++: Add missing header to test

We need to include  (or one of the containers) to get a
definition for std::begin.

libstdc++-v3/ChangeLog:

* testsuite/25_algorithms/is_permutation/2.cc: Include .

diff --git a/libstdc++-v3/testsuite/25_algorithms/is_permutation/2.cc 
b/libstdc++-v3/testsuite/25_algorithms/is_permutation/2.cc
index 8d15c22f593..252226ca08f 100644
--- a/libstdc++-v3/testsuite/25_algorithms/is_permutation/2.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/is_permutation/2.cc
@@ -20,6 +20,7 @@
 // 25.2.12 [alg.is_permutation] Is permutation
 
 #include 
+#include 
 #include 
 #include 
 


[committed] libstdc++: Add noexcept to istream_iterator and ostream_iterator

2021-10-01 Thread Jonathan Wakely via Gcc-patches
libstdc++-v3/ChangeLog:

* include/bits/stream_iterator.h (istream_iterator): Add
noexcept to constructors and non-throwing member functions and
friend functions.
(ostream_iterator): Likewise.

Tested x86_64-linux. Committed to trunk.

commit 901fa4cc27ce693b361220818732556bfa586eea
Author: Jonathan Wakely 
Date:   Thu Sep 30 14:39:36 2021

libstdc++: Add noexcept to istream_iterator and ostream_iterator

libstdc++-v3/ChangeLog:

* include/bits/stream_iterator.h (istream_iterator): Add
noexcept to constructors and non-throwing member functions and
friend functions.
(ostream_iterator): Likewise.

diff --git a/libstdc++-v3/include/bits/stream_iterator.h 
b/libstdc++-v3/include/bits/stream_iterator.h
index d74c158f342..5a132319111 100644
--- a/libstdc++-v3/include/bits/stream_iterator.h
+++ b/libstdc++-v3/include/bits/stream_iterator.h
@@ -65,6 +65,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 public:
   ///  Construct end of input stream iterator.
   _GLIBCXX_CONSTEXPR istream_iterator()
+  _GLIBCXX_NOEXCEPT_IF(is_nothrow_default_constructible<_Tp>::value)
   : _M_stream(0), _M_value(), _M_ok(false) {}
 
   ///  Construct start of input stream iterator.
@@ -73,6 +74,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   { _M_read(); }
 
   istream_iterator(const istream_iterator& __obj)
+  _GLIBCXX_NOEXCEPT_IF(is_nothrow_copy_constructible<_Tp>::value)
   : _M_stream(__obj._M_stream), _M_value(__obj._M_value),
 _M_ok(__obj._M_ok)
   { }
@@ -91,7 +93,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   _GLIBCXX_NODISCARD
   const _Tp&
-  operator*() const
+  operator*() const _GLIBCXX_NOEXCEPT
   {
__glibcxx_requires_cond(_M_ok,
_M_message(__gnu_debug::__msg_deref_istream)
@@ -101,7 +103,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   _GLIBCXX_NODISCARD
   const _Tp*
-  operator->() const { return std::__addressof((operator*())); }
+  operator->() const _GLIBCXX_NOEXCEPT
+  { return std::__addressof((operator*())); }
 
   istream_iterator&
   operator++()
@@ -126,7 +129,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 private:
   bool
-  _M_equal(const istream_iterator& __x) const
+  _M_equal(const istream_iterator& __x) const _GLIBCXX_NOEXCEPT
   {
// Ideally this would just return _M_stream == __x._M_stream,
// but code compiled with old versions never sets _M_stream to null.
@@ -148,6 +151,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   _GLIBCXX_NODISCARD
   friend bool
   operator==(const istream_iterator& __x, const istream_iterator& __y)
+  _GLIBCXX_NOEXCEPT
   { return __x._M_equal(__y); }
 
 #if __cpp_impl_three_way_comparison < 201907L
@@ -156,13 +160,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   _GLIBCXX_NODISCARD
   friend bool
   operator!=(const istream_iterator& __x, const istream_iterator& __y)
+  _GLIBCXX_NOEXCEPT
   { return !__x._M_equal(__y); }
 #endif
 
 #if __cplusplus > 201703L && __cpp_lib_concepts
   [[nodiscard]]
   friend bool
-  operator==(const istream_iterator& __i, default_sentinel_t)
+  operator==(const istream_iterator& __i, default_sentinel_t) noexcept
   { return !__i._M_stream; }
 #endif
 };
@@ -200,7 +205,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 public:
   /// Construct from an ostream.
-  ostream_iterator(ostream_type& __s)
+  ostream_iterator(ostream_type& __s) _GLIBCXX_NOEXCEPT
   : _M_stream(std::__addressof(__s)), _M_string(0) {}
 
   /**
@@ -213,11 +218,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  @param  __s  Underlying ostream to write to.
*  @param  __c  CharT delimiter string to insert.
   */
-  ostream_iterator(ostream_type& __s, const _CharT* __c)
+  ostream_iterator(ostream_type& __s, const _CharT* __c) _GLIBCXX_NOEXCEPT
   : _M_stream(std::__addressof(__s)), _M_string(__c)  { }
 
   /// Copy constructor.
-  ostream_iterator(const ostream_iterator& __obj)
+  ostream_iterator(const ostream_iterator& __obj) _GLIBCXX_NOEXCEPT
   : _M_stream(__obj._M_stream), _M_string(__obj._M_string)  { }
 
 #if __cplusplus >= 201103L
@@ -240,15 +245,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   _GLIBCXX_NODISCARD
   ostream_iterator&
-  operator*()
+  operator*() _GLIBCXX_NOEXCEPT
   { return *this; }
 
   ostream_iterator&
-  operator++()
+  operator++() _GLIBCXX_NOEXCEPT
   { return *this; }
 
   ostream_iterator&
-  operator++(int)
+  operator++(int) _GLIBCXX_NOEXCEPT
   { return *this; }
 };
 


[committed] libstdc++: Fix _ForwardIteratorConcept for __gnu_debug::vector

2021-10-01 Thread Jonathan Wakely via Gcc-patches
The recent changes to the _GLIBCXX_CONCEPT_CHECKS checks for forward
iterators don't work for vector iterators in debug mode, because
the _Safe_iterator specializations don't match the special cases I added
for _Bit_iterator and _Bit_const_iterator.

This refactors the _ForwardIteratorReferenceConcept class template to
identify vector iterators using a new trait, which also works for
debug iterators.

libstdc++-v3/ChangeLog:

* include/bits/boost_concept_check.h (_Is_vector_bool_iterator):
New trait to identify vector iterators, including debug
ones.
(_ForwardIteratorReferenceConcept): Add default template
argument using _Is_vector_bool_iterator and use it in partial
specialization for the vector cases.
(_Mutable_ForwardIteratorReferenceConcept): Likewise.
* testsuite/24_iterators/operations/prev_neg.cc: Adjust dg-error
line number.

Tested x86_64-linux. Committed to trunk.

commit c67339d12653c33f85f8141789d7a7cf38831cbd
Author: Jonathan Wakely 
Date:   Thu Sep 30 11:25:15 2021

libstdc++: Fix _ForwardIteratorConcept for __gnu_debug::vector

The recent changes to the _GLIBCXX_CONCEPT_CHECKS checks for forward
iterators don't work for vector iterators in debug mode, because
the _Safe_iterator specializations don't match the special cases I added
for _Bit_iterator and _Bit_const_iterator.

This refactors the _ForwardIteratorReferenceConcept class template to
identify vector iterators using a new trait, which also works for
debug iterators.

libstdc++-v3/ChangeLog:

* include/bits/boost_concept_check.h (_Is_vector_bool_iterator):
New trait to identify vector iterators, including debug
ones.
(_ForwardIteratorReferenceConcept): Add default template
argument using _Is_vector_bool_iterator and use it in partial
specialization for the vector cases.
(_Mutable_ForwardIteratorReferenceConcept): Likewise.
* testsuite/24_iterators/operations/prev_neg.cc: Adjust dg-error
line number.

diff --git a/libstdc++-v3/include/bits/boost_concept_check.h 
b/libstdc++-v3/include/bits/boost_concept_check.h
index 71c99c13e93..81352518c50 100644
--- a/libstdc++-v3/include/bits/boost_concept_check.h
+++ b/libstdc++-v3/include/bits/boost_concept_check.h
@@ -47,11 +47,19 @@
 namespace std  _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
+_GLIBCXX_BEGIN_NAMESPACE_CONTAINER
   struct _Bit_iterator;
   struct _Bit_const_iterator;
+_GLIBCXX_END_NAMESPACE_CONTAINER
 _GLIBCXX_END_NAMESPACE_VERSION
 }
 
+namespace __gnu_debug
+{
+  template
+class _Safe_iterator;
+}
+
 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -478,10 +486,32 @@ struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; };
 _ValueT __val() const;
   };
 
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-variable"
+  template
+  struct _Is_vector_bool_iterator
+  { static const bool __value = false; };
 
-  template 
+#ifdef _GLIBCXX_DEBUG
+  namespace __cont = ::std::_GLIBCXX_STD_C;
+#else
+  namespace __cont = ::std;
+#endif
+
+  // Trait to identify vector::iterator
+  template <>
+  struct _Is_vector_bool_iterator<__cont::_Bit_iterator>
+  { static const bool __value = true; };
+
+  // And for vector::const_iterator.
+  template <>
+  struct _Is_vector_bool_iterator<__cont::_Bit_const_iterator>
+  { static const bool __value = true; };
+
+  // And for __gnu_debug::vector iterators too.
+  template 
+  struct _Is_vector_bool_iterator<__gnu_debug::_Safe_iterator<_It, _Seq, _Tag> 
>
+  : _Is_vector_bool_iterator<_It> { };
+
+  template ::__value>
   struct _ForwardIteratorReferenceConcept
   {
 void __constraints() {
@@ -493,7 +523,7 @@ struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; };
 }
   };
 
-  template 
+  template ::__value>
   struct _Mutable_ForwardIteratorReferenceConcept
   {
 void __constraints() {
@@ -503,26 +533,22 @@ struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; };
 }
   };
 
-  // vector::iterator is not a real forward reference, but pretend it is.
-  template <>
-  struct _ForwardIteratorReferenceConcept
+  // vector iterators are not real forward iterators, but we ignore that.
+  template 
+  struct _ForwardIteratorReferenceConcept<_Tp, true>
   {
 void __constraints() { }
   };
 
-  // vector::iterator is not a real forward reference, but pretend it is.
-  template <>
-  struct _Mutable_ForwardIteratorReferenceConcept
+  // vector iterators are not real forward iterators, but we ignore that.
+  template 
+  struct _Mutable_ForwardIteratorReferenceConcept<_Tp, true>
   {
 void __constraints() { }
   };
 
-  // And vector::const iterator too.
-  template <>
-  struct _ForwardIteratorReferenceConcept
-  {
-void __constraints() { }
-  };
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored 

[committed] libstdc++: Replace try-catch in std::list::merge to avoid O(N) size

2021-10-01 Thread Jonathan Wakely via Gcc-patches
The current std::list::merge code calls size() before starting to merge
any elements, so that the _M_size members can be updated after the merge
finishes. The work is done in a try-block so that the sizes can still be
updated in an exception handler if any element comparison throws.

The _M_size members only exist for the cxx11 ABI, so the initial call to
size() and the try-catch are only needed for that ABI. For the old ABI
the size() call performs an O(N) list traversal to get a value that
isn't even used, and catching exceptions just to rethrow them isn't
needed either.

This refactors the merge functions to remove the try-catch block and use
an RAII type instead. For the cxx11 ABI that type's destructor updates
the list sizes, and for the old ABI it's a no-op.

libstdc++-v3/ChangeLog:

* include/bits/list.tcc (list::merge): Remove call to size() and
try-catch block. Use _Finalize_merge instead.
* include/bits/stl_list.h (list::_Finalize_merge): New
scope guard type to update _M_size members after a merge.

Tested x86_64-linux. Committed to trunk.

commit b8d42cfa84fb31e592411e6cea41bdde980c51d7
Author: Jonathan Wakely 
Date:   Wed Sep 29 20:46:55 2021

libstdc++: Replace try-catch in std::list::merge to avoid O(N) size

The current std::list::merge code calls size() before starting to merge
any elements, so that the _M_size members can be updated after the merge
finishes. The work is done in a try-block so that the sizes can still be
updated in an exception handler if any element comparison throws.

The _M_size members only exist for the cxx11 ABI, so the initial call to
size() and the try-catch are only needed for that ABI. For the old ABI
the size() call performs an O(N) list traversal to get a value that
isn't even used, and catching exceptions just to rethrow them isn't
needed either.

This refactors the merge functions to remove the try-catch block and use
an RAII type instead. For the cxx11 ABI that type's destructor updates
the list sizes, and for the old ABI it's a no-op.

libstdc++-v3/ChangeLog:

* include/bits/list.tcc (list::merge): Remove call to size() and
try-catch block. Use _Finalize_merge instead.
* include/bits/stl_list.h (list::_Finalize_merge): New
scope guard type to update _M_size members after a merge.

diff --git a/libstdc++-v3/include/bits/list.tcc 
b/libstdc++-v3/include/bits/list.tcc
index 0ce4c47a90e..62b0ba1063a 100644
--- a/libstdc++-v3/include/bits/list.tcc
+++ b/libstdc++-v3/include/bits/list.tcc
@@ -416,29 +416,22 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
  iterator __last1 = end();
  iterator __first2 = __x.begin();
  iterator __last2 = __x.end();
- const size_t __orig_size = __x.size();
- __try {
-   while (__first1 != __last1 && __first2 != __last2)
- if (*__first2 < *__first1)
-   {
- iterator __next = __first2;
- _M_transfer(__first1, __first2, ++__next);
- __first2 = __next;
-   }
- else
-   ++__first1;
-   if (__first2 != __last2)
- _M_transfer(__last1, __first2, __last2);
 
-   this->_M_inc_size(__x._M_get_size());
-   __x._M_set_size(0);
- }
- __catch(...)
+ const _Finalize_merge __fin(*this, __x, __first2);
+
+ while (__first1 != __last1 && __first2 != __last2)
+   if (*__first2 < *__first1)
+ {
+   iterator __next = __first2;
+   _M_transfer(__first1, __first2, ++__next);
+   __first2 = __next;
+ }
+   else
+ ++__first1;
+ if (__first2 != __last2)
{
- const size_t __dist = std::distance(__first2, __last2);
- this->_M_inc_size(__orig_size - __dist);
- __x._M_set_size(__dist);
- __throw_exception_again;
+ _M_transfer(__last1, __first2, __last2);
+ __first2 = __last2;
}
}
 }
@@ -463,30 +456,22 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
iterator __last1 = end();
iterator __first2 = __x.begin();
iterator __last2 = __x.end();
-   const size_t __orig_size = __x.size();
-   __try
- {
-   while (__first1 != __last1 && __first2 != __last2)
- if (__comp(*__first2, *__first1))
-   {
- iterator __next = __first2;
- _M_transfer(__first1, __first2, ++__next);
- __first2 = __next;
-   }
- else
-   ++__first1;
-   if (__first2 != __last2)
- _M_transfer(__last1, __first2, __last2);
 
-   this->_M_inc_size(__x._M_get_size());
-   __x._M_set_size(0);

Re: [PATCH] c++: unifying equal NONTYPE_ARGUMENT_PACKs [PR102547]

2021-10-01 Thread Jason Merrill via Gcc-patches

On 10/1/21 09:46, Patrick Palka wrote:

Here during partial ordering of the two partial specializations we end
up in unify with parm=arg=NONTYPE_ARGUMENT_PACK, and crash shortly
thereafter because uses_template_parms calls potential_constant_expression
which doesn't handle NONTYPE_ARGUMENT_PACK.

This patch fixes this by checking dependent_template_arg_p instead of
uses_template_parms when parm==arg, which does handle NONTYPE_ARGUMENT_PACK.
We could also perhaps fix uses_template_parms / inst_dep_expr_p to better
handle NONTYPE_ARGUMENT_PACK,


Please.


but interestingly none of our existing tests
exercise calling those functions on NONTYPE_ARGUMENT_PACK, so such a fix
would be seemingly moot.

Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
trunk/11?

PR c++/102547

gcc/cp/ChangeLog:

* pt.c (unify): Check dependent_template_arg_p instead of
uses_template_parms when parm==arg.

gcc/testsuite/ChangeLog:

* g++.dg/cpp0x/variadic-partial2.C: New test.
---
  gcc/cp/pt.c   |  2 +-
  .../g++.dg/cpp0x/variadic-partial2.C  | 16 ++
  .../g++.dg/cpp0x/variadic-partial2a.C | 22 +++
  3 files changed, 39 insertions(+), 1 deletion(-)
  create mode 100644 gcc/testsuite/g++.dg/cpp0x/variadic-partial2.C
  create mode 100644 gcc/testsuite/g++.dg/cpp0x/variadic-partial2a.C

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 1dcdffe322a..59c00c77a30 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -23587,7 +23587,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, 
int strict,
   even if ARG == PARM, since we won't record unifications for the
   template parameters.  We might need them if we're trying to
   figure out which of two things is more specialized.  */
-  if (arg == parm && !uses_template_parms (parm))
+  if (arg == parm && !dependent_template_arg_p (parm))
  return unify_success (explain_p);
  
/* Handle init lists early, so the rest of the function can assume

diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-partial2.C 
b/gcc/testsuite/g++.dg/cpp0x/variadic-partial2.C
new file mode 100644
index 000..df61f26a3c1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic-partial2.C
@@ -0,0 +1,16 @@
+// PR c++/102547
+// { dg-do compile { target c++11 } }
+
+template
+struct vals { };
+
+template
+struct vals_client { };
+
+template
+struct vals_client, T> { };
+
+template
+struct vals_client, void> { };
+
+template struct vals_client, void>; //- "sorry, unimplemented..., 
ICE"
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-partial2a.C 
b/gcc/testsuite/g++.dg/cpp0x/variadic-partial2a.C
new file mode 100644
index 000..cc0ea488ad3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic-partial2a.C
@@ -0,0 +1,22 @@
+// PR c++/102547
+// { dg-do compile { target c++11 } }
+// A version of variadic-partial2.C where the partial ordering is performed
+// on function templates instead of class templates.
+
+template
+struct vals { };
+
+template
+void f(V, T) { };
+
+template
+void f(vals, T) { };
+
+template
+void f(vals, char) { };
+
+template void f(vals<1, 2>, char); //- "sorry, unimplemented..., ICE"
+
+int main() {
+  f(vals<1, 3>{}, 'a'); //- "sorry, unimplemented..., ICE"
+}





[PATCH][pushed] options: fix concat of options.

2021-10-01 Thread Martin Liška

It's quite an obvious error I made during concat of
merged_decoded_options.

make check -k RUNTESTFLAGS="i386.exp"

works fine now.

Martin

PR target/102552

gcc/c-family/ChangeLog:

* c-common.c (parse_optimize_options): decoded_options[0] is
  used for program name, so merged_decoded_options should also
  respect that.
---
 gcc/c-family/c-common.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 7b99a5546ea..5845c675e85 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -5912,9 +5912,10 @@ parse_optimize_options (tree args, bool attr_p)
   cl_decoded_option *merged_decoded_options
 = XNEWVEC (cl_decoded_option, merged_decoded_options_count);
 
+  /* Note the first decoded_options is used for the program name.  */

   for (unsigned i = 0; i < save_opt_count; ++i)
-merged_decoded_options[i] = save_opt_decoded_options[i];
-  for (unsigned i = 0; i < decoded_options_count; ++i)
+merged_decoded_options[i + 1] = save_opt_decoded_options[i];
+  for (unsigned i = 1; i < decoded_options_count; ++i)
 merged_decoded_options[save_opt_count + i] = decoded_options[i];
 
/* And apply them.  */

--
2.33.0



[PATCH] c++: unifying equal NONTYPE_ARGUMENT_PACKs [PR102547]

2021-10-01 Thread Patrick Palka via Gcc-patches
Here during partial ordering of the two partial specializations we end
up in unify with parm=arg=NONTYPE_ARGUMENT_PACK, and crash shortly
thereafter because uses_template_parms calls potential_constant_expression
which doesn't handle NONTYPE_ARGUMENT_PACK.

This patch fixes this by checking dependent_template_arg_p instead of
uses_template_parms when parm==arg, which does handle NONTYPE_ARGUMENT_PACK.
We could also perhaps fix uses_template_parms / inst_dep_expr_p to better
handle NONTYPE_ARGUMENT_PACK, but interestingly none of our existing tests
exercise calling those functions on NONTYPE_ARGUMENT_PACK, so such a fix
would be seemingly moot.

Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
trunk/11?

PR c++/102547

gcc/cp/ChangeLog:

* pt.c (unify): Check dependent_template_arg_p instead of
uses_template_parms when parm==arg.

gcc/testsuite/ChangeLog:

* g++.dg/cpp0x/variadic-partial2.C: New test.
---
 gcc/cp/pt.c   |  2 +-
 .../g++.dg/cpp0x/variadic-partial2.C  | 16 ++
 .../g++.dg/cpp0x/variadic-partial2a.C | 22 +++
 3 files changed, 39 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/variadic-partial2.C
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/variadic-partial2a.C

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 1dcdffe322a..59c00c77a30 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -23587,7 +23587,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, 
int strict,
  even if ARG == PARM, since we won't record unifications for the
  template parameters.  We might need them if we're trying to
  figure out which of two things is more specialized.  */
-  if (arg == parm && !uses_template_parms (parm))
+  if (arg == parm && !dependent_template_arg_p (parm))
 return unify_success (explain_p);
 
   /* Handle init lists early, so the rest of the function can assume
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-partial2.C 
b/gcc/testsuite/g++.dg/cpp0x/variadic-partial2.C
new file mode 100644
index 000..df61f26a3c1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic-partial2.C
@@ -0,0 +1,16 @@
+// PR c++/102547
+// { dg-do compile { target c++11 } }
+
+template
+struct vals { };
+
+template
+struct vals_client { };
+
+template
+struct vals_client, T> { };
+
+template
+struct vals_client, void> { };
+
+template struct vals_client, void>; //- "sorry, unimplemented..., 
ICE"
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-partial2a.C 
b/gcc/testsuite/g++.dg/cpp0x/variadic-partial2a.C
new file mode 100644
index 000..cc0ea488ad3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic-partial2a.C
@@ -0,0 +1,22 @@
+// PR c++/102547
+// { dg-do compile { target c++11 } }
+// A version of variadic-partial2.C where the partial ordering is performed
+// on function templates instead of class templates.
+
+template
+struct vals { };
+
+template
+void f(V, T) { };
+
+template
+void f(vals, T) { };
+
+template
+void f(vals, char) { };
+
+template void f(vals<1, 2>, char); //- "sorry, unimplemented..., ICE"
+
+int main() {
+  f(vals<1, 3>{}, 'a'); //- "sorry, unimplemented..., ICE"
+}
-- 
2.33.0.610.gcefe983a32



Re: [PATCH] Pass relations down to range_operator::op[12]_range.

2021-10-01 Thread Andrew MacLeod via Gcc-patches

On 10/1/21 8:43 AM, Aldy Hernandez wrote:

It looks like we don't pass relations down to the op[12]_range
operators.  This is causing problems when implementing some relational
magic for the shift operators.

Andrew, this looks like an oversight.  If so, how does this look?



Hrm.  It's at least partial.  It will utilize relations as they exist at 
the query point, but they would not include any relations introduced by 
the unwind sequence.


at the If, there is no relation c_1 < a_2.  Its true we are checking the 
true edge, and in theory the relation should be registered on that true 
edge..  Perhaps I need to register the relation on the edge from the 
stmt before resolving the stmt rather than after like we currently do.


Let me think about that for a bit.

Andrew



Re: [PATCH] c++: Implement C++20 -Wdeprecated-array-compare [PR97573]

2021-10-01 Thread Jason Merrill via Gcc-patches

On 9/30/21 17:56, Marek Polacek wrote:

On Thu, Sep 30, 2021 at 03:34:24PM -0400, Jason Merrill wrote:

On 9/30/21 10:50, Marek Polacek wrote:

This patch addresses one of my leftovers from GCC 11.  C++20 introduced
[depr.array.comp]:
"Equality and relational comparisons between two operands of array type are
deprecated."
so this patch adds -Wdeprecated-array-compare (enabled by default in C++20).


Why not enable it by default in all modes?  It was always pretty dubious
code.


Sure, it could be done, but it kind of complicates things: we'd probably
need a different option and a different message because it seems incorrect
to say "deprecated" in e.g. C++17 when this was only deprecated in C++20.


The warning could say "deprecated in C++20", which is always true?


I'd rather not add another option; if it stays -Wdeprecated-array-compare
but -Wno-deprecated doesn't turn it off that also seems weird.

I could rename it to -Warray-compare, enable by -Wall, and only
append "is deprecated" to the warning message in C++20.  Does that seem
better?


That sounds fine too.


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

PR c++/97573

gcc/c-family/ChangeLog:

* c-opts.c (c_common_post_options): In C++20, turn on
-Wdeprecated-array-compare.
* c.opt (Wdeprecated-array-compare): New option.

gcc/cp/ChangeLog:

* typeck.c (do_warn_deprecated_array_compare): New.
(cp_build_binary_op): Call it for equality and relational comparisons.

gcc/ChangeLog:

* doc/invoke.texi: Document -Wdeprecated-array-compare.

gcc/testsuite/ChangeLog:

* g++.dg/tree-ssa/pr15791-1.C: Add dg-warning.
* g++.dg/cpp2a/array-comp1.C: New test.
* g++.dg/cpp2a/array-comp2.C: New test.
* g++.dg/cpp2a/array-comp3.C: New test.
---
   gcc/c-family/c-opts.c |  5 
   gcc/c-family/c.opt|  4 +++
   gcc/cp/typeck.c   | 28 +++
   gcc/doc/invoke.texi   | 19 -
   gcc/testsuite/g++.dg/cpp2a/array-comp1.C  | 34 +++
   gcc/testsuite/g++.dg/cpp2a/array-comp2.C  | 31 +
   gcc/testsuite/g++.dg/cpp2a/array-comp3.C  | 29 +++
   gcc/testsuite/g++.dg/tree-ssa/pr15791-1.C |  2 +-
   8 files changed, 150 insertions(+), 2 deletions(-)
   create mode 100644 gcc/testsuite/g++.dg/cpp2a/array-comp1.C
   create mode 100644 gcc/testsuite/g++.dg/cpp2a/array-comp2.C
   create mode 100644 gcc/testsuite/g++.dg/cpp2a/array-comp3.C

diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c
index 3eaab5e1530..00b52cc5e12 100644
--- a/gcc/c-family/c-opts.c
+++ b/gcc/c-family/c-opts.c
@@ -962,6 +962,11 @@ c_common_post_options (const char **pfilename)
   warn_deprecated_enum_float_conv,
   cxx_dialect >= cxx20 && warn_deprecated);
+  /* -Wdeprecated-array-compare is enabled by default in C++20.  */
+  SET_OPTION_IF_UNSET (_options, _options_set,
+  warn_deprecated_array_compare,
+  cxx_dialect >= cxx20 && warn_deprecated);
+
 /* Declone C++ 'structors if -Os.  */
 if (flag_declone_ctor_dtor == -1)
   flag_declone_ctor_dtor = optimize_size;
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 9c151d19870..a4f0ea68594 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -540,6 +540,10 @@ Wdeprecated
   C C++ ObjC ObjC++ CPP(cpp_warn_deprecated) CppReason(CPP_W_DEPRECATED)
   ; Documented in common.opt
+Wdeprecated-array-compare
+C++ ObjC++ Var(warn_deprecated_array_compare) Warning
+Warn about deprecated comparisons between two operands of array type.
+
   Wdeprecated-copy
   C++ ObjC++ Var(warn_deprecated_copy) Warning LangEnabledBy(C++ ObjC++, 
Wextra)
   Mark implicitly-declared copy operations as deprecated if the class has a
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index a2398dbe660..1e3a41104d6 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -40,6 +40,7 @@ along with GCC; see the file COPYING3.  If not see
   #include "attribs.h"
   #include "asan.h"
   #include "gimplify.h"
+#include "tree-pretty-print.h"
   static tree cp_build_addr_expr_strict (tree, tsubst_flags_t);
   static tree cp_build_function_call (tree, tree, tsubst_flags_t);
@@ -4725,6 +4726,21 @@ do_warn_enum_conversions (location_t loc, enum tree_code 
code, tree type0,
   }
   }
+/* Warn about C++20 [depr.array.comp] array comparisons: "Equality
+   and relational comparisons between two operands of array type are
+   deprecated."  */
+
+static inline void
+do_warn_deprecated_array_compare (location_t location, tree_code code,
+ tree op0, tree op1)
+{
+  if (warning_at (location, OPT_Wdeprecated_array_compare,
+ "comparison between two arrays is deprecated"))
+inform (location, "use unary %<+%> which decays operands to pointers "
+   "or %<&%D[0] %s &%D[0]%> to 

Re: [PATCH] c++: Suppress error when cv-qualified reference is introduced by typedef [PR101783]

2021-10-01 Thread Jason Merrill via Gcc-patches

On 9/30/21 14:24, nick huang wrote:

You may need to run contrib/gcc-git-customization.sh to get the git
gcc-verify command.

I re-setup and can use git gcc-verify. Now I can see it rejects because I 
forgot to add a
description of modified file. Now that it passes gcc-verify and I attach the 
changelog
as attachment.

Thank you again for your patient explanation and help!


You're welcome, thanks for your patience as well!  Unfortunately, git 
gcc-verify still fails with this version:



ERR: line should start with a tab: "PR c++/101783"
ERR: line should start with a tab: "* tree.c (cp_build_qualified_type_real): 
Excluding typedef from error"
ERR: line should start with a tab: "PR c++/101783"
ERR: line should start with a tab: "* g++.dg/parse/pr101783.C: New test."


It might work better to attach the output of git format-patch.

Also, your commit subject line is too long, at 83 characters: It must be 
under 75 characters, and preferably closer to 50.  I might shorten it to


c++: cv-qualified ref introduced by typedef [PR101783]


* tree.c (cp_build_qualified_type_real): Excluding typedef from error


A change description in the ChangeLog should use present tense 
("Exclude"), have a period at the end, and line wrap at 75 characters 
like the rest of the commit message.  So,


* tree.c (cp_build_qualified_type_real): Exclude typedef from
error.

+ ([dcl.type.decltype]),in which case the cv-qualifiers are ignored.
+  */   


We usually don't put */ on its own line.

Jason



[PATCH][GCC][committed] aarch64: fix AARCH64_FL_V9 flag value

2021-10-01 Thread Przemyslaw Wirkus via Gcc-patches
Patch is fixing AARCH64_FL_V9 flag value which is now wrongly set due to
merge error.

Committed as obvious.

gcc/ChangeLog:

* config/aarch64/aarch64.h (AARCH64_FL_V9): Update value.

--- 

diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index 6908b8f4a16..2792bb29adb 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -230,8 +230,6 @@ extern unsigned aarch64_architecture_version;

 /* Pointer Authentication (PAUTH) extension.  */
 #define AARCH64_FL_PAUTH  (1ULL << 40)
-/* Armv9.0-A.  */
-#define AARCH64_FL_V9 (1ULL << 41)  /* Armv9.0-A Architecture.  */

 /* 64-byte atomic load/store extensions.  */
 #define AARCH64_FL_LS64  (1ULL << 41)
@@ -239,6 +237,9 @@ extern unsigned aarch64_architecture_version;
 /* Armv8.7-a architecture extensions.  */
 #define AARCH64_FL_V8_7   (1ULL << 42)

+/* Armv9.0-A.  */
+#define AARCH64_FL_V9 (1ULL << 43)  /* Armv9.0-A Architecture.  */
+
 /* Has FP and SIMD.  */
 #define AARCH64_FL_FPSIMD (AARCH64_FL_FP | AARCH64_FL_SIMD)


Re: [PATCH v2] tree-optimization/101186 - extend FRE with "equivalence map" for condition prediction

2021-10-01 Thread Richard Biener via Gcc-patches
On Thu, Sep 16, 2021 at 8:13 PM Di Zhao OS
 wrote:
>
> Sorry about updating on this after so long. It took me much time to work out a
> new plan and pass the tests.
>
> The new idea is to use one variable to represent a set of equal variables at
> some basic-block. This variable is called a "equivalence head" or "equiv-head"
> in the code. (There's no-longer a "equivalence map".)
>
> - Initially an SSA_NAME's "equivalence head" is its value number. Temporary
>   equivalence heads are recorded as unary NOP_EXPR results in the vn_nary_op_t
>   map. Besides, when inserting into vn_nary_op_t map, make the new result at
>   front of the vn_pval list, so that when searching for a variable's
>   equivalence head, the first result represents the largest equivalence set at
>   current location.
> - In vn_ssa_aux_t, maintain a list of references to valid_info->nary entry.
>   For recorded equivalences, the reference is result->entry; for normal N-ary
>   operations, the reference is operand->entry.
> - When recording equivalences, if one side A is constant or has more refs, 
> make
>   it the new equivalence head of the other side B. Traverse B's ref-list, if a
>   variable C's previous equiv-head is B, update to A. And re-insert B's n-ary
>   operations by replacing B with A.
> - When inserting and looking for the results of n-ary operations, insert and
>   lookup by the operands' equiv-heads.
>
> So except for the refs in vn_ssa_aux_t, this scheme uses the original
> infrastructure to its best. Quadric search time is avoided at the cost of some
> re-insertions. Test results on SPEC2017 intrate (counts and percentages):
>
> |more bb |more bb |more stmt|more stmt|more   |more
> |removed |removed |removed  |removed  |nv_nary_ops|nv_nary_ops
> |at fre1 |at fre1 |at fre1  |at fre1  |inserted   |inserted
> --
>  500.perlbench_r| 64 | 1.98%  | 103 | 0.19%   | 11260 | 12.16%
>  502.gcc_r  | 671| 4.80%  | 317 | 0.23%   | 13964 | 6.09%
>  505.mcf_r  | 5  | 35.71% | 9   | 1.40%   | 32| 2.52%
>  520.omnetpp| 132| 5.45%  | 39  | 0.11%   | 1895  | 3.91%
>  523.xalancbmk_r| 238| 3.26%  | 313 | 0.36%   | 1417  | 1.27%
>  525.x264_r | 4  | 1.36%  | 27  | 0.11%   | 1752  | 6.78%
>  531.deepsjeng_r| 1  | 3.45%  | 2   | 0.14%   | 228   | 8.67%
>  541.leela_r| 2  | 0.63%  | 0   | 0.00%   | 92| 1.14%
>  548.exchange2_r| 0  | 0.00%  | 3   | 0.04%   | 49| 1.03%
>  557.xz_r   | 0  | 0.00%  | 3   | 0.07%   | 272   | 7.55%
>
> There're more basic_blocks and statements removed compared with last
> implementation, the reasons are:
> 1) "CONST op CONST" simplification is included. It is missed in previous 
> patch.
> 2) By inserting RHS of statements on equiv-heads, more N-ary operations can be
>simplified. One example is in 'ssa-fre-97.c' in the patch file.
>
> While jump-threading & vrp also utilize temporary equivalences (so some of the
> newly removed blocks and statements can also be covered by them), I think this
> patch is a supplement, in cases when jump threading cannot take place (the
> original example), or value number info needs to be involved (the
> 'ssa-fre-97.c' example).
>
> Fixed the former issue with non-iterate mode.
>
> About recording the temporary equivalences generated by PHIs (i.e. the
> 'record_equiv_from_previous_cond' stuff), I have to admit it looks strange and
> the code size is large, but I haven't find a better way yet. Consider a piece
> of CFG like the one below, if we want to record x==x2 on the true edge when
> processing bb1, the location (following current practice) will be bb2. But 
> that
> is not useful at bb5 or bb6, because bb2 doesn't dominate them. And I can't
> find a place to record x==x1 when processing bb1.
> If we can record things on edges rather than blocks, say x==x1 on 1->3 and
> x==x2 on 1->2, then perhaps with an extra check for "a!=0", x2 can be a valid
> equiv-head for x since bb5. But I think it lacks efficiency and is not
> persuasive. It is more efficient to find a valid previous predicate when
> processing bb4, because the vn_nary_op_t will be fetched anyway.
> --
> | if (a != 0) | bb1
> --
> f |  \ t
>   |---
>   || bb2 |
>   |---
>   |  /
> -
> | x = PHI | bb3
> -
>|
>   
>|
>--
>| if (a != 0) | bb4
>--
>|f \t
> -  ---
> bb7 | where |  | bb5 |  ==> where "x==x2" is recorded now
> | "x==x1" is|  ---
> | recorded  |\
> | now   |...
> - |
>

[PATCH] Handle EQ_EXPR relation for operator_lshift.

2021-10-01 Thread Aldy Hernandez via Gcc-patches
Knowing that X << X is non-zero means X is also non-zero.  This patch
teaches this this to range-ops.

As usual, the big twiddling experts could come up with all sorts of
fancy enhancements in this area, and we welcome all patches :).

I will push this pending tests.

gcc/ChangeLog:

PR tree-optimization/102546
* range-op.cc (operator_lshift::op1_range): Handle EQ_EXPR
relation.
---
 gcc/range-op.cc  | 19 ---
 gcc/testsuite/gcc.dg/tree-ssa/pr102546.c | 23 +++
 2 files changed, 39 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr102546.c

diff --git a/gcc/range-op.cc b/gcc/range-op.cc
index 5e37133026d..53f3be4266e 100644
--- a/gcc/range-op.cc
+++ b/gcc/range-op.cc
@@ -2075,9 +2075,14 @@ operator_lshift::op1_range (irange ,
tree type,
const irange ,
const irange ,
-   relation_kind rel ATTRIBUTE_UNUSED) const
+   relation_kind rel) const
 {
   tree shift_amount;
+  int_range<2> adjust (type);
+
+  if (rel == EQ_EXPR && !lhs.contains_p (build_zero_cst (type)))
+adjust.set_nonzero (type);
+
   if (op2.singleton_p (_amount))
 {
   wide_int shift = wi::to_wide (shift_amount);
@@ -2086,10 +2091,11 @@ operator_lshift::op1_range (irange ,
   if (wi::ge_p (shift, wi::uhwi (TYPE_PRECISION (type),
 TYPE_PRECISION (op2.type ())),
UNSIGNED))
-   return false;
+   goto done;
   if (shift == 0)
{
  r = lhs;
+ r.intersect (adjust);
  return true;
}
 
@@ -2126,9 +2132,16 @@ operator_lshift::op1_range (irange ,
 
   if (utype != type)
range_cast (r, type);
+  r.intersect (adjust);
   return true;
 }
-  return false;
+
+ done:
+  if (adjust.varying_p ())
+return false;
+
+  r = adjust;
+  return true;
 }
 
 bool
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr102546.c 
b/gcc/testsuite/gcc.dg/tree-ssa/pr102546.c
new file mode 100644
index 000..4bd98747732
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr102546.c
@@ -0,0 +1,23 @@
+// { dg-do compile }
+// { dg-options "-O3 -fdump-tree-optimized" }
+
+static int a;
+static char b, c, d;
+void bar(void);
+void foo(void);
+
+int main() {
+int f = 0;
+for (; f <= 5; f++) {
+bar();
+b = b && f;
+d = f << f;
+if (!(a >= d || f))
+foo();
+c = 1;
+for (; c; c = 0)
+;
+}
+}
+
+// { dg-final { scan-tree-dump-not "foo" "optimized" } }
-- 
2.31.1



[PATCH] Pass relations down to range_operator::op[12]_range.

2021-10-01 Thread Aldy Hernandez via Gcc-patches
It looks like we don't pass relations down to the op[12]_range
operators.  This is causing problems when implementing some relational
magic for the shift operators.

Andrew, this looks like an oversight.  If so, how does this look?

Tested on x86-64 Linux.

gcc/ChangeLog:

* gimple-range-gori.cc (gimple_range_calc_op1): Add relation argument.
(gimple_range_calc_op2): Same.
(gori_compute::compute_operand1_range): Pass relation to
gimple_range_calc_op*.
(gori_compute::compute_operand2_range): Same.
---
 gcc/gimple-range-gori.cc | 28 +---
 1 file changed, 21 insertions(+), 7 deletions(-)

diff --git a/gcc/gimple-range-gori.cc b/gcc/gimple-range-gori.cc
index 4a1ade7f921..c7cfb71d849 100644
--- a/gcc/gimple-range-gori.cc
+++ b/gcc/gimple-range-gori.cc
@@ -59,7 +59,8 @@ gimple_range_calc_op1 (irange , const gimple *stmt, const 
irange _range)
 
 bool
 gimple_range_calc_op1 (irange , const gimple *stmt,
-  const irange _range, const irange _range)
+  const irange _range, const irange _range,
+  relation_kind rel)
 {
   // Unary operation are allowed to pass a range in for second operand
   // as there are often additional restrictions beyond the type which
@@ -72,7 +73,7 @@ gimple_range_calc_op1 (irange , const gimple *stmt,
   return true;
 }
   return gimple_range_handler (stmt)->op1_range (r, type, lhs_range,
-op2_range);
+op2_range, rel);
 }
 
 // Calculate what we can determine of the range of this statement's
@@ -82,7 +83,8 @@ gimple_range_calc_op1 (irange , const gimple *stmt,
 
 bool
 gimple_range_calc_op2 (irange , const gimple *stmt,
-  const irange _range, const irange _range)
+  const irange _range, const irange _range,
+  relation_kind rel)
 {
   tree type = TREE_TYPE (gimple_range_operand2 (stmt));
   // An empty range is viral.
@@ -92,7 +94,7 @@ gimple_range_calc_op2 (irange , const gimple *stmt,
   return true;
 }
   return gimple_range_handler (stmt)->op2_range (r, type, lhs_range,
-op1_range);
+op1_range, rel);
 }
 
 // Return TRUE if GS is a logical && or || expression.
@@ -1000,6 +1002,12 @@ gori_compute::compute_operand1_range (irange , gimple 
*stmt,
   int_range_max op1_range, op2_range;
   tree op1 = gimple_range_operand1 (stmt);
   tree op2 = gimple_range_operand2 (stmt);
+  relation_kind rel;
+
+  if (op1 && op2)
+rel = src.query_relation (op1, op2);
+  else
+rel = VREL_NONE;
 
   // Fetch the known range for op1 in this block.
   src.get_operand (op1_range, op1);
@@ -1008,7 +1016,7 @@ gori_compute::compute_operand1_range (irange , gimple 
*stmt,
   if (op2)
 {
   src.get_operand (op2_range, op2);
-  if (!gimple_range_calc_op1 (r, stmt, lhs, op2_range))
+  if (!gimple_range_calc_op1 (r, stmt, lhs, op2_range, rel))
return false;
 }
   else
@@ -1016,7 +1024,7 @@ gori_compute::compute_operand1_range (irange , gimple 
*stmt,
   // We pass op1_range to the unary operation.  Nomally it's a
   // hidden range_for_type parameter, but sometimes having the
   // actual range can result in better information.
-  if (!gimple_range_calc_op1 (r, stmt, lhs, op1_range))
+  if (!gimple_range_calc_op1 (r, stmt, lhs, op1_range, rel))
return false;
 }
 
@@ -1077,12 +1085,18 @@ gori_compute::compute_operand2_range (irange , gimple 
*stmt,
   int_range_max op1_range, op2_range;
   tree op1 = gimple_range_operand1 (stmt);
   tree op2 = gimple_range_operand2 (stmt);
+  relation_kind rel;
+
+  if (op1 && op2)
+rel = src.query_relation (op1, op2);
+  else
+rel = VREL_NONE;
 
   src.get_operand (op1_range, op1);
   src.get_operand (op2_range, op2);
 
   // Intersect with range for op2 based on lhs and op1.
-  if (!gimple_range_calc_op2 (r, stmt, lhs, op1_range))
+  if (!gimple_range_calc_op2 (r, stmt, lhs, op1_range, rel))
 return false;
 
   unsigned idx;
-- 
2.31.1



[COMMITTED] Remove shadowed oracle field.

2021-10-01 Thread Aldy Hernandez via Gcc-patches
The m_oracle field in the path solver was shadowing the base class.
This was causing subtle problems while calculating outgoing edges
between blocks, because the query object being passed did not have an
oracle set.

This should further improve our solving ability.

Tested on x86-64 Linux.

gcc/ChangeLog:

* gimple-range-path.cc (path_range_query::compute_ranges): Use
get_path_oracle.
* gimple-range-path.h (class path_range_query): Remove shadowed
m_oracle field.
(path_range_query::get_path_oracle): New.
---
 gcc/gimple-range-path.cc | 2 +-
 gcc/gimple-range-path.h  | 3 +--
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/gcc/gimple-range-path.cc b/gcc/gimple-range-path.cc
index a29d5318ca9..422abfddb8f 100644
--- a/gcc/gimple-range-path.cc
+++ b/gcc/gimple-range-path.cc
@@ -480,7 +480,7 @@ path_range_query::compute_ranges (const vec 
,
   if (m_resolve)
 {
   add_copies_to_imports ();
-  m_oracle->reset_path ();
+  get_path_oracle ()->reset_path ();
   compute_relations (path);
 }
 
diff --git a/gcc/gimple-range-path.h b/gcc/gimple-range-path.h
index cf49c6dc086..5f4e73a5949 100644
--- a/gcc/gimple-range-path.h
+++ b/gcc/gimple-range-path.h
@@ -38,7 +38,6 @@ public:
   bool range_of_expr (irange , tree name, gimple * = NULL) override;
   bool range_of_stmt (irange , gimple *, tree name = NULL) override;
   bool unreachable_path_p ();
-  path_oracle *oracle () { return m_oracle; }
   void dump (FILE *) override;
   void debug ();
 
@@ -46,6 +45,7 @@ private:
   bool internal_range_of_expr (irange , tree name, gimple *);
   bool defined_outside_path (tree name);
   void range_on_path_entry (irange , tree name);
+  path_oracle *get_path_oracle () { return (path_oracle *)m_oracle; }
 
   // Cache manipulation.
   void set_cache (const irange , tree name);
@@ -85,7 +85,6 @@ private:
   auto_bitmap m_imports;
   gimple_ranger _ranger;
   non_null_ref m_non_null;
-  path_oracle *m_oracle;
 
   // Current path position.
   unsigned m_pos;
-- 
2.31.1



RE: [PATCH][GCC] aarch64: enable cortex-x2 CPU

2021-10-01 Thread Kyrylo Tkachov via Gcc-patches



> -Original Message-
> From: Kyrylo Tkachov
> Sent: Friday, October 1, 2021 1:17 PM
> To: Przemyslaw Wirkus ; gcc-
> patc...@gcc.gnu.org
> Cc: Richard Earnshaw ; Richard Sandiford
> ; Marcus Shawcroft
> 
> Subject: RE: [PATCH][GCC] aarch64: enable cortex-x2 CPU
> 
> 
> 
> > -Original Message-
> > From: Przemyslaw Wirkus 
> > Sent: Wednesday, September 22, 2021 9:38 AM
> > To: gcc-patches@gcc.gnu.org
> > Cc: Richard Earnshaw ; Richard Sandiford
> > ; Marcus Shawcroft
> > ; Kyrylo Tkachov
> 
> > Subject: [PATCH][GCC] aarch64: enable cortex-x2 CPU
> >
> > Patch is adding 'cortex-x2' to -mcpu command line option.
> >
> > OK for master?
> >
> > gcc/ChangeLog:
> >
> > 2021-09-02  Przemyslaw Wirkus  
> >
> > * config/aarch64/aarch64-cores.def (AARCH64_CORE): New
> > Cortex-X2 core.
> > * config/aarch64/aarch64-tune.md: Regenerate.
> > * doc/invoke.texi: Update docs.
> diff --git a/gcc/config/aarch64/aarch64-cores.def
> b/gcc/config/aarch64/aarch64-cores.def
> index
> a8027e92fa8f7554e2b19d00f7c85c6ed48a92e5..34d9646ab6a32a19e7cd09d9
> 5594b59278d02920 100644
> --- a/gcc/config/aarch64/aarch64-cores.def
> +++ b/gcc/config/aarch64/aarch64-cores.def
> @@ -168,4 +168,6 @@ AARCH64_CORE("cortex-a510",  cortexa510,
> cortexa55, 9A,  AARCH64_FL_FOR_ARCH9 |
> 
>  AARCH64_CORE("cortex-a710",  cortexa710, cortexa55, 9A,
> AARCH64_FL_FOR_ARCH9 | AARCH64_FL_SVE2_BITPERM |
> AARCH64_FL_MEMTAG | AARCH64_FL_I8MM | AARCH64_FL_BF16,
> neoversen2, 0x41, 0xd47, -1)
> 
> +AARCH64_CORE("cortex-x2",  cortexx2, cortexa55, 9A,
> AARCH64_FL_FOR_ARCH9 | AARCH64_FL_SVE2_BITPERM |
> AARCH64_FL_MEMTAG | AARCH64_FL_I8MM | AARCH64_FL_BF16,
> neoversen2, 0x41, 0xd48, -1)
> +
> 
> Let's use cortexa57 for scheduling here for now.

I should have said, ok with that change.
Kyrill
> Thanks,
> Kyrill


  1   2   >