[PATCH] libstdc++: use new built-in trait __is_reference

2023-03-18 Thread Ken Matsui via Gcc-patches
libstdc++-v3/ChangeLog:

* include/std/type_traits (is_reference): Use __is_reference built-in trait.
---
diff --git a/libstdc++-v3/include/std/type_traits
b/libstdc++-v3/include/std/type_traits
index 2bd607a8b8f..18408d8ceb6 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -639,6 +639,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // Composite type categories.

   /// is_reference
+#if __has_builtin(__is_reference)
+  template
+struct is_reference
+: public integral_constant
+{ };
+#else
   template
 struct is_reference
 : public false_type
@@ -653,6 +659,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 struct is_reference<_Tp&&>
 : public true_type
 { };
+#endif

   /// is_arithmetic
   template


[PATCH] c++: implement __is_reference built-in trait

2023-03-18 Thread Ken Matsui via Gcc-patches
This patch implements built-in trait for std::is_reference.

gcc/cp/ChangeLog:

* cp-trait.def (names_builtin_p): Define __is_reference.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_REFERENCE.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Test existence of __is_reference.
* g++.dg/ext/is_reference.C: New test.

---
diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 273d15ab097..23e5bc24dbb 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3701,6 +3701,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_HAS_VIRTUAL_DESTRUCTOR:
   inform (loc, "  %qT does not have a virtual destructor", t1);
   break;
+case CPTK_IS_REFERENCE:
+  inform (loc, "  %qT is not a reference", t1);
+  break;
 case CPTK_IS_ABSTRACT:
   inform (loc, "  %qT is not an abstract class", t1);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index bac593c0094..63a64152ce6 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -67,6 +67,7 @@ DEFTRAIT_EXPR (IS_CONVERTIBLE, "__is_convertible", 2)
 DEFTRAIT_EXPR (IS_EMPTY, "__is_empty", 1)
 DEFTRAIT_EXPR (IS_ENUM, "__is_enum", 1)
 DEFTRAIT_EXPR (IS_FINAL, "__is_final", 1)
+DEFTRAIT_EXPR (IS_REFERENCE, "__is_reference", 1)
 DEFTRAIT_EXPR (IS_LAYOUT_COMPATIBLE, "__is_layout_compatible", 2)
 DEFTRAIT_EXPR (IS_LITERAL_TYPE, "__is_literal_type", 1)
 DEFTRAIT_EXPR (IS_NOTHROW_ASSIGNABLE, "__is_nothrow_assignable", 2)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 87c2e8a7111..dce98af4f72 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -11995,6 +11995,9 @@ trait_expr_value (cp_trait_kind kind, tree
type1, tree type2)
 case CPTK_IS_FINAL:
   return CLASS_TYPE_P (type1) && CLASSTYPE_FINAL (type1);

+case CPTK_IS_REFERENCE:
+  return type_code1 == REFERENCE_TYPE;
+
 case CPTK_IS_LAYOUT_COMPATIBLE:
   return layout_compatible_type_p (type1, type2);

@@ -12139,6 +12142,7 @@ finish_trait_expr (location_t loc,
cp_trait_kind kind, tree type1, tree type2)
 case CPTK_HAS_TRIVIAL_COPY:
 case CPTK_HAS_TRIVIAL_DESTRUCTOR:
 case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
+case CPTK_IS_REFERENCE:
   if (!check_trait_type (type1))
  return error_mark_node;
   break;
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index f343e153e56..b697673790c 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -146,3 +146,6 @@
 #if !__has_builtin (__remove_cvref)
 # error "__has_builtin (__remove_cvref) failed"
 #endif
+#if !__has_builtin (__is_reference)
+# error "__has_builtin (__is_reference) failed"
+#endif
diff --git a/gcc/testsuite/g++.dg/ext/is_reference.C
b/gcc/testsuite/g++.dg/ext/is_reference.C
new file mode 100644
index 000..b4f048538e5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_reference.C
@@ -0,0 +1,26 @@
+// { dg-do compile { target c++11 } }
+
+#define SA(X) static_assert((X),#X)
+
+SA(!__is_reference(void));
+SA(!__is_reference(int*));
+
+SA(__is_reference(int&));
+SA(__is_reference(const int&));
+SA(__is_reference(volatile int&));
+SA(__is_reference(const volatile int&));
+
+SA(__is_reference(int&&));
+SA(__is_reference(const int&&));
+SA(__is_reference(volatile int&&));
+SA(__is_reference(const volatile int&&));
+
+SA(!__is_reference(int[3]));
+SA(!__is_reference(const int[3]));
+SA(!__is_reference(volatile int[3]));
+SA(!__is_reference(const volatile int[3]));
+
+SA(!__is_reference(int(int)));
+SA(!__is_reference(int(*const)(int)));
+SA(!__is_reference(int(*volatile)(int)));
+SA(!__is_reference(int(*const volatile)(int)));


Re: [PATCH] correct function attribute typo

2023-03-18 Thread Sandra Loosemore

On 3/16/23 16:37, Jonny Grant wrote:

Hello
There's a typo in the common function attribute docs, "nonnul" which this patch 
corrects.


Thank you!  I've pushed this patch.

-Sandra


Re: [patch, wwwdocs] Mention random number generators in porting_to.html

2023-03-18 Thread Harald Anlauf via Gcc-patches

Hi Thomas,

Am 18.03.23 um 19:23 schrieb Thomas Koenig via Gcc-patches:

Hi,

Text says it all.  OK for web pages?

Best regards

 Thomas

Mention issues with integer owerflow for random number generators.

This mentions the issues with integer overflow and how to work
around them.


it's basically fine, although I'd prefer a formulation replacing

+  GCC 13 includes new optimizations which expose reliance on
+  non-standard behavior for integer overflow, which was often used
+  for linear congruential pseudo-random number generators in old
+  programs.  It is recommended to use the intrinsic

by something like:

GCC 13 includes new optimizations which may change behavior on
integer overflow.  Traditional code, like linear congruential
pseudo-random number generators in old programs and relying on a
specific, non-standard behavior may now generate unexpected results.
In such cases it is recommended to use the intrinsic ...


Thanks for updating the documentation!

Harald




Re: [PATCH] Fortran: procedures with BIND(C) attribute require explicit interface [PR85877]

2023-03-18 Thread Harald Anlauf via Gcc-patches

Hi Thomas,

Am 18.03.23 um 19:52 schrieb Thomas Koenig via Gcc-patches:

Hi Harald,


the Fortran standard requires an explicit procedure interface in certain
situations, such as when they have a BIND(C) attribute (F2018:15.4.2.2).
The attached patch adds a check for this.

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


While this fixes the ICE, it misses

function f() bind(c)
   f = 42.
end

subroutine p
   bind(c) f ! { dg-error "must be explicit" }
   x = f()
end


what do you mean by "it misses"?  I do not see an explicit interface
here, only a global symbol.  All compiler I tried with the above
code reject it one way or the other, e g. Cray:

  x = f()
  ^
ftn-954 crayftn: ERROR P, File = pr85877-2.f90, Line = 12, Column = 3
  Procedure "f", referenced at line 6 (pr85877-2.f90) must have an
explicit interface because one or more arguments have the BIND attribute.



subroutine s
   interface
  function g() bind(c)
  end function g
   end interface
   x = g()
end

where the interface is picked up via a global symbol.


Is it really true that this is in the spirit of the standard?
Is the global declaration above really equivalent to an explicit
interface?

I would expect legal code to be like:

function g() bind(c)
  g = 42.
end

subroutine s
  interface
 function g() bind(c)
 end function g
  end interface
  x = g()
end

unless you do it in the context of a module and in the right way.


This code
may not be valid; nagfor rejects it, but I cannot find a
constraint at least in the F2022 draft that prohibits it.


I thought that F2018:15.4.2.2 and F2023:15.4.2.2(7) are rather
clear and "explicit" on this.  IMHO the case of "f" above seems
to be excluded and thus not conforming.


Hm... might it be better to check for attr->module_procedure ||
attr->if_source == IFSRC_IFBODY?


Maybe we should find a set of legal and illegal cases that we
can agree upon.

Thanks,
Harald


Best regards

 Thomas






Ping (gcc/configure.ac, docs): [PATCH v2 4/5] Update texinfo.tex, remove the @gol macro/alias

2023-03-18 Thread Arsen Arsenović via Gcc-patches
Evening,

Ping on this patch series.

I believe we're close to being able to apply it, with contents of the
documentation changes being approved, and only a small build system
change and a revised patch series "shape" left to review.

The former change of these two is in:
https://inbox.sourceware.org/gcc-patches/20230311203234.2257423-1-ar...@aarsen.me/
The patch adds a test for the presence of CONTENTS_OUTPUT_LOCATION into
the build system in order to avoid shortcontents coming after contents
in HTML output.  We've also updated Texinfo to output shortcontents
before contents by default as a result of the discussion here, though
that will only happen in newer versions.

The latter "shape" is a git log documented at:
https://inbox.sourceware.org/gcc-patches/87ttysppsc@aarsen.me/

As always, I've freshly rebased the patch series at

  https://git.sr.ht/~arsen/gcc texinfo_improvements

... or, in (git)web form, at:

  https://git.sr.ht/~arsen/gcc/log/texinfo_improvements

... with the render at:

  https://www.aarsen.me/~arsen/final/

Thank you all in advance, have a lovely day.
-- 
Arsen Arsenović


signature.asc
Description: PGP signature


Re: [PATCH] Fortran: procedures with BIND(C) attribute require explicit interface [PR85877]

2023-03-18 Thread Thomas Koenig via Gcc-patches

Hi Harald,


the Fortran standard requires an explicit procedure interface in certain
situations, such as when they have a BIND(C) attribute (F2018:15.4.2.2).
The attached patch adds a check for this.

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


While this fixes the ICE, it misses

function f() bind(c)
  f = 42.
end

subroutine p
  bind(c) f ! { dg-error "must be explicit" }
  x = f()
end

subroutine s
  interface
 function g() bind(c)
 end function g
  end interface
  x = g()
end

where the interface is picked up via a global symbol.  This code
may not be valid; nagfor rejects it, but I cannot find a
constraint at least in the F2022 draft that prohibits it.

Hm... might it be better to check for attr->module_procedure ||
attr->if_source == IFSRC_IFBODY?

Best regards

Thomas



[patch, wwwdocs] Mention random number generators in porting_to.html

2023-03-18 Thread Thomas Koenig via Gcc-patches

Hi,

Text says it all.  OK for web pages?

Best regards

Thomas

Mention issues with integer owerflow for random number generators.

This mentions the issues with integer overflow and how to work
around them.
diff --git a/htdocs/gcc-13/porting_to.html b/htdocs/gcc-13/porting_to.html
index 0ee58802..7d733b16 100644
--- a/htdocs/gcc-13/porting_to.html
+++ b/htdocs/gcc-13/porting_to.html
@@ -203,11 +203,20 @@ class Alloc
 
 Since C++20, there is no rebind member in
 std::allocator, so deriving your own allocator types from
-std::allocator is simpler and doesn't require the derived
+std::allocator is simpler and does not require the derived
 allocator to provide its own rebind.
 For compatibility with previous C++ standards, the member should still be
 provided. The converting constructor is still required even in C++20.
 
 
+Fortran language issues
+Behavior on integer overflow
+ GCC 13 includes new optimizations which expose reliance on
+  non-standard behavior for integer overflow, which was often used
+  for linear congruential pseudo-random number generators in old
+  programs.  It is recommended to use the intrinsic
+  subroutine RANDOM_NUMBER for random number generators
+  or, if the old behavior is desired, to use the -fwrapv
+  option.  Note that this option can impact performance.
 
 


[pushed] analyzer: fix ICE on certain longjmp calls [PR109094]

2023-03-18 Thread David Malcolm via Gcc-patches
PR analyzer/109094 reports an ICE in the analyzer seen on qemu's
target/i386/tcg/translate.c

The issue turned out to be that when handling a longjmp, the code
to pop the frames was generating an svalue for the result_decl of any
popped frame that had a non-void return type (and discarding it) leading
to "uninit" poisoned_svalue_diagnostic instances being saved since the
result_decl is only set by the greturn stmt.  Later, when checking the
feasibility of the path to these diagnostics, m_check_expr was evaluated
in the context of the frame of the longjmp, leading to an attempt to
evaluate the result_decl of each intervening frames whilst in the
context of the topmost frame, leading to an assertion failure in
frame_region::get_region_for_local here:

919 case RESULT_DECL:
920   gcc_assert (DECL_CONTEXT (expr) == m_fun->decl);
921   break;

This patch updates the analyzer's longjmp implementation so that it
doesn't attempt to generate svalues for the result_decls when popping
frames, fixing the assertion failure (and presumably fixing "uninit"
false positives in a release build).

Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
Analyzer integration tests shows no regressions.
Pushed to trunk as r13-6749-g430d7d88c1a123.

gcc/analyzer/ChangeLog:
PR analyzer/109094
* region-model.cc (region_model::on_longjmp): Pass false for
new "eval_return_svalue" param of pop_frame.
(region_model::pop_frame): Add new "eval_return_svalue" param and
use it to suppress the call to get_rvalue on the result when
needed by on_longjmp.
* region-model.h (region_model::pop_frame): Add new
"eval_return_svalue" param.

gcc/testsuite/ChangeLog:
PR analyzer/109094
* gcc.dg/analyzer/setjmp-pr109094.c: New test.

Signed-off-by: David Malcolm 
---
 gcc/analyzer/region-model.cc  | 15 ++--
 gcc/analyzer/region-model.h   |  3 +-
 .../gcc.dg/analyzer/setjmp-pr109094.c | 38 +++
 3 files changed, 52 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/analyzer/setjmp-pr109094.c

diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index 56beaa82f95..fb81d43f91b 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -1952,7 +1952,7 @@ region_model::on_longjmp (const gcall *longjmp_call, 
const gcall *setjmp_call,
  setjmp was called.  */
   gcc_assert (get_stack_depth () >= setjmp_stack_depth);
   while (get_stack_depth () > setjmp_stack_depth)
-pop_frame (NULL, NULL, ctxt);
+pop_frame (NULL, NULL, ctxt, false);
 
   gcc_assert (get_stack_depth () == setjmp_stack_depth);
 
@@ -4679,6 +4679,10 @@ region_model::get_current_function () const
If OUT_RESULT is non-null, copy any return value from the frame
into *OUT_RESULT.
 
+   If EVAL_RETURN_SVALUE is false, then don't evaluate the return value.
+   This is for use when unwinding frames e.g. due to longjmp, to suppress
+   erroneously reporting uninitialized return values.
+
Purge the frame region and all its descendent regions.
Convert any pointers that point into such regions into
POISON_KIND_POPPED_STACK svalues.  */
@@ -4686,7 +4690,8 @@ region_model::get_current_function () const
 void
 region_model::pop_frame (tree result_lvalue,
 const svalue **out_result,
-region_model_context *ctxt)
+region_model_context *ctxt,
+bool eval_return_svalue)
 {
   gcc_assert (m_current_frame);
 
@@ -4700,7 +4705,9 @@ region_model::pop_frame (tree result_lvalue,
   tree fndecl = m_current_frame->get_function ()->decl;
   tree result = DECL_RESULT (fndecl);
   const svalue *retval = NULL;
-  if (result && TREE_TYPE (result) != void_type_node)
+  if (result
+  && TREE_TYPE (result) != void_type_node
+  && eval_return_svalue)
 {
   retval = get_rvalue (result, ctxt);
   if (out_result)
@@ -4712,6 +4719,8 @@ region_model::pop_frame (tree result_lvalue,
 
   if (result_lvalue && retval)
 {
+  gcc_assert (eval_return_svalue);
+
   /* Compute result_dst_reg using RESULT_LVALUE *after* popping
 the frame, but before poisoning pointers into the old frame.  */
   const region *result_dst_reg = get_lvalue (result_lvalue, ctxt);
diff --git a/gcc/analyzer/region-model.h b/gcc/analyzer/region-model.h
index 197b5358678..fe3db0b0c98 100644
--- a/gcc/analyzer/region-model.h
+++ b/gcc/analyzer/region-model.h
@@ -341,7 +341,8 @@ class region_model
   function * get_current_function () const;
   void pop_frame (tree result_lvalue,
  const svalue **out_result,
- region_model_context *ctxt);
+ region_model_context *ctxt,
+ bool eval_return_svalue = true);
   int get_stack_depth () const;
   const frame_region *get_frame_at_index (int index) const;
 

[PATCH] c++, v2: Drop TREE_READONLY on vars (possibly) initialized by tls wrapper [PR109164]

2023-03-18 Thread Jakub Jelinek via Gcc-patches
On Sat, Mar 18, 2023 at 01:54:58PM +0100, Jakub Jelinek via Gcc-patches wrote:
> The patch is mostly about DECL_EXTERNAL cases, the others are supposedly
> handled by the var_definition_p code there (or at least I assumed;
> testcases certainly test only DECL_EXTERNAL).
> I guess it could be done in cp_finish_decl, maybe better next to the
>   /* A reference will be modified here, as it is initialized.  */
>   if (! DECL_EXTERNAL (decl)
>   && TREE_READONLY (decl)
>   && TYPE_REF_P (type))
> {
>   was_readonly = 1;
>   TREE_READONLY (decl) = 0;
> }
> spot, but we'd need to export the decl2.cc helpers for it,
> because not all DECL_THREAD_LOCAL_P vars need to be treated that way.
>   if (VAR_P (decl)
>   && CP_DECL_THREAD_LOCAL_P (decl)
>   && var_needs_tls_wrapper (decl)
>   && (!DECL_EXTERNAL (decl) || flag_extern_tls_init))
> TREE_READONLY (decl) = 0;
> where var_needs_tls_wrapper would need to be exported from decl2.cc.
> Though, var_needs_tls_wrapper -> var_defined_without_dynamic_init
> needs
> DECL_NONTRIVIALLY_INITIALIZED_P/DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P,
> so perhaps that is accurate only closer to the end of cp_finish_decl?

Here it is in patch form, tested so far on tls.exp:

2023-03-18  Jakub Jelinek  

PR c++/109164
* cp-tree.h (var_needs_tls_wrapper): Declare.
* decl2.cc (var_needs_tls_wrapper): No longer static.
* decl.cc (cp_finish_decl): Clear TREE_READONLY on TLS variables
for which a TLS wrapper will be needed.

* g++.dg/tls/thread_local13.C: New test.
* g++.dg/tls/thread_local13-aux.cc: New file.
* g++.dg/tls/thread_local14.C: New test.
* g++.dg/tls/thread_local14-aux.cc: New file.

--- gcc/cp/cp-tree.h.jj 2023-03-17 08:37:07.542937058 +0100
+++ gcc/cp/cp-tree.h2023-03-18 16:02:46.771230806 +0100
@@ -6989,6 +6989,7 @@ extern void copy_linkage  (tree, tree);
 extern tree get_guard  (tree);
 extern tree get_guard_cond (tree, bool);
 extern tree set_guard  (tree);
+extern bool var_needs_tls_wrapper  (tree);
 extern tree maybe_get_tls_wrapper_call (tree);
 extern void mark_needed(tree);
 extern bool decl_needed_p  (tree);
--- gcc/cp/decl2.cc.jj  2023-03-17 16:09:01.749244271 +0100
+++ gcc/cp/decl2.cc 2023-03-18 15:48:31.340642324 +0100
@@ -3623,7 +3623,7 @@ var_defined_without_dynamic_init (tree v
 /* Returns true iff VAR is a variable that needs uses to be
wrapped for possible dynamic initialization.  */
 
-static bool
+bool
 var_needs_tls_wrapper (tree var)
 {
   return (!error_operand_p (var)
--- gcc/cp/decl.cc.jj   2023-03-18 15:47:32.198500421 +0100
+++ gcc/cp/decl.cc  2023-03-18 16:00:04.565584266 +0100
@@ -8706,6 +8706,18 @@ cp_finish_decl (tree decl, tree init, bo
  if (!decl_maybe_constant_destruction (decl, type))
TREE_READONLY (decl) = 0;
}
+  else if (VAR_P (decl)
+  && CP_DECL_THREAD_LOCAL_P (decl)
+  && (!DECL_EXTERNAL (decl) || flag_extern_tls_init)
+  && (was_readonly || TREE_READONLY (decl))
+  && var_needs_tls_wrapper (decl))
+   {
+ /* TLS variables need dynamic initialization by the TLS wrapper
+function, we don't want to hoist accesses to it before the
+wrapper.  */
+ was_readonly = 0;
+ TREE_READONLY (decl) = 0;
+   }
 
   make_rtl_for_nonlocal_decl (decl, init, asmspec);
 
--- gcc/testsuite/g++.dg/tls/thread_local13.C.jj2023-03-18 
15:47:50.934228583 +0100
+++ gcc/testsuite/g++.dg/tls/thread_local13.C   2023-03-18 15:47:50.934228583 
+0100
@@ -0,0 +1,21 @@
+// PR c++/109164
+// { dg-do run { target c++11 } }
+// { dg-options "-O2" }
+// { dg-add-options tls }
+// { dg-require-effective-target tls_runtime }
+// { dg-additional-sources "thread_local13-aux.cc" }
+
+struct S { virtual void foo (); int s; };
+extern thread_local S 
+bool bar ();
+
+bool
+baz ()
+{
+  while (1)
+{
+  t.foo ();
+  if (!bar ())
+return false;
+}
+}
--- gcc/testsuite/g++.dg/tls/thread_local13-aux.cc.jj   2023-03-18 
15:47:50.934228583 +0100
+++ gcc/testsuite/g++.dg/tls/thread_local13-aux.cc  2023-03-18 
15:47:50.934228583 +0100
@@ -0,0 +1,35 @@
+// PR c++/109164
+
+struct S { virtual void foo (); int s; };
+extern bool baz ();
+
+void
+S::foo ()
+{
+  if (s != 42)
+__builtin_abort ();
+}
+
+S s;
+
+S &
+qux ()
+{
+  s.s = 42;
+  return s;
+}
+
+thread_local S  = qux ();
+
+bool
+bar ()
+{
+  return false;
+}
+
+int
+main ()
+{
+  if (baz ())
+__builtin_abort ();
+}
--- gcc/testsuite/g++.dg/tls/thread_local14.C.jj2023-03-18 
15:47:50.934228583 +0100
+++ gcc/testsuite/g++.dg/tls/thread_local14.C   2023-03-18 15:47:50.934228583 
+0100
@@ -0,0 +1,19 @@
+// PR c++/109164
+// { dg-do run { target c++11 } }
+// { 

Re: [pushed] c++: constant, array, lambda, template [PR108975]

2023-03-18 Thread Patrick Palka via Gcc-patches
On Fri, 17 Mar 2023, Jason Merrill via Gcc-patches wrote:

> Tested x86_64-pc-linux-gnu, applying to trunk.
> 
> -- 8< --
> 
> When a lambda refers to a constant local variable in the enclosing scope, we
> tentatively capture it, but if we end up pulling out its constant value, we
> go back at the end of the lambda and prune any unneeded captures.  Here
> while parsing the template we decided that the dim capture was unneeded,
> because we folded it away, but then we brought back the use in the template
> trees that try to preserve the source representation with added type info.
> So then when we tried to instantiate that use, we couldn't find what it was
> trying to use, and crashed.
> 
> Fixed by not trying to prune when parsing a template; we'll prune at
> instantiation time.
> 
>   PR c++/108975
> 
> gcc/cp/ChangeLog:
> 
>   * lambda.cc (prune_lambda_captures): Don't bother in a template.
> 
> gcc/testsuite/ChangeLog:
> 
>   * g++.dg/cpp0x/lambda/lambda-const11.C: New test.
> ---
>  gcc/cp/lambda.cc   |  3 +++
>  gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const11.C | 14 ++
>  2 files changed, 17 insertions(+)
>  create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const11.C
> 
> diff --git a/gcc/cp/lambda.cc b/gcc/cp/lambda.cc
> index 212990a21bf..9925209b2ed 100644
> --- a/gcc/cp/lambda.cc
> +++ b/gcc/cp/lambda.cc
> @@ -1760,6 +1760,9 @@ prune_lambda_captures (tree body)
>if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lam) == CPLD_NONE)
>  /* No default captures, and we don't prune explicit captures.  */
>  return;
> +  /* Don't bother pruning in a template, we'll prune at instantiation time.  
> */
> +  if (dependent_type_p (TREE_TYPE (lam)))
> +return;
>  
>hash_map const_vars;
>  
> diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const11.C 
> b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const11.C
> new file mode 100644
> index 000..26af75bf132
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const11.C
> @@ -0,0 +1,14 @@
> +// PR c++/108975
> +// { dg-do compile { target c++11 } }
> +
> +template
> +void f() {
> +  constexpr int dim = 1;
> +  auto l = [&] {
> +int n[dim * 1];
> +  };
> +  // In f, we shouldn't actually capture dim.
> +  static_assert (sizeof(l) == 1, "");
> +}
> +
> +template void f();

Sadly I think more is needed to fix the generic lambda case, we still
crash for:

  template
  void f() {
constexpr int dim = 1;
auto l = [&] (auto) {
  int n[dim * 1];
};
l(0);
// In f, we shouldn't actually capture dim.
static_assert (sizeof(l) == 1, "");
  }

  template void f();

It seems prune_lambda_captures doesn't thoroughly walk the lambda body,
and so fails to find all uses of constant captures such as in 'int n[dim * 1]'
or 'using type = decltype(g())' (in the original testcase the
constant capture use occurred inside an alias declaration).

I guess generic lambdas are special in that their body is always
templated and so fewer constant captures are folded away by instantiation
time.  So they are more sensitive to incomplete walking by
prune_lambda_captures.



Re: [PATCH] c++: Drop TREE_READONLY on vars (possibly) initialized by tls wrapper [PR109164]

2023-03-18 Thread Jakub Jelinek via Gcc-patches
On Sat, Mar 18, 2023 at 08:39:45AM -0400, Jason Merrill wrote:
> On 3/17/23 13:51, Jakub Jelinek wrote:
> > The following two testcases are miscompiled, because we keep TREE_READONLY
> > on the vars even when they are (possibly) dynamically initialized by a TLS
> > wrapper function.  Normally cp_finish_decl drops TREE_READONLY from vars
> > which need dynamic initialization, but for TLS we do this kind of
> > initialization upon every access to those variables.
> 
> Why not handle this case in cp_finish_decl, too?  That is, add
> DECL_THREAD_LOCAL_P to the TREE_STATIC check in

The patch is mostly about DECL_EXTERNAL cases, the others are supposedly
handled by the var_definition_p code there (or at least I assumed;
testcases certainly test only DECL_EXTERNAL).
I guess it could be done in cp_finish_decl, maybe better next to the
  /* A reference will be modified here, as it is initialized.  */
  if (! DECL_EXTERNAL (decl)
  && TREE_READONLY (decl)
  && TYPE_REF_P (type))
{
  was_readonly = 1;
  TREE_READONLY (decl) = 0;
}
spot, but we'd need to export the decl2.cc helpers for it,
because not all DECL_THREAD_LOCAL_P vars need to be treated that way.
  if (VAR_P (decl)
  && CP_DECL_THREAD_LOCAL_P (decl)
  && var_needs_tls_wrapper (decl)
  && (!DECL_EXTERNAL (decl) || flag_extern_tls_init))
TREE_READONLY (decl) = 0;
where var_needs_tls_wrapper would need to be exported from decl2.cc.
Though, var_needs_tls_wrapper -> var_defined_without_dynamic_init
needs
DECL_NONTRIVIALLY_INITIALIZED_P/DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P,
so perhaps that is accurate only closer to the end of cp_finish_decl?

Jakub



Re: [PATCH] c++: Drop TREE_READONLY on vars (possibly) initialized by tls wrapper [PR109164]

2023-03-18 Thread Jason Merrill via Gcc-patches

On 3/17/23 13:51, Jakub Jelinek wrote:

Hi!

The following two testcases are miscompiled, because we keep TREE_READONLY
on the vars even when they are (possibly) dynamically initialized by a TLS
wrapper function.  Normally cp_finish_decl drops TREE_READONLY from vars
which need dynamic initialization, but for TLS we do this kind of
initialization upon every access to those variables.


Why not handle this case in cp_finish_decl, too?  That is, add 
DECL_THREAD_LOCAL_P to the TREE_STATIC check in



  if (var_definition_p
  /* With -fmerge-all-constants, gimplify_init_constructor  
 might add TREE_STATIC to aggregate variables.  */

  && (TREE_STATIC (decl)
  || (flag_merge_constants >= 2
  && AGGREGATE_TYPE_P (type
{
  /* If a TREE_READONLY variable needs initialization   
 at runtime, it is no longer readonly and we need to
 avoid MEM_READONLY_P being set on RTL created for it.  */


?


Keeping them
TREE_READONLY means e.g. PRE can hoist loads from those before loops
which contain the TLS wrapper calls, so we can access the TLS variables
before they are initialized.

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

2023-03-17  Jakub Jelinek  

PR c++/109164
* decl2.cc (get_tls_wrapper_fn): Clear TREE_READONLY on variables for
which a TLS wrapper is added.

* g++.dg/tls/thread_local13.C: New test.
* g++.dg/tls/thread_local13-aux.cc: New file.
* g++.dg/tls/thread_local14.C: New test.
* g++.dg/tls/thread_local14-aux.cc: New file.

--- gcc/cp/decl2.cc.jj  2023-03-07 21:20:31.800491531 +0100
+++ gcc/cp/decl2.cc 2023-03-17 12:20:11.960678291 +0100
@@ -3773,6 +3773,12 @@ get_tls_wrapper_fn (tree var)
DECL_BEFRIENDING_CLASSES (fn) = var;
  
set_global_binding (fn);

+
+  /* The variable now needs dynamic initialization by the wrapper
+function, we don't want to hoist accesses to it before the
+wrapper.  */
+  if (TREE_READONLY (var))
+   TREE_READONLY (var) = 0;
  }
return fn;
  }
--- gcc/testsuite/g++.dg/tls/thread_local13.C.jj2023-03-17 
12:28:24.692427351 +0100
+++ gcc/testsuite/g++.dg/tls/thread_local13.C   2023-03-17 12:30:34.505519746 
+0100
@@ -0,0 +1,21 @@
+// PR c++/109164
+// { dg-do run { target c++11 } }
+// { dg-options "-O2" }
+// { dg-add-options tls }
+// { dg-require-effective-target tls_runtime }
+// { dg-additional-sources "thread_local13-aux.cc" }
+
+struct S { virtual void foo (); int s; };
+extern thread_local S 
+bool bar ();
+
+bool
+baz ()
+{
+  while (1)
+{
+  t.foo ();
+  if (!bar ())
+return false;
+}
+}
--- gcc/testsuite/g++.dg/tls/thread_local13-aux.cc.jj   2023-03-17 
12:28:28.721368058 +0100
+++ gcc/testsuite/g++.dg/tls/thread_local13-aux.cc  2023-03-17 
12:37:53.952070861 +0100
@@ -0,0 +1,35 @@
+// PR c++/109164
+
+struct S { virtual void foo (); int s; };
+extern bool baz ();
+
+void
+S::foo ()
+{
+  if (s != 42)
+__builtin_abort ();
+}
+
+S s;
+
+S &
+qux ()
+{
+  s.s = 42;
+  return s;
+}
+
+thread_local S  = qux ();
+
+bool
+bar ()
+{
+  return false;
+}
+
+int
+main ()
+{
+  if (baz ())
+__builtin_abort ();
+}
--- gcc/testsuite/g++.dg/tls/thread_local14.C.jj2023-03-17 
12:35:48.951905245 +0100
+++ gcc/testsuite/g++.dg/tls/thread_local14.C   2023-03-17 12:49:03.456249628 
+0100
@@ -0,0 +1,19 @@
+// PR c++/109164
+// { dg-do run { target c++11 } }
+// { dg-options "-O2" }
+// { dg-add-options tls }
+// { dg-require-effective-target tls_runtime }
+// { dg-additional-sources "thread_local14-aux.cc" }
+
+extern thread_local const int t;
+bool bar (int);
+
+bool
+baz ()
+{
+  while (1)
+{
+  if (!bar (t))
+return false;
+}
+}
--- gcc/testsuite/g++.dg/tls/thread_local14-aux.cc.jj   2023-03-17 
12:36:58.724881322 +0100
+++ gcc/testsuite/g++.dg/tls/thread_local14-aux.cc  2023-03-17 
12:48:53.914389421 +0100
@@ -0,0 +1,26 @@
+// PR c++/109164
+
+extern bool baz ();
+
+int
+qux ()
+{
+  return 42;
+}
+
+extern thread_local const int t = qux ();
+
+bool
+bar (int x)
+{
+  if (x != 42)
+__builtin_abort ();
+  return false;
+}
+
+int
+main ()
+{
+  if (baz ())
+__builtin_abort ();
+}

Jakub





Re: [PATCH] c++: further -Wdangling-reference refinement [PR107532]

2023-03-18 Thread Jason Merrill via Gcc-patches

On 3/17/23 16:29, Marek Polacek wrote:

Based on ,
it seems like we should treat *any* class with a reference member
as a reference wrapper.  This simplifies the code so I'm happy to
make that change.

The patch, however, does not suppress the warning in

   int i = 42;
   auto const& v = std::get<0>(std::tuple(i));


Why not?  tuple has an int& member, doesn't it?  Do we need to 
look into bases as well?



Since reference_like_class_p already checks for std::pair
maybe it could also check for std::tuple.  I don't know if we
want to make that change in GCC 13, or move -Wdangling-reference to
-Wextra for GCC 13 and perhaps move it back to -Wall in GCC 14.

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

PR c++/107532

gcc/cp/ChangeLog:

* call.cc (reference_like_class_p): Don't look for a constructor.

gcc/testsuite/ChangeLog:

* g++.dg/warn/Wdangling-reference11.C: New test.
---
  gcc/cp/call.cc| 35 +++
  .../g++.dg/warn/Wdangling-reference11.C   | 23 
  2 files changed, 35 insertions(+), 23 deletions(-)
  create mode 100644 gcc/testsuite/g++.dg/warn/Wdangling-reference11.C

diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index c01e7b82457..00d56a157b6 100644
--- a/gcc/cp/call.cc
+++ b/gcc/cp/call.cc
@@ -13781,8 +13781,9 @@ std_pair_ref_ref_p (tree t)
  
  /* Return true if a class CTYPE is either std::reference_wrapper or

 std::ref_view, or a reference wrapper class.  We consider a class
-   a reference wrapper class if it has a reference member and a
-   constructor taking the same reference type.  */
+   a reference wrapper class if it has a reference member.  We no
+   longer check that it has a constructor taking the same reference type
+   since that approach still generated too many false positives.  */
  
  static bool

  reference_like_class_p (tree ctype)
@@ -13798,31 +13799,19 @@ reference_like_class_p (tree ctype)
if (decl_in_std_namespace_p (tdecl))
  {
tree name = DECL_NAME (tdecl);
-  return (name
- && (id_equal (name, "reference_wrapper")
- || id_equal (name, "span")
- || id_equal (name, "ref_view")));
+  if (name
+ && (id_equal (name, "reference_wrapper")
+ || id_equal (name, "span")
+ || id_equal (name, "ref_view")))
+   return true;
  }
for (tree fields = TYPE_FIELDS (ctype);
 fields;
 fields = DECL_CHAIN (fields))
-{
-  if (TREE_CODE (fields) != FIELD_DECL || DECL_ARTIFICIAL (fields))
-   continue;
-  tree type = TREE_TYPE (fields);
-  if (!TYPE_REF_P (type))
-   continue;
-  /* OK, the field is a reference member.  Do we have a constructor
-taking its type?  */
-  for (tree fn : ovl_range (CLASSTYPE_CONSTRUCTORS (ctype)))
-   {
- tree args = FUNCTION_FIRST_USER_PARMTYPE (fn);
- if (args
- && same_type_p (TREE_VALUE (args), type)
- && TREE_CHAIN (args) == void_list_node)
-   return true;
-   }
-}
+if (TREE_CODE (fields) == FIELD_DECL
+   && !DECL_ARTIFICIAL (fields)
+   && TYPE_REF_P (TREE_TYPE (fields)))
+  return true;
return false;
  }
  
diff --git a/gcc/testsuite/g++.dg/warn/Wdangling-reference11.C b/gcc/testsuite/g++.dg/warn/Wdangling-reference11.C

new file mode 100644
index 000..667618e7196
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wdangling-reference11.C
@@ -0,0 +1,23 @@
+// PR c++/107532
+// { dg-do compile { target c++11 } }
+// { dg-options "-Wdangling-reference" }
+
+struct R
+{
+int& r;
+int& get() { return r; }
+int&& rget() { return static_cast(r); }
+};
+
+int main()
+{
+int i = 42;
+int& l = R{i}.get(); // { dg-bogus "dangling reference" }
+int const& cl = R{i}.get(); // { dg-bogus "dangling reference" }
+int&& r = R{i}.rget(); // { dg-bogus "dangling reference" }
+int const&& cr = R{i}.rget(); // { dg-bogus "dangling reference" }
+(void) l;
+(void) r;
+(void) cr;
+(void) cl;
+}

base-commit: ae7190e345a8d80310835cb83b3b41ef2aeb0d37




Re: [committed] libstdc++: Add const to hash>::operator() [PR109165]

2023-03-18 Thread Jonathan Wakely via Gcc-patches
On Sat, 18 Mar 2023 at 00:49, Nathaniel Shead wrote:

> On Sat, Mar 18, 2023 at 7:36 AM Jonathan Wakely via Libstdc++
>  wrote:
> >
> > Tested x86_64-linux. Pushed to trunk. gcc-12 backport needed too.
> >
> > -- >8 --
> >
> > libstdc++-v3/ChangeLog:
> >
> > PR libstdc++/109165
> > * include/std/coroutine (hash<>::operator()): Add const.
> > * testsuite/18_support/coroutines/hash.cc: New test.
> > ---
> >  libstdc++-v3/include/std/coroutine|  2 +-
> >  .../testsuite/18_support/coroutines/hash.cc   | 22 +++
> >  2 files changed, 23 insertions(+), 1 deletion(-)
> >  create mode 100644 libstdc++-v3/testsuite/18_support/coroutines/hash.cc
> >
> > diff --git a/libstdc++-v3/include/std/coroutine
> b/libstdc++-v3/include/std/coroutine
> > index f6e65566f10..b0ca18949db 100644
> > --- a/libstdc++-v3/include/std/coroutine
> > +++ b/libstdc++-v3/include/std/coroutine
> > @@ -345,7 +345,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> >  struct hash>
> >  {
> >size_t
> > -  operator()(const coroutine_handle<_Promise>& __h) noexcept
> > +  operator()(const coroutine_handle<_Promise>& __h) const noexcept
> >{
> > return reinterpret_cast(__h.address());
> >}
> > diff --git a/libstdc++-v3/testsuite/18_support/coroutines/hash.cc
> b/libstdc++-v3/testsuite/18_support/coroutines/hash.cc
> > new file mode 100644
> > index 000..68e5e640477
> > --- /dev/null
> > +++ b/libstdc++-v3/testsuite/18_support/coroutines/hash.cc
> > @@ -0,0 +1,22 @@
> > +// { dg-options "-std=gnu++2a" }
> > +// { dg-do run { target c++2a } }
> > +
> > +#include 
> > +#include 
> > +
> > +void
> > +test01()
> > +{
> > +  std::hash h;
> > +  std::size_t v = h(std::noop_coroutine());
> > +
> > +  const auto& ch = h;
> > +  std::size_t v2 = h(std::noop_coroutine()); // PR libstdc++/109165
>
> Is this supposed to be `std::size_t v2 = ch(...)`?
>
>
Doh! Yes, thanks. Fixed by the attached change.

Tested x86_64-linux, pushed to trunk.
commit 9b83d4755a7da02f25788fce14bec949e7045f8f
Author: Jonathan Wakely 
Date:   Fri Mar 17 11:39:55 2023

libstdc++: Fix test for hash>::operator() [PR109165]

libstdc++-v3/ChangeLog:

PR libstdc++/109165
* testsuite/18_support/coroutines/hash.cc: Use const object
in second call.

diff --git a/libstdc++-v3/testsuite/18_support/coroutines/hash.cc 
b/libstdc++-v3/testsuite/18_support/coroutines/hash.cc
index 68e5e640477..81b68f8246a 100644
--- a/libstdc++-v3/testsuite/18_support/coroutines/hash.cc
+++ b/libstdc++-v3/testsuite/18_support/coroutines/hash.cc
@@ -7,11 +7,12 @@
 void
 test01()
 {
+  auto coro = std::noop_coroutine();
   std::hash h;
-  std::size_t v = h(std::noop_coroutine());
+  std::size_t v = h(coro);
 
   const auto& ch = h;
-  std::size_t v2 = h(std::noop_coroutine()); // PR libstdc++/109165
+  std::size_t v2 = ch(coro); // PR libstdc++/109165
 
   VERIFY( v2 == v );
 }


[PATCH] or1k: Do not clear existing FPU exceptions before updating

2023-03-18 Thread Stafford Horne via Gcc-patches
We should always carry the exceptions forward.  This bug was found when
working on testing glibc math tests, many tests were failing with
Overflow and Underflow flags not set.  This was traced to here.

libgcc/ChangeLog:

* config/or1k/sfp-machine.h (FP_HANDLE_EXCEPTIONS): Remove
statement clearing existing exceptions.
---
 libgcc/config/or1k/sfp-machine.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/libgcc/config/or1k/sfp-machine.h b/libgcc/config/or1k/sfp-machine.h
index 162c6bc5326..c804270fb3c 100644
--- a/libgcc/config/or1k/sfp-machine.h
+++ b/libgcc/config/or1k/sfp-machine.h
@@ -73,7 +73,6 @@ do {  
\
 do {   \
   if (__builtin_expect (_fex, 0))  \
 {  \
-  _fpcsr &= ~FP_EX_ALL;\
   _fpcsr |= _fex;  \
   __asm__ volatile ("l.mtspr r0,%0,20" : : "r" (_fpcsr));  \
 }  \
-- 
2.39.1



Re: [PATCH] [testsuite] test for weak_undefined support and add options

2023-03-18 Thread Mike Stump via Gcc-patches
On Mar 15, 2023, at 11:40 PM, Alexandre Oliva  wrote:
> 
> On Mar 15, 2023, Alexandre Oliva  wrote:
> 
>> Regstrapped on ppc64-linux-gnu.  Also tested (with gcc-12) on multiple
>> *-vxworks7r2 targets (arm, aarch64, ppc64, x86, x86_64).  Ok to install?
> 
> Further testing revealed a problem in my attempted use of lappend in
> aapcs64.exp, in the previous version of the patch.  Fixed in this one,
> retested on aarch64-vxworks7r2.  Ok to install?

Ok.