Re: [PATCH v3 1/3] c++: Track lifetimes in constant evaluation [PR70331,PR96630,PR98675]

2023-07-16 Thread Nathaniel Shead via Gcc-patches
On Fri, Jul 14, 2023 at 11:16:58AM -0400, Jason Merrill wrote:
> On 6/30/23 23:28, Nathaniel Shead via Gcc-patches wrote:
> > This adds rudimentary lifetime tracking in C++ constexpr contexts,
> 
> Thanks!
> 
> I'm not seeing either a copyright assignment or DCO certification for you;
> please see https://gcc.gnu.org/contribute.html#legal for more information.
> 
> > diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
> > index cca0435bafc..bc59b4aab67 100644
> > --- a/gcc/cp/constexpr.cc
> > +++ b/gcc/cp/constexpr.cc
> > @@ -1188,7 +1190,12 @@ public:
> >   if (!already_in_map && modifiable)
> > modifiable->add (t);
> > }
> > -  void remove_value (tree t) { values.remove (t); }
> > +  void remove_value (tree t)
> > +  {
> > +if (DECL_P (t))
> > +  outside_lifetime.add (t);
> > +values.remove (t);
> 
> What if, instead of removing the variable from one hash table and adding it
> to another, we change the value to, say, void_node?

I have another patch I'm working on after this which does seem to
require the overlapping tables to properly catch uses of aggregates
while they are still being constructed (i.e. before their lifetime has
begun), as part of PR c++/109518. In that case the 'values' map contains
the CONSTRUCTOR node for the aggregate, but it also needs to be in
'outside_lifetime'. I could also explore solving this another way
however if you prefer.

(I also have vague dreams of at some point making this a map to the
location that the object was destroyed for more context in the error
messages, but I'm not yet sure if that's feasible or will actually be
all that helpful so I'm happy to forgo that.)

> > + /* Also don't cache a call if we return a pointer to an expired
> > +value.  */
> > + if (cacheable && (cp_walk_tree_without_duplicates
> > +   (, find_expired_values,
> > +>global->outside_lifetime)))
> > +   cacheable = false;
> 
> I think we need to reconsider cacheability in general; I think we only want
> to cache calls that are themselves valid constant expressions, in that the
> return value is a "permitted result of a constant expression"
> (https://eel.is/c++draft/expr.const#13).  A pointer to an automatic variable
> is not, whether or not it is currently within its lifetime.
> 
> That is, only cacheable if reduced_constant_expression_p (result).
> 
> I'm experimenting with this now, you don't need to mess with it.

Thanks! I agree, that sounds a lot nicer; I definitely ran into caching
problems in a few different ways when I was developing this patch, and
this approach sounds like it would have avoided that.

> > @@ -7085,7 +7138,7 @@ cxx_eval_constant_expression (const constexpr_ctx 
> > *ctx, tree t,
> >   case PARM_DECL:
> > if (lval && !TYPE_REF_P (TREE_TYPE (t)))
> > /* glvalue use.  */;
> > -  else if (tree v = ctx->global->get_value (r))
> > +  else if (tree v = ctx->global->get_value (t))
> 
> I agree with this change, but it doesn't have any actual effect, right? I'll
> go ahead and apply it separately.

Yup, it was just a drive-by cleanup I made while trying to understand
this part of the code. Thanks.

> > @@ -7328,17 +7386,28 @@ cxx_eval_constant_expression (const constexpr_ctx 
> > *ctx, tree t,
> > auto_vec cleanups;
> > vec *prev_cleanups = ctx->global->cleanups;
> > ctx->global->cleanups = 
> > -   r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
> > +
> > +   auto_vec save_exprs;
> 
> Now that we're going to track temporaries for each full-expression, I think
> we shouldn't also need to track them for loops and calls.

Good point, I didn't think about that. I'm now bootstrapping/regtesting
a modification of this patch that removes the tracking in loops and
calls, but an initial run of the dg.exp testsuite is promising. It also
fixes an issue I just noticed where I don't actually check lifetimes of
empty types.

I'll send out a new version when that finishes.


[PATCH v3 3/3] c++: Improve location information in constant evaluation

2023-06-30 Thread Nathaniel Shead via Gcc-patches
This patch updates 'input_location' during constant evaluation to ensure
that errors in subexpressions that lack location information still
provide accurate diagnostics.

By itself this change causes some small regressions in diagnostic
quality for circumstances where errors used 'input_location' but the
location of the parent subexpression doesn't make sense, so this patch
also includes a couple of other small diagnostic improvements to improve
the most egregious cases.

gcc/cp/ChangeLog:

* constexpr.cc (modifying_const_object_error): Find the source
location of the const object's declaration.
(cxx_eval_store_expression): Fall back to the location of the
target object when evaluating initialiser.
(cxx_eval_constant_expression): Update input_location to the location
of the currently evaluated expression.

libstdc++-v3/ChangeLog:

* testsuite/25_algorithms/equal/constexpr_neg.cc: Update diagnostic
locations.
* testsuite/26_numerics/gcd/105844.cc: Likewise.
* testsuite/26_numerics/lcm/105844.cc: Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/cpp0x/constexpr-48089.C: Update diagnostic locations.
* g++.dg/cpp0x/constexpr-70323.C: Likewise.
* g++.dg/cpp0x/constexpr-70323a.C: Likewise.
* g++.dg/cpp0x/constexpr-delete2.C: Likewise.
* g++.dg/cpp0x/constexpr-diag3.C: Likewise.
* g++.dg/cpp0x/constexpr-ice20.C: Likewise.
* g++.dg/cpp0x/constexpr-recursion.C: Likewise.
* g++.dg/cpp0x/overflow1.C: Likewise.
* g++.dg/cpp1y/constexpr-89285.C: Likewise.
* g++.dg/cpp1y/constexpr-89481.C: Likewise.
* g++.dg/cpp1y/constexpr-lifetime1.C: Likewise.
* g++.dg/cpp1y/constexpr-lifetime2.C: Likewise.
* g++.dg/cpp1y/constexpr-lifetime3.C: Likewise.
* g++.dg/cpp1y/constexpr-lifetime4.C: Likewise.
* g++.dg/cpp1y/constexpr-lifetime5.C: Likewise.
* g++.dg/cpp1y/constexpr-tracking-const14.C: Likewise.
* g++.dg/cpp1y/constexpr-tracking-const16.C: Likewise.
* g++.dg/cpp1y/constexpr-tracking-const18.C: Likewise.
* g++.dg/cpp1y/constexpr-tracking-const19.C: Likewise.
* g++.dg/cpp1y/constexpr-tracking-const21.C: Likewise.
* g++.dg/cpp1y/constexpr-tracking-const22.C: Likewise.
* g++.dg/cpp1y/constexpr-tracking-const3.C: Likewise.
* g++.dg/cpp1y/constexpr-tracking-const4.C: Likewise.
* g++.dg/cpp1y/constexpr-tracking-const7.C: Likewise.
* g++.dg/cpp1y/constexpr-union5.C: Likewise.
* g++.dg/cpp1y/pr68180.C: Likewise.
* g++.dg/cpp1z/constexpr-lambda6.C: Likewise.
* g++.dg/cpp1z/constexpr-lambda8.C: Likewise.
* g++.dg/cpp2a/bit-cast11.C: Likewise.
* g++.dg/cpp2a/bit-cast12.C: Likewise.
* g++.dg/cpp2a/bit-cast14.C: Likewise.
* g++.dg/cpp2a/constexpr-98122.C: Likewise.
* g++.dg/cpp2a/constexpr-dynamic17.C: Likewise.
* g++.dg/cpp2a/constexpr-init1.C: Likewise.
* g++.dg/cpp2a/constexpr-new12.C: Likewise.
* g++.dg/cpp2a/constexpr-new3.C: Likewise.
* g++.dg/cpp2a/constinit10.C: Likewise.
* g++.dg/cpp2a/is-corresponding-member4.C: Likewise.
* g++.dg/ext/constexpr-vla2.C: Likewise.
* g++.dg/ext/constexpr-vla3.C: Likewise.
* g++.dg/ubsan/pr63956.C: Likewise.

Signed-off-by: Nathaniel Shead 
---
 gcc/cp/constexpr.cc   | 46 ++-
 gcc/testsuite/g++.dg/cpp0x/constexpr-48089.C  | 10 ++--
 gcc/testsuite/g++.dg/cpp0x/constexpr-70323.C  |  8 ++--
 gcc/testsuite/g++.dg/cpp0x/constexpr-70323a.C |  8 ++--
 .../g++.dg/cpp0x/constexpr-delete2.C  |  5 +-
 gcc/testsuite/g++.dg/cpp0x/constexpr-diag3.C  |  2 +-
 gcc/testsuite/g++.dg/cpp0x/constexpr-ice20.C  |  1 +
 .../g++.dg/cpp0x/constexpr-recursion.C|  6 +--
 gcc/testsuite/g++.dg/cpp0x/overflow1.C|  2 +-
 gcc/testsuite/g++.dg/cpp1y/constexpr-89285.C  |  5 +-
 gcc/testsuite/g++.dg/cpp1y/constexpr-89481.C  |  3 +-
 .../g++.dg/cpp1y/constexpr-lifetime1.C|  1 +
 .../g++.dg/cpp1y/constexpr-lifetime2.C|  4 +-
 .../g++.dg/cpp1y/constexpr-lifetime3.C|  4 +-
 .../g++.dg/cpp1y/constexpr-lifetime4.C|  2 +-
 .../g++.dg/cpp1y/constexpr-lifetime5.C|  4 +-
 .../g++.dg/cpp1y/constexpr-tracking-const14.C |  3 +-
 .../g++.dg/cpp1y/constexpr-tracking-const16.C |  3 +-
 .../g++.dg/cpp1y/constexpr-tracking-const18.C |  4 +-
 .../g++.dg/cpp1y/constexpr-tracking-const19.C |  4 +-
 .../g++.dg/cpp1y/constexpr-tracking-const21.C |  4 +-
 .../g++.dg/cpp1y/constexpr-tracking-const22.C |  4 +-
 .../g++.dg/cpp1y/constexpr-tracking-const3.C  |  3 +-
 .../g++.dg/cpp1y/constexpr-tracking-const4.C  |  3 +-
 .../g++.dg/cpp1y/constexpr-tracking-const7.C  |  3 +-
 gcc/testsuite/g++.dg/cpp1y/constexpr-union5.C |  4 +-
 gcc/testsuite/g++.dg/cpp1y/pr68180.C  |  4 +-
 .../g++.dg/cpp1z/constexpr-lambda6.C  |  4 +-
 .../g++.dg/cpp1z/constexpr

[PATCH v3 2/3] c++: Improve constexpr error for dangling local variables

2023-06-30 Thread Nathaniel Shead via Gcc-patches
Currently, when typeck discovers that a return statement will refer to a
local variable it rewrites to return a null pointer. This causes the
error messages for using the return value in a constant expression to be
unhelpful, especially for reference return values.

This patch removes this "optimisation". Relying on this raises a warning
by default and causes UB anyway, so there should be no issue in doing
so. We also suppress additional warnings from later passes that detect
this as a dangling pointer, since we've already indicated this anyway.

gcc/cp/ChangeLog:

* semantics.cc (finish_return_stmt): Suppress dangling pointer
reporting on return statement if already reported.
* typeck.cc (check_return_expr): Don't set return expression to
zero for dangling addresses.

gcc/testsuite/ChangeLog:

* g++.dg/cpp1y/constexpr-lifetime5.C: Test reported message is
correct.
* g++.dg/warn/Wreturn-local-addr-6.C: Remove check for return
value optimisation.

Signed-off-by: Nathaniel Shead 
---
 gcc/cp/semantics.cc  | 5 -
 gcc/cp/typeck.cc | 5 +++--
 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime5.C | 4 ++--
 gcc/testsuite/g++.dg/warn/Wreturn-local-addr-6.C | 3 ---
 4 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 8fb47fd179e..107407de513 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -1260,7 +1260,10 @@ finish_return_stmt (tree expr)
 
   r = build_stmt (input_location, RETURN_EXPR, expr);
   if (no_warning)
-suppress_warning (r, OPT_Wreturn_type);
+{
+  suppress_warning (r, OPT_Wreturn_type);
+  suppress_warning (r, OPT_Wdangling_pointer_);
+}
   r = maybe_cleanup_point_expr_void (r);
   r = add_stmt (r);
 
diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
index 859b133a18d..47233b3b717 100644
--- a/gcc/cp/typeck.cc
+++ b/gcc/cp/typeck.cc
@@ -11273,8 +11273,9 @@ check_return_expr (tree retval, bool *no_warning)
   else if (!processing_template_decl
   && maybe_warn_about_returning_address_of_local (retval, loc)
   && INDIRECT_TYPE_P (valtype))
-   retval = build2 (COMPOUND_EXPR, TREE_TYPE (retval), retval,
-build_zero_cst (TREE_TYPE (retval)));
+   /* Suppress the Wdangling-pointer warning in the return statement
+  that would otherwise occur.  */
+   *no_warning = true;
 }
 
   /* A naive attempt to reduce the number of -Wdangling-reference false
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime5.C 
b/gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime5.C
index a4bc71d890a..ad3ef579f63 100644
--- a/gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime5.C
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime5.C
@@ -1,11 +1,11 @@
 // { dg-do compile { target c++14 } }
 // { dg-options "-Wno-return-local-addr" }
 
-constexpr const int& id(int x) { return x; }
+constexpr const int& id(int x) { return x; }  // { dg-message "note: declared 
here" }
 
 constexpr bool test() {
   const int& y = id(3);
   return y == 3;
 }
 
-constexpr bool x = test();  // { dg-error "" }
+constexpr bool x = test();  // { dg-error "accessing object outside its 
lifetime" }
diff --git a/gcc/testsuite/g++.dg/warn/Wreturn-local-addr-6.C 
b/gcc/testsuite/g++.dg/warn/Wreturn-local-addr-6.C
index fae8b7e766f..ec8e241d83e 100644
--- a/gcc/testsuite/g++.dg/warn/Wreturn-local-addr-6.C
+++ b/gcc/testsuite/g++.dg/warn/Wreturn-local-addr-6.C
@@ -24,6 +24,3 @@ return_addr_local_as_intref (void)
 
   return (const intptr_t&)a;   // { dg-warning "\\\[-Wreturn-local-addr]" } */
 }
-
-/* Verify that the return value has been replaced with zero:
-  { dg-final { scan-tree-dump-times "return 0;" 2 "optimized" } } */
-- 
2.41.0



[PATCH v3 1/3] c++: Track lifetimes in constant evaluation [PR70331,PR96630,PR98675]

2023-06-30 Thread Nathaniel Shead via Gcc-patches
This adds rudimentary lifetime tracking in C++ constexpr contexts,
allowing the compiler to report errors with using values after their
backing has gone out of scope. We don't yet handle other ways of
accessing values outside their lifetime (e.g. following explicit
destructor calls).

PR c++/96630
PR c++/98675
PR c++/70331

gcc/cp/ChangeLog:

* constexpr.cc (constexpr_global_ctx::remove_value): Mark value as
outside lifetime.
(find_expired_values): New function.
(outside_lifetime_error): New function.
(cxx_eval_call_expression): Don't cache calls that return references to
values outside their lifetime.
(cxx_eval_constant_expression): Add checks for out-of-lifetime values.
Forget local variables at end of bind expressions, and temporaries
after cleanup points.

gcc/testsuite/ChangeLog:

* g++.dg/cpp1y/constexpr-lifetime1.C: New test.
* g++.dg/cpp1y/constexpr-lifetime2.C: New test.
* g++.dg/cpp1y/constexpr-lifetime3.C: New test.
* g++.dg/cpp1y/constexpr-lifetime4.C: New test.
* g++.dg/cpp1y/constexpr-lifetime5.C: New test.

Signed-off-by: Nathaniel Shead 
---
 gcc/cp/constexpr.cc   | 112 ++
 .../g++.dg/cpp1y/constexpr-lifetime1.C|  13 ++
 .../g++.dg/cpp1y/constexpr-lifetime2.C|  20 
 .../g++.dg/cpp1y/constexpr-lifetime3.C|  13 ++
 .../g++.dg/cpp1y/constexpr-lifetime4.C|  11 ++
 .../g++.dg/cpp1y/constexpr-lifetime5.C|  11 ++
 6 files changed, 160 insertions(+), 20 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime1.C
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime2.C
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime3.C
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime4.C
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime5.C

diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index cca0435bafc..bc59b4aab67 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -1165,6 +1165,8 @@ public:
   hash_set *modifiable;
   /* Number of heap VAR_DECL deallocations.  */
   unsigned heap_dealloc_count;
+  /* Values that are not within their lifetime.  */
+  hash_set outside_lifetime;
   /* Constructor.  */
   constexpr_global_ctx ()
 : constexpr_ops_count (0), cleanups (NULL), modifiable (nullptr),
@@ -1188,7 +1190,12 @@ public:
 if (!already_in_map && modifiable)
   modifiable->add (t);
   }
-  void remove_value (tree t) { values.remove (t); }
+  void remove_value (tree t)
+  {
+if (DECL_P (t))
+  outside_lifetime.add (t);
+values.remove (t);
+  }
 };
 
 /* Helper class for constexpr_global_ctx.  In some cases we want to avoid
@@ -2509,6 +2516,22 @@ cxx_eval_dynamic_cast_fn (const constexpr_ctx *ctx, tree 
call,
   return cp_build_addr_expr (obj, complain);
 }
 
+/* Look for expired values in the expression *TP, called through
+   cp_walk_tree.  DATA is ctx->global->outside_lifetime.  */
+
+static tree
+find_expired_values (tree *tp, int *walk_subtrees, void *data)
+{
+  hash_set *outside_lifetime = (hash_set *) data;
+
+  if (TYPE_P (*tp))
+*walk_subtrees = 0;
+  else if (outside_lifetime->contains (*tp))
+return *tp;
+
+  return NULL_TREE;
+}
+
 /* Data structure used by replace_decl and replace_decl_r.  */
 
 struct replace_decl_data
@@ -3160,10 +3183,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree 
t,
  for (tree save_expr : save_exprs)
ctx->global->remove_value (save_expr);
 
- /* Remove the parms/result from the values map.  Is it worth
-bothering to do this when the map itself is only live for
-one constexpr evaluation?  If so, maybe also clear out
-other vars from call, maybe in BIND_EXPR handling?  */
+ /* Remove the parms/result from the values map.  */
  ctx->global->remove_value (res);
  for (tree parm = parms; parm; parm = TREE_CHAIN (parm))
ctx->global->remove_value (parm);
@@ -3210,13 +3230,20 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, 
tree t,
cacheable = false;
}
 
-   /* Rewrite all occurrences of the function's RESULT_DECL with the
-  current object under construction.  */
-   if (!*non_constant_p && ctx->object
-   && CLASS_TYPE_P (TREE_TYPE (res))
-   && !is_empty_class (TREE_TYPE (res)))
- if (replace_decl (, res, ctx->object))
-   cacheable = false;
+ /* Also don't cache a call if we return a pointer to an expired
+value.  */
+ if (cacheable && (cp_walk_tree_without_duplicates
+   (, find_expired_values,
+>global->outside_lifetime)))
+   cache

[PATCH v3 0/3] c++: Track lifetimes in constant evaluation [PR70331,...]

2023-06-30 Thread Nathaniel Shead via Gcc-patches
This is an update of the patch series at
https://gcc.gnu.org/pipermail/gcc-patches/2023-March/614811.html

Changes since v2:

- Use a separate 'hash_set' to track expired variables instead of
  adding a flag to 'lang_decl_base'.
- Use 'iloc_sentinel' to propagate location information down to
  subexpressions instead of manually saving and falling back to a
  parent expression's location.
- Update more tests with improved error location information.

Bootstrapped and regtested on x86_64-pc-linux-gnu.

---

Nathaniel Shead (3):
  c++: Track lifetimes in constant evaluation [PR70331,PR96630,PR98675]
  c++: Improve constexpr error for dangling local variables
  c++: Improve location information in constant evaluation

 gcc/cp/constexpr.cc   | 158 +++---
 gcc/cp/semantics.cc   |   5 +-
 gcc/cp/typeck.cc  |   5 +-
 gcc/testsuite/g++.dg/cpp0x/constexpr-48089.C  |  10 +-
 gcc/testsuite/g++.dg/cpp0x/constexpr-70323.C  |   8 +-
 gcc/testsuite/g++.dg/cpp0x/constexpr-70323a.C |   8 +-
 .../g++.dg/cpp0x/constexpr-delete2.C  |   5 +-
 gcc/testsuite/g++.dg/cpp0x/constexpr-diag3.C  |   2 +-
 gcc/testsuite/g++.dg/cpp0x/constexpr-ice20.C  |   1 +
 .../g++.dg/cpp0x/constexpr-recursion.C|   6 +-
 gcc/testsuite/g++.dg/cpp0x/overflow1.C|   2 +-
 gcc/testsuite/g++.dg/cpp1y/constexpr-89285.C  |   5 +-
 gcc/testsuite/g++.dg/cpp1y/constexpr-89481.C  |   3 +-
 .../g++.dg/cpp1y/constexpr-lifetime1.C|  14 ++
 .../g++.dg/cpp1y/constexpr-lifetime2.C|  20 +++
 .../g++.dg/cpp1y/constexpr-lifetime3.C|  13 ++
 .../g++.dg/cpp1y/constexpr-lifetime4.C|  11 ++
 .../g++.dg/cpp1y/constexpr-lifetime5.C|  11 ++
 .../g++.dg/cpp1y/constexpr-tracking-const14.C |   3 +-
 .../g++.dg/cpp1y/constexpr-tracking-const16.C |   3 +-
 .../g++.dg/cpp1y/constexpr-tracking-const18.C |   4 +-
 .../g++.dg/cpp1y/constexpr-tracking-const19.C |   4 +-
 .../g++.dg/cpp1y/constexpr-tracking-const21.C |   4 +-
 .../g++.dg/cpp1y/constexpr-tracking-const22.C |   4 +-
 .../g++.dg/cpp1y/constexpr-tracking-const3.C  |   3 +-
 .../g++.dg/cpp1y/constexpr-tracking-const4.C  |   3 +-
 .../g++.dg/cpp1y/constexpr-tracking-const7.C  |   3 +-
 gcc/testsuite/g++.dg/cpp1y/constexpr-union5.C |   4 +-
 gcc/testsuite/g++.dg/cpp1y/pr68180.C  |   4 +-
 .../g++.dg/cpp1z/constexpr-lambda6.C  |   4 +-
 .../g++.dg/cpp1z/constexpr-lambda8.C  |   5 +-
 gcc/testsuite/g++.dg/cpp2a/bit-cast11.C   |  10 +-
 gcc/testsuite/g++.dg/cpp2a/bit-cast12.C   |  10 +-
 gcc/testsuite/g++.dg/cpp2a/bit-cast14.C   |  14 +-
 gcc/testsuite/g++.dg/cpp2a/constexpr-98122.C  |   4 +-
 .../g++.dg/cpp2a/constexpr-dynamic17.C|   5 +-
 gcc/testsuite/g++.dg/cpp2a/constexpr-init1.C  |   5 +-
 gcc/testsuite/g++.dg/cpp2a/constexpr-new12.C  |   6 +-
 gcc/testsuite/g++.dg/cpp2a/constexpr-new3.C   |  10 +-
 gcc/testsuite/g++.dg/cpp2a/constinit10.C  |   5 +-
 .../g++.dg/cpp2a/is-corresponding-member4.C   |   4 +-
 gcc/testsuite/g++.dg/ext/constexpr-vla2.C |   4 +-
 gcc/testsuite/g++.dg/ext/constexpr-vla3.C |   4 +-
 gcc/testsuite/g++.dg/ubsan/pr63956.C  |  23 +--
 .../g++.dg/warn/Wreturn-local-addr-6.C|   3 -
 .../25_algorithms/equal/constexpr_neg.cc  |   7 +-
 .../testsuite/26_numerics/gcd/105844.cc   |  10 +-
 .../testsuite/26_numerics/lcm/105844.cc   |  14 +-
 48 files changed, 330 insertions(+), 143 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime1.C
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime2.C
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime3.C
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime4.C
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime5.C

-- 
2.41.0



[PATCH v2 3/3] c++: Improve location information in constexpr evaluation

2023-06-30 Thread Nathaniel Shead via Gcc-patches
On Fri, Jun 23, 2023 at 01:09:14PM -0400, Patrick Palka wrote:
> On Wed, 29 Mar 2023, Nathaniel Shead via Gcc-patches wrote:
> 
> > This patch caches the current expression's location information in the
> > constexpr_global_ctx struct, which allows subexpressions that have lost
> > location information to still provide accurate diagnostics. Also
> > rewrites a number of 'error' calls as 'error_at' to provide more
> > specific location information.
> > 
> > The primary effect of this change is that many errors within evaluation
> > of a constexpr function will now point at the offending expression (with
> > expansion tracing information) rather than just the outermost call.
> 
> This seems like a great improvement!
> 
> In other parts of the frontend, e.g. during substitution from
> tsubst_expr or tsubst_copy_and_build, we do something similar by
> setting/restoring input_location directly.  (We've since added the RAII
> class iloc_sentinel for this.)  I wonder if that'd be preferable here?

I didn't consider that; I've given it a try and I think it's nicer.
Doing it this way also updated a number of 'error' calls that I hadn't
fixed up in this version; generally this meant nicer error messages, but
I had to override it for a couple of cases where I felt the errors it
raised were worse (by adding context that made no sense).

I'm still bootstrapping/regtesting but I'll send out an updated version
of this sometime tomorrow when it's done. Thanks!

> > 
> > gcc/cp/ChangeLog:
> > 
> > * constexpr.cc (constexpr_global_ctx): New field for cached
> > tree location, defaulting to input_location.
> > (cxx_eval_internal_function): Fall back to ctx->global->loc
> > rather than input_location.
> > (modifying_const_object_error): Likewise.
> > (cxx_eval_dynamic_cast_fn): Likewise.
> > (eval_and_check_array_index): Likewise.
> > (cxx_eval_array_reference): Likewise.
> > (cxx_eval_bit_field_ref): Likewise.
> > (cxx_eval_component_reference): Likewise.
> > (cxx_eval_indirect_ref): Likewise.
> > (cxx_eval_store_expression): Likewise.
> > (cxx_eval_increment_expression): Likewise.
> > (cxx_eval_loop_expr): Likewise.
> > (cxx_eval_binary_expression): Likewise.
> > (cxx_eval_constant_expression): Cache location of trees for use
> > in errors, and prefer it instead of input_location.
> > 
> > gcc/testsuite/ChangeLog:
> > 
> > * g++.dg/cpp0x/constexpr-48089.C: Updated diagnostic locations.
> > * g++.dg/cpp0x/constexpr-diag3.C: Likewise.
> > * g++.dg/cpp0x/constexpr-ice20.C: Likewise.
> > * g++.dg/cpp1y/constexpr-89481.C: Likewise.
> > * g++.dg/cpp1y/constexpr-lifetime1.C: Likewise.
> > * g++.dg/cpp1y/constexpr-lifetime2.C: Likewise.
> > * g++.dg/cpp1y/constexpr-lifetime3.C: Likewise.
> > * g++.dg/cpp1y/constexpr-lifetime4.C: Likewise.
> > * g++.dg/cpp1y/constexpr-lifetime5.C: Likewise.
> > * g++.dg/cpp1y/constexpr-union5.C: Likewise.
> > * g++.dg/cpp1y/pr68180.C: Likewise.
> > * g++.dg/cpp1z/constexpr-lambda6.C: Likewise.
> > * g++.dg/cpp2a/bit-cast11.C: Likewise.
> > * g++.dg/cpp2a/bit-cast12.C: Likewise.
> > * g++.dg/cpp2a/bit-cast14.C: Likewise.
> > * g++.dg/cpp2a/constexpr-98122.C: Likewise.
> > * g++.dg/cpp2a/constexpr-dynamic17.C: Likewise.
> > * g++.dg/cpp2a/constexpr-init1.C: Likewise.
> > * g++.dg/cpp2a/constexpr-new12.C: Likewise.
> > * g++.dg/cpp2a/constexpr-new3.C: Likewise.
> > * g++.dg/ext/constexpr-vla2.C: Likewise.
> > * g++.dg/ext/constexpr-vla3.C: Likewise.
> > * g++.dg/ubsan/pr63956.C: Likewise.
> > 
> > libstdc++/ChangeLog:
> > 
> > * testsuite/25_algorithms/equal/constexpr_neg.cc: Updated
> > diagnostics locations.
> > 
> > Signed-off-by: Nathaniel Shead 
> > ---
> >  gcc/cp/constexpr.cc   | 83 +++
> >  gcc/testsuite/g++.dg/cpp0x/constexpr-48089.C  | 10 +--
> >  gcc/testsuite/g++.dg/cpp0x/constexpr-diag3.C  |  2 +-
> >  gcc/testsuite/g++.dg/cpp0x/constexpr-ice20.C  |  4 +-
> >  gcc/testsuite/g++.dg/cpp1y/constexpr-89481.C  |  3 +-
> >  .../g++.dg/cpp1y/constexpr-lifetime1.C|  1 +
> >  .../g++.dg/cpp1y/constexpr-lifetime2.C|  4 +-
> >  .../g++.dg/cpp1y/constexpr-lifetime3.C|  4 +-
> >  .../g++.dg/cpp1y/constexpr-lifetime4.C|  2 +-
> >  .../g++.dg/cpp1y/constexpr-lifetime5.C|  4 +-
> >  gcc/testsuite/g++.dg/cpp1y/constexpr-union5.C |  4 +-
> >  gcc/testsuite/g++.dg/cpp1y/pr68180.C   

Re: [PATCH v2 1/3] c++: Track lifetimes in constant evaluation [PR70331, PR96630, PR98675]

2023-06-30 Thread Nathaniel Shead via Gcc-patches
On Mon, Jun 26, 2023 at 03:37:32PM -0400, Patrick Palka wrote:
> On Sun, 25 Jun 2023, Nathaniel Shead wrote:
> 
> > On Fri, Jun 23, 2023 at 12:43:21PM -0400, Patrick Palka wrote:
> > > On Wed, 29 Mar 2023, Nathaniel Shead via Gcc-patches wrote:
> > > 
> > > > This adds rudimentary lifetime tracking in C++ constexpr contexts,
> > > > allowing the compiler to report errors with using values after their
> > > > backing has gone out of scope. We don't yet handle other ways of ending
> > > > lifetimes (e.g. explicit destructor calls).
> > > 
> > > Awesome!
> > > 
> > > > 
> > > > PR c++/96630
> > > > PR c++/98675
> > > > PR c++/70331
> > > > 
> > > > gcc/cp/ChangeLog:
> > > > 
> > > > * constexpr.cc (constexpr_global_ctx::put_value): Mark value as
> > > > in lifetime.
> > > > (constexpr_global_ctx::remove_value): Mark value as expired.
> > > > (cxx_eval_call_expression): Remove comment that is no longer
> > > > applicable.
> > > > (non_const_var_error): Add check for expired values.
> > > > (cxx_eval_constant_expression): Add checks for expired values. 
> > > > Forget
> > > > local variables at end of bind expressions. Forget temporaries 
> > > > at end
> > > > of cleanup points.
> > > > * cp-tree.h (struct lang_decl_base): New flag to track expired 
> > > > values
> > > > in constant evaluation.
> > > > (DECL_EXPIRED_P): Access the new flag.
> > > > (SET_DECL_EXPIRED_P): Modify the new flag.
> > > > * module.cc (trees_out::lang_decl_bools): Write out the new 
> > > > flag.
> > > > (trees_in::lang_decl_bools): Read in the new flag.
> > > > 
> > > > gcc/testsuite/ChangeLog:
> > > > 
> > > > * g++.dg/cpp0x/constexpr-ice20.C: Update error raised by test.
> > > > * g++.dg/cpp1y/constexpr-lifetime1.C: New test.
> > > > * g++.dg/cpp1y/constexpr-lifetime2.C: New test.
> > > > * g++.dg/cpp1y/constexpr-lifetime3.C: New test.
> > > > * g++.dg/cpp1y/constexpr-lifetime4.C: New test.
> > > > * g++.dg/cpp1y/constexpr-lifetime5.C: New test.
> > > > 
> > > > Signed-off-by: Nathaniel Shead 
> > > > ---
> > > >  gcc/cp/constexpr.cc   | 69 +++
> > > >  gcc/cp/cp-tree.h  | 10 ++-
> > > >  gcc/cp/module.cc  |  2 +
> > > >  gcc/testsuite/g++.dg/cpp0x/constexpr-ice20.C  |  2 +-
> > > >  .../g++.dg/cpp1y/constexpr-lifetime1.C| 13 
> > > >  .../g++.dg/cpp1y/constexpr-lifetime2.C| 20 ++
> > > >  .../g++.dg/cpp1y/constexpr-lifetime3.C| 13 
> > > >  .../g++.dg/cpp1y/constexpr-lifetime4.C| 11 +++
> > > >  .../g++.dg/cpp1y/constexpr-lifetime5.C| 11 +++
> > > >  9 files changed, 137 insertions(+), 14 deletions(-)
> > > >  create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime1.C
> > > >  create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime2.C
> > > >  create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime3.C
> > > >  create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime4.C
> > > >  create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime5.C
> > > > 
> > > > diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
> > > > index 3de60cfd0f8..bdbc12144a7 100644
> > > > --- a/gcc/cp/constexpr.cc
> > > > +++ b/gcc/cp/constexpr.cc
> > > > @@ -1185,10 +1185,22 @@ public:
> > > >void put_value (tree t, tree v)
> > > >{
> > > >  bool already_in_map = values.put (t, v);
> > > > +if (!already_in_map && DECL_P (t))
> > > > +  {
> > > > +   if (!DECL_LANG_SPECIFIC (t))
> > > > + retrofit_lang_decl (t);
> > > > +   if (DECL_LANG_SPECIFIC (t))
> > > > + SET_DECL_EXPIRED_P (t, false);
> > > > +  }
> > > 
> > > Since this new flag would only be used only during constexpr evaluation,
> > > could we instead use an on-the-side hash_set in constexpr_global_ctx for
> > >

[PATCH] c++: Fix ICE with parameter pack of decltype(auto) [PR103497]

2023-06-30 Thread Nathaniel Shead via Gcc-patches
On Thu, Jun 29, 2023 at 01:43:07PM -0400, Jason Merrill wrote:
> On 6/24/23 09:24, Nathaniel Shead wrote:
> > On Fri, Jun 23, 2023 at 11:59:51AM -0400, Patrick Palka wrote:
> > > Hi,
> > > 
> > > On Sat, 22 Apr 2023, Nathaniel Shead via Gcc-patches wrote:
> > > 
> > > > Bootstrapped and tested on x86_64-pc-linux-gnu.
> > > > 
> > > > -- 8< --
> > > > 
> > > > This patch raises an error early when the decltype(auto) specifier is
> > > > used as a parameter of a function. This prevents any issues with an
> > > > unexpected tree type later on when performing the call.
> > > 
> > > Thanks very much for the patch!  Some minor comments below.
> > > 
> > > > 
> > > > PR 103497
> > > 
> > > We should include the bug component name when referring to the PR in the
> > > commit message (i.e. PR c++/103497) so that upon pushing the patch the
> > > post-commit hook automatically adds a comment to the PR reffering to the
> > > commit.  I could be wrong but AFAIK the hook only performs this when the
> > > component name is included.
> > 
> > Thanks for the review! Fixed.
> > 
> > > > 
> > > > gcc/cp/ChangeLog:
> > > > 
> > > > * parser.cc (cp_parser_simple_type_specifier): Add check for
> > > > decltype(auto) as function parameter.
> > > > 
> > > > gcc/testsuite/ChangeLog:
> > > > 
> > > > * g++.dg/pr103497.C: New test.
> > > > 
> > > > Signed-off-by: Nathaniel Shead 
> > > > ---
> > > >   gcc/cp/parser.cc| 10 ++
> > > >   gcc/testsuite/g++.dg/pr103497.C |  7 +++
> > > >   2 files changed, 17 insertions(+)
> > > >   create mode 100644 gcc/testsuite/g++.dg/pr103497.C
> > > > 
> > > > diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
> > > > index e5f032f2330..1415e07e152 100644
> > > > --- a/gcc/cp/parser.cc
> > > > +++ b/gcc/cp/parser.cc
> > > > @@ -19884,6 +19884,16 @@ cp_parser_simple_type_specifier (cp_parser* 
> > > > parser,
> > > > && cp_lexer_peek_nth_token (parser->lexer, 2)->type != 
> > > > CPP_SCOPE)
> > > >   {
> > > > type = saved_checks_value (token->u.tree_check_value);
> > > > +  /* Within a function parameter declaration, decltype(auto) is 
> > > > always an
> > > > +error.  */
> > > > +  if (parser->auto_is_implicit_function_template_parm_p
> > > > + && TREE_CODE (type) == TEMPLATE_TYPE_PARM
> > > 
> > > We could check is_auto (type) here instead, to avoid any confusion with
> > > checking AUTO_IS_DECLTYPE for a non-auto TEMPLATE_TYPE_PARM.
> > > 
> > > > + && AUTO_IS_DECLTYPE (type))
> > > > +   {
> > > > + error_at (token->location,
> > > > +   "cannot declare a parameter with 
> > > > %");
> > > > + type = error_mark_node;
> > > > +   }
> > > > if (decl_specs)
> > > > {
> > > >   cp_parser_set_decl_spec_type (decl_specs, type,
> > > > diff --git a/gcc/testsuite/g++.dg/pr103497.C 
> > > > b/gcc/testsuite/g++.dg/pr103497.C
> > > > new file mode 100644
> > > > index 000..bcd421c2907
> > > > --- /dev/null
> > > > +++ b/gcc/testsuite/g++.dg/pr103497.C
> > > > @@ -0,0 +1,7 @@
> > > > +// { dg-do compile { target c++14 } }
> > > > +
> > > > +void foo(decltype(auto)... args);  // { dg-error "parameter with 
> > > > .decltype.auto..|no parameter packs" }
> > > 
> > > I noticed for
> > > 
> > >void foo(decltype(auto) arg);
> > > 
> > > we already issue an identical error from grokdeclarator.  Perhaps we could
> > > instead extend the error handling there to detect decltype(auto)... as 
> > > well,
> > > rather than adding new error handling in cp_parser_simple_type_specifier?
> > 
> > Ah thanks, I didn't notice this; this simplifies the change a fair bit.
> > How about this patch instead?
> > 
> > Regtested on x86_64-pc-linux-gnu.
> > 
> > -- 8< --
> > 
> > This patch ensures that checks for usages of 'auto' in funct

Re: [PATCH v2 1/3] c++: Track lifetimes in constant evaluation [PR70331, PR96630, PR98675]

2023-06-24 Thread Nathaniel Shead via Gcc-patches
On Fri, Jun 23, 2023 at 12:43:21PM -0400, Patrick Palka wrote:
> On Wed, 29 Mar 2023, Nathaniel Shead via Gcc-patches wrote:
> 
> > This adds rudimentary lifetime tracking in C++ constexpr contexts,
> > allowing the compiler to report errors with using values after their
> > backing has gone out of scope. We don't yet handle other ways of ending
> > lifetimes (e.g. explicit destructor calls).
> 
> Awesome!
> 
> > 
> > PR c++/96630
> > PR c++/98675
> > PR c++/70331
> > 
> > gcc/cp/ChangeLog:
> > 
> > * constexpr.cc (constexpr_global_ctx::put_value): Mark value as
> > in lifetime.
> > (constexpr_global_ctx::remove_value): Mark value as expired.
> > (cxx_eval_call_expression): Remove comment that is no longer
> > applicable.
> > (non_const_var_error): Add check for expired values.
> > (cxx_eval_constant_expression): Add checks for expired values. Forget
> > local variables at end of bind expressions. Forget temporaries at end
> > of cleanup points.
> > * cp-tree.h (struct lang_decl_base): New flag to track expired values
> > in constant evaluation.
> > (DECL_EXPIRED_P): Access the new flag.
> > (SET_DECL_EXPIRED_P): Modify the new flag.
> > * module.cc (trees_out::lang_decl_bools): Write out the new flag.
> > (trees_in::lang_decl_bools): Read in the new flag.
> > 
> > gcc/testsuite/ChangeLog:
> > 
> > * g++.dg/cpp0x/constexpr-ice20.C: Update error raised by test.
> > * g++.dg/cpp1y/constexpr-lifetime1.C: New test.
> > * g++.dg/cpp1y/constexpr-lifetime2.C: New test.
> > * g++.dg/cpp1y/constexpr-lifetime3.C: New test.
> > * g++.dg/cpp1y/constexpr-lifetime4.C: New test.
> > * g++.dg/cpp1y/constexpr-lifetime5.C: New test.
> > 
> > Signed-off-by: Nathaniel Shead 
> > ---
> >  gcc/cp/constexpr.cc   | 69 +++
> >  gcc/cp/cp-tree.h  | 10 ++-
> >  gcc/cp/module.cc  |  2 +
> >  gcc/testsuite/g++.dg/cpp0x/constexpr-ice20.C  |  2 +-
> >  .../g++.dg/cpp1y/constexpr-lifetime1.C| 13 
> >  .../g++.dg/cpp1y/constexpr-lifetime2.C| 20 ++
> >  .../g++.dg/cpp1y/constexpr-lifetime3.C| 13 
> >  .../g++.dg/cpp1y/constexpr-lifetime4.C| 11 +++
> >  .../g++.dg/cpp1y/constexpr-lifetime5.C| 11 +++
> >  9 files changed, 137 insertions(+), 14 deletions(-)
> >  create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime1.C
> >  create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime2.C
> >  create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime3.C
> >  create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime4.C
> >  create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime5.C
> > 
> > diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
> > index 3de60cfd0f8..bdbc12144a7 100644
> > --- a/gcc/cp/constexpr.cc
> > +++ b/gcc/cp/constexpr.cc
> > @@ -1185,10 +1185,22 @@ public:
> >void put_value (tree t, tree v)
> >{
> >  bool already_in_map = values.put (t, v);
> > +if (!already_in_map && DECL_P (t))
> > +  {
> > +   if (!DECL_LANG_SPECIFIC (t))
> > + retrofit_lang_decl (t);
> > +   if (DECL_LANG_SPECIFIC (t))
> > + SET_DECL_EXPIRED_P (t, false);
> > +  }
> 
> Since this new flag would only be used only during constexpr evaluation,
> could we instead use an on-the-side hash_set in constexpr_global_ctx for
> tracking expired-ness?  That way we won't have to allocate a
> DECL_LANG_SPECIFIC structure for decls that lack it, and won't have to
> worry about the flag in other parts of the compiler.

I've tried this but I haven't been able to get it to work well. The main
issue I'm running into is the caching of function calls in constant
evaluation. For example, consider the following:

constexpr const double& test() {
  const double& local = 3.0;
  return local;
}

constexpr int foo(const double&) { return 5; }

constexpr int a = foo(test());
static_assert(test() == 3.0);

When constant-evaluating 'a', we evaluate 'test()'. It returns a value
that ends its lifetime immediately, so we mark this in 'ctx->global' as
expired. However, 'foo()' never actually evaluates this expired value,
so the initialisation of 'a' succeeds.

However, then when the static assertion attempts to constant evaluate a
second time, the result of 'test' has already been cached, and we just
get directly handed a value. This is a new constant evaluation, so
'ctx->global' has 

Re: [PATCH] c++: Report invalid id-expression in decltype [PR100482]

2023-06-24 Thread Nathaniel Shead via Gcc-patches
On Fri, Jun 23, 2023 at 12:15:32PM -0400, Patrick Palka wrote:
> On Sun, 30 Apr 2023, Nathaniel Shead via Gcc-patches wrote:
> 
> > This patch ensures that any errors raised by finish_id_expression when
> > parsing a decltype expression are properly reported, rather than
> > potentially going ignored and causing invalid code to be accepted.
> > 
> > We can also now remove the separate check for templates without args as
> > this is also checked for in finish_id_expression.
> > 
> > PR 100482
> > 
> > gcc/cp/ChangeLog:
> > 
> > * parser.cc (cp_parser_decltype_expr): Report errors raised by
> > finish_id_expression.
> > 
> > gcc/testsuite/ChangeLog:
> > 
> > * g++.dg/pr100482.C: New test.
> 
> LGTM.  Some minor comments about the new testcase below:
> 
> > 
> > Signed-off-by: Nathaniel Shead 
> > ---
> >  gcc/cp/parser.cc| 22 +++---
> >  gcc/testsuite/g++.dg/pr100482.C | 11 +++
> >  2 files changed, 22 insertions(+), 11 deletions(-)
> >  create mode 100644 gcc/testsuite/g++.dg/pr100482.C
> > 
> > diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
> > index e5f032f2330..20ebcdc3cfd 100644
> > --- a/gcc/cp/parser.cc
> > +++ b/gcc/cp/parser.cc
> > @@ -16508,10 +16508,6 @@ cp_parser_decltype_expr (cp_parser *parser,
> > expr = cp_parser_lookup_name_simple (parser, expr,
> >  id_expr_start_token->location);
> >  
> > -  if (expr && TREE_CODE (expr) == TEMPLATE_DECL)
> > -   /* A template without args is not a complete id-expression.  */
> > -   expr = error_mark_node;
> > -
> >if (expr
> >&& expr != error_mark_node
> >&& TREE_CODE (expr) != TYPE_DECL
> > @@ -16532,13 +16528,17 @@ cp_parser_decltype_expr (cp_parser *parser,
> > _msg,
> >id_expr_start_token->location));
> >  
> > -  if (expr == error_mark_node)
> > -/* We found an id-expression, but it was something that we
> > -   should not have found. This is an error, not something
> > -   we can recover from, so note that we found an
> > -   id-expression and we'll recover as gracefully as
> > -   possible.  */
> > -id_expression_or_member_access_p = true;
> > + if (error_msg)
> > +   {
> > + /* We found an id-expression, but it was something that we
> > +should not have found. This is an error, not something
> > +we can recover from, so report the error we found and
> > +we'll recover as gracefully as possible.  */
> > + cp_parser_parse_definitely (parser);
> > + cp_parser_error (parser, error_msg);
> > + id_expression_or_member_access_p = true;
> > + return error_mark_node;
> > +   }
> >  }
> >  
> >if (expr
> > diff --git a/gcc/testsuite/g++.dg/pr100482.C 
> > b/gcc/testsuite/g++.dg/pr100482.C
> > new file mode 100644
> > index 000..dcf6722fda5
> > --- /dev/null
> > +++ b/gcc/testsuite/g++.dg/pr100482.C
> 
> We generally prefer to organize tests according to the language dialect
> they apply to and the langugae construct that they're primarily testing.
> In this case we could name the test e.g.
> 
>   gcc/testsuite/g++.dg/cpp0x/decltype-100482.C
> 
> > @@ -0,0 +1,11 @@
> > +// { dg-do compile { target c++10 } }
> 
> We also usually mention the PR number in the test as a comment:
> 
> // PR c++/100482
> 
> One benefit of doing so is that the git alias 'git gcc-commit-mklog'
> (https://gcc.gnu.org/gitwrite.html#vendor) will then automatically
> include the PR number in the commit message template.
> 
> > +
> > +namespace N {}
> > +decltype(std) x;   // { dg-error "expected primary-expression" }
> > +
> > +struct S {};
> > +decltype(S) y;  // { dg-error "argument to .decltype. must be an 
> > expression" }
> > +
> > +template 
> > +struct U {};
> > +decltype(U) z;  // { dg-error "missing template arguments" }
> > -- 
> > 2.40.0
> > 
> > 
> 

Thanks for the comments. I've fixed the test, does this look OK?

-- 8< --

This patch ensures that any errors raised by finish_id_expression when
parsing a decltype expression are properly reported, rather than
potentially going ignored and causing invalid code to be accepted.

We can also now remove the separate check fo

Re: [PATCH] c++: Fix ICE with parameter pack of decltype(auto) [PR103497]

2023-06-24 Thread Nathaniel Shead via Gcc-patches
On Fri, Jun 23, 2023 at 11:59:51AM -0400, Patrick Palka wrote:
> Hi,
> 
> On Sat, 22 Apr 2023, Nathaniel Shead via Gcc-patches wrote:
> 
> > Bootstrapped and tested on x86_64-pc-linux-gnu.
> > 
> > -- 8< --
> > 
> > This patch raises an error early when the decltype(auto) specifier is
> > used as a parameter of a function. This prevents any issues with an
> > unexpected tree type later on when performing the call.
> 
> Thanks very much for the patch!  Some minor comments below.
> 
> > 
> > PR 103497
> 
> We should include the bug component name when referring to the PR in the
> commit message (i.e. PR c++/103497) so that upon pushing the patch the
> post-commit hook automatically adds a comment to the PR reffering to the
> commit.  I could be wrong but AFAIK the hook only performs this when the
> component name is included.

Thanks for the review! Fixed.

> > 
> > gcc/cp/ChangeLog:
> > 
> > * parser.cc (cp_parser_simple_type_specifier): Add check for
> > decltype(auto) as function parameter.
> > 
> > gcc/testsuite/ChangeLog:
> > 
> > * g++.dg/pr103497.C: New test.
> > 
> > Signed-off-by: Nathaniel Shead 
> > ---
> >  gcc/cp/parser.cc| 10 ++
> >  gcc/testsuite/g++.dg/pr103497.C |  7 +++
> >  2 files changed, 17 insertions(+)
> >  create mode 100644 gcc/testsuite/g++.dg/pr103497.C
> > 
> > diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
> > index e5f032f2330..1415e07e152 100644
> > --- a/gcc/cp/parser.cc
> > +++ b/gcc/cp/parser.cc
> > @@ -19884,6 +19884,16 @@ cp_parser_simple_type_specifier (cp_parser* parser,
> >&& cp_lexer_peek_nth_token (parser->lexer, 2)->type != CPP_SCOPE)
> >  {
> >type = saved_checks_value (token->u.tree_check_value);
> > +  /* Within a function parameter declaration, decltype(auto) is always 
> > an
> > +error.  */
> > +  if (parser->auto_is_implicit_function_template_parm_p
> > + && TREE_CODE (type) == TEMPLATE_TYPE_PARM
> 
> We could check is_auto (type) here instead, to avoid any confusion with
> checking AUTO_IS_DECLTYPE for a non-auto TEMPLATE_TYPE_PARM.
> 
> > + && AUTO_IS_DECLTYPE (type))
> > +   {
> > + error_at (token->location,
> > +   "cannot declare a parameter with %");
> > + type = error_mark_node;
> > +   }
> >if (decl_specs)
> > {
> >   cp_parser_set_decl_spec_type (decl_specs, type,
> > diff --git a/gcc/testsuite/g++.dg/pr103497.C 
> > b/gcc/testsuite/g++.dg/pr103497.C
> > new file mode 100644
> > index 000..bcd421c2907
> > --- /dev/null
> > +++ b/gcc/testsuite/g++.dg/pr103497.C
> > @@ -0,0 +1,7 @@
> > +// { dg-do compile { target c++14 } }
> > +
> > +void foo(decltype(auto)... args);  // { dg-error "parameter with 
> > .decltype.auto..|no parameter packs" }
> 
> I noticed for
> 
>   void foo(decltype(auto) arg);
> 
> we already issue an identical error from grokdeclarator.  Perhaps we could
> instead extend the error handling there to detect decltype(auto)... as well,
> rather than adding new error handling in cp_parser_simple_type_specifier?

Ah thanks, I didn't notice this; this simplifies the change a fair bit.
How about this patch instead?

Regtested on x86_64-pc-linux-gnu.

-- 8< --

This patch ensures that checks for usages of 'auto' in function
parameters also consider parameter packs, since 'type_uses_auto' does
not seem to consider this case.

PR c++/103497

gcc/cp/ChangeLog:

* decl.cc (grokdeclarator): Check for decltype(auto) in
parameter pack.

gcc/testsuite/ChangeLog:

* g++.dg/cpp1y/decltype-auto-103497.C: New test.

Signed-off-by: Nathaniel Shead 
---
 gcc/cp/decl.cc| 3 +++
 gcc/testsuite/g++.dg/cpp1y/decltype-auto-103497.C | 8 
 2 files changed, 11 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/decltype-auto-103497.C

diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 60f107d50c4..aaf691fce68 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -14044,6 +14044,9 @@ grokdeclarator (const cp_declarator *declarator,
error ("cannot use %<::%> in parameter declaration");
 
   tree auto_node = type_uses_auto (type);
+  if (!auto_node && parameter_pack_p)
+   auto_node = type_uses_auto (PACK_EXPANSION_PATTERN (type));
+
   if (auto_node && !(cxx_dialect >= cxx17 && template_parm_flag))
{
  if (cxx_dialect >= cxx14)
diff --git a/gcc/testsuite/g++.dg/cpp1y/decltype-auto-103497.C 
b/gcc/testsuite/g++.dg/cpp1y/decltype-auto-103497.C
new file mode 100644
index 000..cedd661710c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/decltype-auto-103497.C
@@ -0,0 +1,8 @@
+// PR c++/103497
+// { dg-do compile { target c++14 } }
+
+void foo(decltype(auto)... args);  // { dg-error "cannot declare a parameter 
with .decltype.auto.." }
+
+int main() {
+  foo();
+}
-- 
2.41.0



[PATCH] c++: Fix ICE with parameter pack of decltype(auto) [PR103497]

2023-06-13 Thread Nathaniel Shead via Gcc-patches
(Another) ping.

https://gcc.gnu.org/pipermail/gcc-patches/2023-April/616465.html

On Sat, Apr 22, 2023 at 04:25:13PM +1000, Nathaniel Shead wrote:
> Bootstrapped and tested on x86_64-pc-linux-gnu.
> 
> -- 8< --
> 
> This patch raises an error early when the decltype(auto) specifier is
> used as a parameter of a function. This prevents any issues with an
> unexpected tree type later on when performing the call.
> 
>   PR 103497
> 
> gcc/cp/ChangeLog:
> 
>   * parser.cc (cp_parser_simple_type_specifier): Add check for
>   decltype(auto) as function parameter.
> 
> gcc/testsuite/ChangeLog:
> 
>   * g++.dg/pr103497.C: New test.
> 
> Signed-off-by: Nathaniel Shead 
> ---
>  gcc/cp/parser.cc| 10 ++
>  gcc/testsuite/g++.dg/pr103497.C |  7 +++
>  2 files changed, 17 insertions(+)
>  create mode 100644 gcc/testsuite/g++.dg/pr103497.C
> 
> diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
> index e5f032f2330..1415e07e152 100644
> --- a/gcc/cp/parser.cc
> +++ b/gcc/cp/parser.cc
> @@ -19884,6 +19884,16 @@ cp_parser_simple_type_specifier (cp_parser* parser,
>&& cp_lexer_peek_nth_token (parser->lexer, 2)->type != CPP_SCOPE)
>  {
>type = saved_checks_value (token->u.tree_check_value);
> +  /* Within a function parameter declaration, decltype(auto) is always an
> +  error.  */
> +  if (parser->auto_is_implicit_function_template_parm_p
> +   && TREE_CODE (type) == TEMPLATE_TYPE_PARM
> +   && AUTO_IS_DECLTYPE (type))
> + {
> +   error_at (token->location,
> + "cannot declare a parameter with %");
> +   type = error_mark_node;
> + }
>if (decl_specs)
>   {
> cp_parser_set_decl_spec_type (decl_specs, type,
> diff --git a/gcc/testsuite/g++.dg/pr103497.C b/gcc/testsuite/g++.dg/pr103497.C
> new file mode 100644
> index 000..bcd421c2907
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/pr103497.C
> @@ -0,0 +1,7 @@
> +// { dg-do compile { target c++14 } }
> +
> +void foo(decltype(auto)... args);  // { dg-error "parameter with 
> .decltype.auto..|no parameter packs" }
> +
> +int main() {
> +  foo();
> +}
> -- 
> 2.34.1
> 


[PATCH] c++: Report invalid id-expression in decltype [PR100482]

2023-06-13 Thread Nathaniel Shead via Gcc-patches
(Another) ping.

On Sun, Apr 30, 2023 at 12:00:05PM +1000, Nathaniel Shead wrote:
> This patch ensures that any errors raised by finish_id_expression when
> parsing a decltype expression are properly reported, rather than
> potentially going ignored and causing invalid code to be accepted.
> 
> We can also now remove the separate check for templates without args as
> this is also checked for in finish_id_expression.
> 
>   PR 100482
> 
> gcc/cp/ChangeLog:
> 
>   * parser.cc (cp_parser_decltype_expr): Report errors raised by
>   finish_id_expression.
> 
> gcc/testsuite/ChangeLog:
> 
>   * g++.dg/pr100482.C: New test.
> 
> Signed-off-by: Nathaniel Shead 
> ---
>  gcc/cp/parser.cc| 22 +++---
>  gcc/testsuite/g++.dg/pr100482.C | 11 +++
>  2 files changed, 22 insertions(+), 11 deletions(-)
>  create mode 100644 gcc/testsuite/g++.dg/pr100482.C
> 
> diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
> index e5f032f2330..20ebcdc3cfd 100644
> --- a/gcc/cp/parser.cc
> +++ b/gcc/cp/parser.cc
> @@ -16508,10 +16508,6 @@ cp_parser_decltype_expr (cp_parser *parser,
>   expr = cp_parser_lookup_name_simple (parser, expr,
>id_expr_start_token->location);
>  
> -  if (expr && TREE_CODE (expr) == TEMPLATE_DECL)
> - /* A template without args is not a complete id-expression.  */
> - expr = error_mark_node;
> -
>if (expr
>&& expr != error_mark_node
>&& TREE_CODE (expr) != TYPE_DECL
> @@ -16532,13 +16528,17 @@ cp_parser_decltype_expr (cp_parser *parser,
> _msg,
>  id_expr_start_token->location));
>  
> -  if (expr == error_mark_node)
> -/* We found an id-expression, but it was something that we
> -   should not have found. This is an error, not something
> -   we can recover from, so note that we found an
> -   id-expression and we'll recover as gracefully as
> -   possible.  */
> -id_expression_or_member_access_p = true;
> +   if (error_msg)
> + {
> +   /* We found an id-expression, but it was something that we
> +  should not have found. This is an error, not something
> +  we can recover from, so report the error we found and
> +  we'll recover as gracefully as possible.  */
> +   cp_parser_parse_definitely (parser);
> +   cp_parser_error (parser, error_msg);
> +   id_expression_or_member_access_p = true;
> +   return error_mark_node;
> + }
>  }
>  
>if (expr
> diff --git a/gcc/testsuite/g++.dg/pr100482.C b/gcc/testsuite/g++.dg/pr100482.C
> new file mode 100644
> index 000..dcf6722fda5
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/pr100482.C
> @@ -0,0 +1,11 @@
> +// { dg-do compile { target c++11 } }
> +
> +namespace N {}
> +decltype(std) x;   // { dg-error "expected primary-expression" }
> +
> +struct S {};
> +decltype(S) y;  // { dg-error "argument to .decltype. must be an expression" 
> }
> +
> +template 
> +struct U {};
> +decltype(U) z;  // { dg-error "missing template arguments" }
> -- 
> 2.40.0
> 


[PATCH v2 0/3] c++: Track lifetimes in constant evaluation [PR70331,...]

2023-06-13 Thread Nathaniel Shead via Gcc-patches
(Another) ping. I also have some more changes on top of this patch set
as well if this looks good as it is.

https://gcc.gnu.org/pipermail/gcc-patches/2023-March/614811.html

Thanks!

On Wed, Mar 29, 2023 at 01:32:55PM +1100, Nathaniel Shead wrote:
> This is an update of the patch series at
> https://gcc.gnu.org/pipermail/gcc-patches/2023-March/614759.html
> 
> The main change is modifying the first patch to store the "expired" flag
> in the C++-specific lang_decl_base struct instead of tree_decl_common.
> The second and third patches to improve diagnostic locations are
> otherwise unchanged.
> 
> Bootstrapped and regression tested on x86_64 linux.
> 
> Nathaniel
> 
> ---
> 
> Nathaniel Shead (3):
>   c++: Track lifetimes in constant evaluation [PR70331,PR96630,PR98675]
>   c++: Improve constexpr error for dangling local variables
>   c++: Improve location information in constexpr evaluation
> 
>  gcc/cp/constexpr.cc   | 152 --
>  gcc/cp/cp-tree.h  |  10 +-
>  gcc/cp/module.cc  |   2 +
>  gcc/cp/semantics.cc   |   5 +-
>  gcc/cp/typeck.cc  |   5 +-
>  gcc/testsuite/g++.dg/cpp0x/constexpr-48089.C  |  10 +-
>  gcc/testsuite/g++.dg/cpp0x/constexpr-diag3.C  |   2 +-
>  gcc/testsuite/g++.dg/cpp0x/constexpr-ice20.C  |   2 +-
>  gcc/testsuite/g++.dg/cpp1y/constexpr-89481.C  |   3 +-
>  .../g++.dg/cpp1y/constexpr-lifetime1.C|  14 ++
>  .../g++.dg/cpp1y/constexpr-lifetime2.C|  20 +++
>  .../g++.dg/cpp1y/constexpr-lifetime3.C|  13 ++
>  .../g++.dg/cpp1y/constexpr-lifetime4.C|  11 ++
>  .../g++.dg/cpp1y/constexpr-lifetime5.C|  11 ++
>  gcc/testsuite/g++.dg/cpp1y/constexpr-union5.C |   4 +-
>  gcc/testsuite/g++.dg/cpp1y/pr68180.C  |   4 +-
>  .../g++.dg/cpp1z/constexpr-lambda6.C  |   4 +-
>  gcc/testsuite/g++.dg/cpp2a/bit-cast11.C   |  10 +-
>  gcc/testsuite/g++.dg/cpp2a/bit-cast12.C   |  10 +-
>  gcc/testsuite/g++.dg/cpp2a/bit-cast14.C   |  14 +-
>  gcc/testsuite/g++.dg/cpp2a/constexpr-98122.C  |   4 +-
>  .../g++.dg/cpp2a/constexpr-dynamic17.C|   5 +-
>  gcc/testsuite/g++.dg/cpp2a/constexpr-init1.C  |   5 +-
>  gcc/testsuite/g++.dg/cpp2a/constexpr-new12.C  |   6 +-
>  gcc/testsuite/g++.dg/cpp2a/constexpr-new3.C   |  10 +-
>  gcc/testsuite/g++.dg/ext/constexpr-vla2.C |   4 +-
>  gcc/testsuite/g++.dg/ext/constexpr-vla3.C |   4 +-
>  gcc/testsuite/g++.dg/ubsan/pr63956.C  |   4 +-
>  .../g++.dg/warn/Wreturn-local-addr-6.C|   3 -
>  .../25_algorithms/equal/constexpr_neg.cc  |   7 +-
>  30 files changed, 246 insertions(+), 112 deletions(-)
>  create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime1.C
>  create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime2.C
>  create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime3.C
>  create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime4.C
>  create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime5.C
> 
> -- 
> 2.34.1
> 


ping: [PATCH] c++: Report invalid id-expression in decltype [PR100482]

2023-05-27 Thread Nathaniel Shead via Gcc-patches
Ping: https://gcc.gnu.org/pipermail/gcc-patches/2023-April/617145.html

Also it looks like I forgot to mention, but this patch was bootstrapped
and regtested on x86_64-pc-linux-gnu.

On Sun, Apr 30, 2023 at 12:00:05PM +1000, Nathaniel Shead wrote:
> This patch ensures that any errors raised by finish_id_expression when
> parsing a decltype expression are properly reported, rather than
> potentially going ignored and causing invalid code to be accepted.
> 
> We can also now remove the separate check for templates without args as
> this is also checked for in finish_id_expression.
> 
>   PR 100482
> 
> gcc/cp/ChangeLog:
> 
>   * parser.cc (cp_parser_decltype_expr): Report errors raised by
>   finish_id_expression.
> 
> gcc/testsuite/ChangeLog:
> 
>   * g++.dg/pr100482.C: New test.
> 
> Signed-off-by: Nathaniel Shead 
> ---
>  gcc/cp/parser.cc| 22 +++---
>  gcc/testsuite/g++.dg/pr100482.C | 11 +++
>  2 files changed, 22 insertions(+), 11 deletions(-)
>  create mode 100644 gcc/testsuite/g++.dg/pr100482.C
> 
> diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
> index e5f032f2330..20ebcdc3cfd 100644
> --- a/gcc/cp/parser.cc
> +++ b/gcc/cp/parser.cc
> @@ -16508,10 +16508,6 @@ cp_parser_decltype_expr (cp_parser *parser,
>   expr = cp_parser_lookup_name_simple (parser, expr,
>id_expr_start_token->location);
>  
> -  if (expr && TREE_CODE (expr) == TEMPLATE_DECL)
> - /* A template without args is not a complete id-expression.  */
> - expr = error_mark_node;
> -
>if (expr
>&& expr != error_mark_node
>&& TREE_CODE (expr) != TYPE_DECL
> @@ -16532,13 +16528,17 @@ cp_parser_decltype_expr (cp_parser *parser,
> _msg,
>  id_expr_start_token->location));
>  
> -  if (expr == error_mark_node)
> -/* We found an id-expression, but it was something that we
> -   should not have found. This is an error, not something
> -   we can recover from, so note that we found an
> -   id-expression and we'll recover as gracefully as
> -   possible.  */
> -id_expression_or_member_access_p = true;
> +   if (error_msg)
> + {
> +   /* We found an id-expression, but it was something that we
> +  should not have found. This is an error, not something
> +  we can recover from, so report the error we found and
> +  we'll recover as gracefully as possible.  */
> +   cp_parser_parse_definitely (parser);
> +   cp_parser_error (parser, error_msg);
> +   id_expression_or_member_access_p = true;
> +   return error_mark_node;
> + }
>  }
>  
>if (expr
> diff --git a/gcc/testsuite/g++.dg/pr100482.C b/gcc/testsuite/g++.dg/pr100482.C
> new file mode 100644
> index 000..dcf6722fda5
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/pr100482.C
> @@ -0,0 +1,11 @@
> +// { dg-do compile { target c++11 } }
> +
> +namespace N {}
> +decltype(std) x;   // { dg-error "expected primary-expression" }
> +
> +struct S {};
> +decltype(S) y;  // { dg-error "argument to .decltype. must be an expression" 
> }
> +
> +template 
> +struct U {};
> +decltype(U) z;  // { dg-error "missing template arguments" }
> -- 
> 2.40.0
> 


ping: [PATCH] c++: Fix ICE with parameter pack of decltype(auto) [PR103497]

2023-05-27 Thread Nathaniel Shead via Gcc-patches
Ping: https://gcc.gnu.org/pipermail/gcc-patches/2023-April/616465.html

On Sat, Apr 22, 2023 at 04:25:13PM +1000, Nathaniel Shead wrote:
> Bootstrapped and tested on x86_64-pc-linux-gnu.
> 
> -- 8< --
> 
> This patch raises an error early when the decltype(auto) specifier is
> used as a parameter of a function. This prevents any issues with an
> unexpected tree type later on when performing the call.
> 
>   PR 103497
> 
> gcc/cp/ChangeLog:
> 
>   * parser.cc (cp_parser_simple_type_specifier): Add check for
>   decltype(auto) as function parameter.
> 
> gcc/testsuite/ChangeLog:
> 
>   * g++.dg/pr103497.C: New test.
> 
> Signed-off-by: Nathaniel Shead 
> ---
>  gcc/cp/parser.cc| 10 ++
>  gcc/testsuite/g++.dg/pr103497.C |  7 +++
>  2 files changed, 17 insertions(+)
>  create mode 100644 gcc/testsuite/g++.dg/pr103497.C
> 
> diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
> index e5f032f2330..1415e07e152 100644
> --- a/gcc/cp/parser.cc
> +++ b/gcc/cp/parser.cc
> @@ -19884,6 +19884,16 @@ cp_parser_simple_type_specifier (cp_parser* parser,
>&& cp_lexer_peek_nth_token (parser->lexer, 2)->type != CPP_SCOPE)
>  {
>type = saved_checks_value (token->u.tree_check_value);
> +  /* Within a function parameter declaration, decltype(auto) is always an
> +  error.  */
> +  if (parser->auto_is_implicit_function_template_parm_p
> +   && TREE_CODE (type) == TEMPLATE_TYPE_PARM
> +   && AUTO_IS_DECLTYPE (type))
> + {
> +   error_at (token->location,
> + "cannot declare a parameter with %");
> +   type = error_mark_node;
> + }
>if (decl_specs)
>   {
> cp_parser_set_decl_spec_type (decl_specs, type,
> diff --git a/gcc/testsuite/g++.dg/pr103497.C b/gcc/testsuite/g++.dg/pr103497.C
> new file mode 100644
> index 000..bcd421c2907
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/pr103497.C
> @@ -0,0 +1,7 @@
> +// { dg-do compile { target c++14 } }
> +
> +void foo(decltype(auto)... args);  // { dg-error "parameter with 
> .decltype.auto..|no parameter packs" }
> +
> +int main() {
> +  foo();
> +}
> -- 
> 2.34.1
> 


Re: [Ping][PATCH] libstdc++: Add missing functions to [PR79700]

2023-05-17 Thread Nathaniel Shead via Gcc-patches
On Wed, May 17, 2023 at 10:05:59AM +0100, Jonathan Wakely wrote:
> On Wed, 17 May 2023 at 09:37, Nathaniel Shead wrote:
> 
> > Now that GCC13.1 is released is it ok to merge? Thanks!
> >
> 
> Yes, I've been testing this locally, but I think it needs more work (sorry!)
> 
> Looking at it again, I'm not sure why I asked for the additional tests
> because if they fail, it's a problem in libc, and there's nothing we can
> actually do about it in libstdc++. We certainly do want std::expl(0.0L) to
> return the same thing as std::exp(0.0L), but if it doesn't, we'll just have
> a libstdc++ test failure caused by a bug in libc. But you wrote the test
> now, so let's keep it. If we get failures for the test it will allow us to
> inform the relevant libc maintainers that they have a bug.

Sounds good.

> Also, since you're contributing this under the DCO terms the new test
> should not have the FSF copyright header, unless it's a derived work of an
> existing test with that header (and in that case it should retain the dates
> from the copied test). I don't actually bother putting the copyright and
> license header on new tests these days. There's nothing in that test that
> is novel or interesting, and I think it's arguably not useful or meaningful
> to consider it copyrighted.

Makes sense, I was just copying from other tests in the directory. I'll
keep this in mind for the future, thanks!

> Finally, and most importantly, the new using-declarations in  are
> not guarded by any autoconf macro. That will break targets without full C99
>  support, e.g. djgpp declares acosf but not acosl, so the new
> "using acosl;" would be a hard error as soon as  is included (and
> might even prevent GCC building on that target). So I think we need a new
> autoconf check for the existence of those functions. I'm in the process of
> reworking the autoconf macros for  (due to PR 109818), which is why
> I didn't address it for this patch yet.

Ah, I see; yes, that would be a problem. I'm not very familiar with
autoconf, so thanks for working this out. Let me know when you've done
that if there's anything else I should do for this patch.

> >
> > On Tue, Apr 18, 2023 at 6:48 PM Jonathan Wakely 
> > wrote:
> > >
> > > On Mon, 17 Apr 2023 at 09:11, Nathaniel Shead 
> > wrote:
> > > >
> > > > Hi, just checking whether there were any issues with this patch?
> > > > https://gcc.gnu.org/pipermail/gcc-patches/2023-February/612386.html
> > > >
> > > > Otherwise I assume it won't be in GCC13.
> > >
> > > That's right, it's too large and invasive a change to get into GCC 13
> > > when only submitted in February, sorry. I'll merge it to trunk once
> > > GCC 13.1 is released though.
> > >
> >
> >


Re: [Ping][PATCH] libstdc++: Add missing functions to [PR79700]

2023-05-17 Thread Nathaniel Shead via Gcc-patches
Now that GCC13.1 is released is it ok to merge? Thanks!

On Tue, Apr 18, 2023 at 6:48 PM Jonathan Wakely  wrote:
>
> On Mon, 17 Apr 2023 at 09:11, Nathaniel Shead  
> wrote:
> >
> > Hi, just checking whether there were any issues with this patch?
> > https://gcc.gnu.org/pipermail/gcc-patches/2023-February/612386.html
> >
> > Otherwise I assume it won't be in GCC13.
>
> That's right, it's too large and invasive a change to get into GCC 13
> when only submitted in February, sorry. I'll merge it to trunk once
> GCC 13.1 is released though.
>


Re: [PATCH v2 0/3] c++: Track lifetimes in constant evaluation [PR70331, ...]

2023-05-08 Thread Nathaniel Shead via Gcc-patches
Just pinging in case this fix has fallen through the cracks.

https://gcc.gnu.org/pipermail/gcc-patches/2023-March/614811.html

On Wed, Mar 29, 2023 at 1:33 PM Nathaniel Shead
 wrote:
>
> This is an update of the patch series at
> https://gcc.gnu.org/pipermail/gcc-patches/2023-March/614759.html
>
> The main change is modifying the first patch to store the "expired" flag
> in the C++-specific lang_decl_base struct instead of tree_decl_common.
> The second and third patches to improve diagnostic locations are
> otherwise unchanged.
>
> Bootstrapped and regression tested on x86_64 linux.
>
> Nathaniel
>
> ---
>
> Nathaniel Shead (3):
>   c++: Track lifetimes in constant evaluation [PR70331,PR96630,PR98675]
>   c++: Improve constexpr error for dangling local variables
>   c++: Improve location information in constexpr evaluation
>
>  gcc/cp/constexpr.cc   | 152 --
>  gcc/cp/cp-tree.h  |  10 +-
>  gcc/cp/module.cc  |   2 +
>  gcc/cp/semantics.cc   |   5 +-
>  gcc/cp/typeck.cc  |   5 +-
>  gcc/testsuite/g++.dg/cpp0x/constexpr-48089.C  |  10 +-
>  gcc/testsuite/g++.dg/cpp0x/constexpr-diag3.C  |   2 +-
>  gcc/testsuite/g++.dg/cpp0x/constexpr-ice20.C  |   2 +-
>  gcc/testsuite/g++.dg/cpp1y/constexpr-89481.C  |   3 +-
>  .../g++.dg/cpp1y/constexpr-lifetime1.C|  14 ++
>  .../g++.dg/cpp1y/constexpr-lifetime2.C|  20 +++
>  .../g++.dg/cpp1y/constexpr-lifetime3.C|  13 ++
>  .../g++.dg/cpp1y/constexpr-lifetime4.C|  11 ++
>  .../g++.dg/cpp1y/constexpr-lifetime5.C|  11 ++
>  gcc/testsuite/g++.dg/cpp1y/constexpr-union5.C |   4 +-
>  gcc/testsuite/g++.dg/cpp1y/pr68180.C  |   4 +-
>  .../g++.dg/cpp1z/constexpr-lambda6.C  |   4 +-
>  gcc/testsuite/g++.dg/cpp2a/bit-cast11.C   |  10 +-
>  gcc/testsuite/g++.dg/cpp2a/bit-cast12.C   |  10 +-
>  gcc/testsuite/g++.dg/cpp2a/bit-cast14.C   |  14 +-
>  gcc/testsuite/g++.dg/cpp2a/constexpr-98122.C  |   4 +-
>  .../g++.dg/cpp2a/constexpr-dynamic17.C|   5 +-
>  gcc/testsuite/g++.dg/cpp2a/constexpr-init1.C  |   5 +-
>  gcc/testsuite/g++.dg/cpp2a/constexpr-new12.C  |   6 +-
>  gcc/testsuite/g++.dg/cpp2a/constexpr-new3.C   |  10 +-
>  gcc/testsuite/g++.dg/ext/constexpr-vla2.C |   4 +-
>  gcc/testsuite/g++.dg/ext/constexpr-vla3.C |   4 +-
>  gcc/testsuite/g++.dg/ubsan/pr63956.C  |   4 +-
>  .../g++.dg/warn/Wreturn-local-addr-6.C|   3 -
>  .../25_algorithms/equal/constexpr_neg.cc  |   7 +-
>  30 files changed, 246 insertions(+), 112 deletions(-)
>  create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime1.C
>  create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime2.C
>  create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime3.C
>  create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime4.C
>  create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime5.C
>
> --
> 2.34.1
>


[PATCH] c++: Report invalid id-expression in decltype [PR100482]

2023-04-29 Thread Nathaniel Shead via Gcc-patches
This patch ensures that any errors raised by finish_id_expression when
parsing a decltype expression are properly reported, rather than
potentially going ignored and causing invalid code to be accepted.

We can also now remove the separate check for templates without args as
this is also checked for in finish_id_expression.

PR 100482

gcc/cp/ChangeLog:

* parser.cc (cp_parser_decltype_expr): Report errors raised by
finish_id_expression.

gcc/testsuite/ChangeLog:

* g++.dg/pr100482.C: New test.

Signed-off-by: Nathaniel Shead 
---
 gcc/cp/parser.cc| 22 +++---
 gcc/testsuite/g++.dg/pr100482.C | 11 +++
 2 files changed, 22 insertions(+), 11 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/pr100482.C

diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index e5f032f2330..20ebcdc3cfd 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -16508,10 +16508,6 @@ cp_parser_decltype_expr (cp_parser *parser,
expr = cp_parser_lookup_name_simple (parser, expr,
 id_expr_start_token->location);
 
-  if (expr && TREE_CODE (expr) == TEMPLATE_DECL)
-   /* A template without args is not a complete id-expression.  */
-   expr = error_mark_node;
-
   if (expr
   && expr != error_mark_node
   && TREE_CODE (expr) != TYPE_DECL
@@ -16532,13 +16528,17 @@ cp_parser_decltype_expr (cp_parser *parser,
_msg,
   id_expr_start_token->location));
 
-  if (expr == error_mark_node)
-/* We found an id-expression, but it was something that we
-   should not have found. This is an error, not something
-   we can recover from, so note that we found an
-   id-expression and we'll recover as gracefully as
-   possible.  */
-id_expression_or_member_access_p = true;
+ if (error_msg)
+   {
+ /* We found an id-expression, but it was something that we
+should not have found. This is an error, not something
+we can recover from, so report the error we found and
+we'll recover as gracefully as possible.  */
+ cp_parser_parse_definitely (parser);
+ cp_parser_error (parser, error_msg);
+ id_expression_or_member_access_p = true;
+ return error_mark_node;
+   }
 }
 
   if (expr
diff --git a/gcc/testsuite/g++.dg/pr100482.C b/gcc/testsuite/g++.dg/pr100482.C
new file mode 100644
index 000..dcf6722fda5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr100482.C
@@ -0,0 +1,11 @@
+// { dg-do compile { target c++11 } }
+
+namespace N {}
+decltype(std) x;   // { dg-error "expected primary-expression" }
+
+struct S {};
+decltype(S) y;  // { dg-error "argument to .decltype. must be an expression" }
+
+template 
+struct U {};
+decltype(U) z;  // { dg-error "missing template arguments" }
-- 
2.40.0



[PATCH] c++: Fix ICE with parameter pack of decltype(auto) [PR103497]

2023-04-22 Thread Nathaniel Shead via Gcc-patches
Bootstrapped and tested on x86_64-pc-linux-gnu.

-- 8< --

This patch raises an error early when the decltype(auto) specifier is
used as a parameter of a function. This prevents any issues with an
unexpected tree type later on when performing the call.

PR 103497

gcc/cp/ChangeLog:

* parser.cc (cp_parser_simple_type_specifier): Add check for
decltype(auto) as function parameter.

gcc/testsuite/ChangeLog:

* g++.dg/pr103497.C: New test.

Signed-off-by: Nathaniel Shead 
---
 gcc/cp/parser.cc| 10 ++
 gcc/testsuite/g++.dg/pr103497.C |  7 +++
 2 files changed, 17 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/pr103497.C

diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index e5f032f2330..1415e07e152 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -19884,6 +19884,16 @@ cp_parser_simple_type_specifier (cp_parser* parser,
   && cp_lexer_peek_nth_token (parser->lexer, 2)->type != CPP_SCOPE)
 {
   type = saved_checks_value (token->u.tree_check_value);
+  /* Within a function parameter declaration, decltype(auto) is always an
+error.  */
+  if (parser->auto_is_implicit_function_template_parm_p
+ && TREE_CODE (type) == TEMPLATE_TYPE_PARM
+ && AUTO_IS_DECLTYPE (type))
+   {
+ error_at (token->location,
+   "cannot declare a parameter with %");
+ type = error_mark_node;
+   }
   if (decl_specs)
{
  cp_parser_set_decl_spec_type (decl_specs, type,
diff --git a/gcc/testsuite/g++.dg/pr103497.C b/gcc/testsuite/g++.dg/pr103497.C
new file mode 100644
index 000..bcd421c2907
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr103497.C
@@ -0,0 +1,7 @@
+// { dg-do compile { target c++14 } }
+
+void foo(decltype(auto)... args);  // { dg-error "parameter with 
.decltype.auto..|no parameter packs" }
+
+int main() {
+  foo();
+}
-- 
2.34.1



[Ping][PATCH] libstdc++: Add missing functions to [PR79700]

2023-04-17 Thread Nathaniel Shead via Gcc-patches
Hi, just checking whether there were any issues with this patch?
https://gcc.gnu.org/pipermail/gcc-patches/2023-February/612386.html

Otherwise I assume it won't be in GCC13.

Thanks,
Nathaniel


[PATCH v2 3/3] c++: Improve location information in constexpr evaluation

2023-03-28 Thread Nathaniel Shead via Gcc-patches
This patch caches the current expression's location information in the
constexpr_global_ctx struct, which allows subexpressions that have lost
location information to still provide accurate diagnostics. Also
rewrites a number of 'error' calls as 'error_at' to provide more
specific location information.

The primary effect of this change is that many errors within evaluation
of a constexpr function will now point at the offending expression (with
expansion tracing information) rather than just the outermost call.

gcc/cp/ChangeLog:

* constexpr.cc (constexpr_global_ctx): New field for cached
tree location, defaulting to input_location.
(cxx_eval_internal_function): Fall back to ctx->global->loc
rather than input_location.
(modifying_const_object_error): Likewise.
(cxx_eval_dynamic_cast_fn): Likewise.
(eval_and_check_array_index): Likewise.
(cxx_eval_array_reference): Likewise.
(cxx_eval_bit_field_ref): Likewise.
(cxx_eval_component_reference): Likewise.
(cxx_eval_indirect_ref): Likewise.
(cxx_eval_store_expression): Likewise.
(cxx_eval_increment_expression): Likewise.
(cxx_eval_loop_expr): Likewise.
(cxx_eval_binary_expression): Likewise.
(cxx_eval_constant_expression): Cache location of trees for use
in errors, and prefer it instead of input_location.

gcc/testsuite/ChangeLog:

* g++.dg/cpp0x/constexpr-48089.C: Updated diagnostic locations.
* g++.dg/cpp0x/constexpr-diag3.C: Likewise.
* g++.dg/cpp0x/constexpr-ice20.C: Likewise.
* g++.dg/cpp1y/constexpr-89481.C: Likewise.
* g++.dg/cpp1y/constexpr-lifetime1.C: Likewise.
* g++.dg/cpp1y/constexpr-lifetime2.C: Likewise.
* g++.dg/cpp1y/constexpr-lifetime3.C: Likewise.
* g++.dg/cpp1y/constexpr-lifetime4.C: Likewise.
* g++.dg/cpp1y/constexpr-lifetime5.C: Likewise.
* g++.dg/cpp1y/constexpr-union5.C: Likewise.
* g++.dg/cpp1y/pr68180.C: Likewise.
* g++.dg/cpp1z/constexpr-lambda6.C: Likewise.
* g++.dg/cpp2a/bit-cast11.C: Likewise.
* g++.dg/cpp2a/bit-cast12.C: Likewise.
* g++.dg/cpp2a/bit-cast14.C: Likewise.
* g++.dg/cpp2a/constexpr-98122.C: Likewise.
* g++.dg/cpp2a/constexpr-dynamic17.C: Likewise.
* g++.dg/cpp2a/constexpr-init1.C: Likewise.
* g++.dg/cpp2a/constexpr-new12.C: Likewise.
* g++.dg/cpp2a/constexpr-new3.C: Likewise.
* g++.dg/ext/constexpr-vla2.C: Likewise.
* g++.dg/ext/constexpr-vla3.C: Likewise.
* g++.dg/ubsan/pr63956.C: Likewise.

libstdc++/ChangeLog:

* testsuite/25_algorithms/equal/constexpr_neg.cc: Updated
diagnostics locations.

Signed-off-by: Nathaniel Shead 
---
 gcc/cp/constexpr.cc   | 83 +++
 gcc/testsuite/g++.dg/cpp0x/constexpr-48089.C  | 10 +--
 gcc/testsuite/g++.dg/cpp0x/constexpr-diag3.C  |  2 +-
 gcc/testsuite/g++.dg/cpp0x/constexpr-ice20.C  |  4 +-
 gcc/testsuite/g++.dg/cpp1y/constexpr-89481.C  |  3 +-
 .../g++.dg/cpp1y/constexpr-lifetime1.C|  1 +
 .../g++.dg/cpp1y/constexpr-lifetime2.C|  4 +-
 .../g++.dg/cpp1y/constexpr-lifetime3.C|  4 +-
 .../g++.dg/cpp1y/constexpr-lifetime4.C|  2 +-
 .../g++.dg/cpp1y/constexpr-lifetime5.C|  4 +-
 gcc/testsuite/g++.dg/cpp1y/constexpr-union5.C |  4 +-
 gcc/testsuite/g++.dg/cpp1y/pr68180.C  |  4 +-
 .../g++.dg/cpp1z/constexpr-lambda6.C  |  4 +-
 gcc/testsuite/g++.dg/cpp2a/bit-cast11.C   | 10 +--
 gcc/testsuite/g++.dg/cpp2a/bit-cast12.C   | 10 +--
 gcc/testsuite/g++.dg/cpp2a/bit-cast14.C   | 14 ++--
 gcc/testsuite/g++.dg/cpp2a/constexpr-98122.C  |  4 +-
 .../g++.dg/cpp2a/constexpr-dynamic17.C|  5 +-
 gcc/testsuite/g++.dg/cpp2a/constexpr-init1.C  |  5 +-
 gcc/testsuite/g++.dg/cpp2a/constexpr-new12.C  |  6 +-
 gcc/testsuite/g++.dg/cpp2a/constexpr-new3.C   | 10 +--
 gcc/testsuite/g++.dg/ext/constexpr-vla2.C |  4 +-
 gcc/testsuite/g++.dg/ext/constexpr-vla3.C |  4 +-
 gcc/testsuite/g++.dg/ubsan/pr63956.C  |  4 +-
 .../25_algorithms/equal/constexpr_neg.cc  |  7 +-
 25 files changed, 111 insertions(+), 101 deletions(-)

diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index bdbc12144a7..74045477a92 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -1165,10 +1165,12 @@ public:
   hash_set *modifiable;
   /* Number of heap VAR_DECL deallocations.  */
   unsigned heap_dealloc_count;
+  /* Current location in case subtree has no location information.  */
+  location_t loc;
   /* Constructor.  */
   constexpr_global_ctx ()
 : constexpr_ops_count (0), cleanups (NULL), modifiable (nullptr),
-  heap_dealloc_count (0) {}
+  heap_dealloc_count (0), loc (input_location) {}
 
  tree get_value (tree t)
   {
@@ -2113,7 +2115,7 @@ cxx_eval_internal_function (const constexpr_ctx *ctx, 
tree t,
 
 default:
   if (!ctx-

[PATCH v2 1/3] c++: Track lifetimes in constant evaluation [PR70331, PR96630, PR98675]

2023-03-28 Thread Nathaniel Shead via Gcc-patches
This adds rudimentary lifetime tracking in C++ constexpr contexts,
allowing the compiler to report errors with using values after their
backing has gone out of scope. We don't yet handle other ways of ending
lifetimes (e.g. explicit destructor calls).

PR c++/96630
PR c++/98675
PR c++/70331

gcc/cp/ChangeLog:

* constexpr.cc (constexpr_global_ctx::put_value): Mark value as
in lifetime.
(constexpr_global_ctx::remove_value): Mark value as expired.
(cxx_eval_call_expression): Remove comment that is no longer
applicable.
(non_const_var_error): Add check for expired values.
(cxx_eval_constant_expression): Add checks for expired values. Forget
local variables at end of bind expressions. Forget temporaries at end
of cleanup points.
* cp-tree.h (struct lang_decl_base): New flag to track expired values
in constant evaluation.
(DECL_EXPIRED_P): Access the new flag.
(SET_DECL_EXPIRED_P): Modify the new flag.
* module.cc (trees_out::lang_decl_bools): Write out the new flag.
(trees_in::lang_decl_bools): Read in the new flag.

gcc/testsuite/ChangeLog:

* g++.dg/cpp0x/constexpr-ice20.C: Update error raised by test.
* g++.dg/cpp1y/constexpr-lifetime1.C: New test.
* g++.dg/cpp1y/constexpr-lifetime2.C: New test.
* g++.dg/cpp1y/constexpr-lifetime3.C: New test.
* g++.dg/cpp1y/constexpr-lifetime4.C: New test.
* g++.dg/cpp1y/constexpr-lifetime5.C: New test.

Signed-off-by: Nathaniel Shead 
---
 gcc/cp/constexpr.cc   | 69 +++
 gcc/cp/cp-tree.h  | 10 ++-
 gcc/cp/module.cc  |  2 +
 gcc/testsuite/g++.dg/cpp0x/constexpr-ice20.C  |  2 +-
 .../g++.dg/cpp1y/constexpr-lifetime1.C| 13 
 .../g++.dg/cpp1y/constexpr-lifetime2.C| 20 ++
 .../g++.dg/cpp1y/constexpr-lifetime3.C| 13 
 .../g++.dg/cpp1y/constexpr-lifetime4.C| 11 +++
 .../g++.dg/cpp1y/constexpr-lifetime5.C| 11 +++
 9 files changed, 137 insertions(+), 14 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime1.C
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime2.C
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime3.C
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime4.C
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime5.C

diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index 3de60cfd0f8..bdbc12144a7 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -1185,10 +1185,22 @@ public:
   void put_value (tree t, tree v)
   {
 bool already_in_map = values.put (t, v);
+if (!already_in_map && DECL_P (t))
+  {
+   if (!DECL_LANG_SPECIFIC (t))
+ retrofit_lang_decl (t);
+   if (DECL_LANG_SPECIFIC (t))
+ SET_DECL_EXPIRED_P (t, false);
+  }
 if (!already_in_map && modifiable)
   modifiable->add (t);
   }
-  void remove_value (tree t) { values.remove (t); }
+  void remove_value (tree t)
+  {
+if (DECL_P (t) && DECL_LANG_SPECIFIC (t))
+  SET_DECL_EXPIRED_P (t, true);
+values.remove (t);
+  }
 };
 
 /* Helper class for constexpr_global_ctx.  In some cases we want to avoid
@@ -3157,10 +3169,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree 
t,
  for (tree save_expr : save_exprs)
ctx->global->remove_value (save_expr);
 
- /* Remove the parms/result from the values map.  Is it worth
-bothering to do this when the map itself is only live for
-one constexpr evaluation?  If so, maybe also clear out
-other vars from call, maybe in BIND_EXPR handling?  */
+ /* Remove the parms/result from the values map.  */
  ctx->global->remove_value (res);
  for (tree parm = parms; parm; parm = TREE_CHAIN (parm))
ctx->global->remove_value (parm);
@@ -5708,6 +5717,13 @@ non_const_var_error (location_t loc, tree r, bool 
fundef_p)
inform (DECL_SOURCE_LOCATION (r), "allocated here");
   return;
 }
+  if (DECL_EXPIRED_P (r))
+{
+  if (constexpr_error (loc, fundef_p, "accessing object outside its "
+  "lifetime"))
+   inform (DECL_SOURCE_LOCATION (r), "declared here");
+  return;
+}
   if (!constexpr_error (loc, fundef_p, "the value of %qD is not usable in "
"a constant expression", r))
 return;
@@ -7048,6 +7064,13 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, 
tree t,
  r = build_constructor (TREE_TYPE (t), NULL);
  TREE_CONSTANT (r) = true;
}
+  else if (DECL_EXPIRED_P (t))
+   {
+ if (!ctx->quiet)
+   non_const_var_error (loc, r, /*fundef_p*

[PATCH v2 0/3] c++: Track lifetimes in constant evaluation [PR70331, ...]

2023-03-28 Thread Nathaniel Shead via Gcc-patches
This is an update of the patch series at
https://gcc.gnu.org/pipermail/gcc-patches/2023-March/614759.html

The main change is modifying the first patch to store the "expired" flag
in the C++-specific lang_decl_base struct instead of tree_decl_common.
The second and third patches to improve diagnostic locations are
otherwise unchanged.

Bootstrapped and regression tested on x86_64 linux.

Nathaniel

---

Nathaniel Shead (3):
  c++: Track lifetimes in constant evaluation [PR70331,PR96630,PR98675]
  c++: Improve constexpr error for dangling local variables
  c++: Improve location information in constexpr evaluation

 gcc/cp/constexpr.cc   | 152 --
 gcc/cp/cp-tree.h  |  10 +-
 gcc/cp/module.cc  |   2 +
 gcc/cp/semantics.cc   |   5 +-
 gcc/cp/typeck.cc  |   5 +-
 gcc/testsuite/g++.dg/cpp0x/constexpr-48089.C  |  10 +-
 gcc/testsuite/g++.dg/cpp0x/constexpr-diag3.C  |   2 +-
 gcc/testsuite/g++.dg/cpp0x/constexpr-ice20.C  |   2 +-
 gcc/testsuite/g++.dg/cpp1y/constexpr-89481.C  |   3 +-
 .../g++.dg/cpp1y/constexpr-lifetime1.C|  14 ++
 .../g++.dg/cpp1y/constexpr-lifetime2.C|  20 +++
 .../g++.dg/cpp1y/constexpr-lifetime3.C|  13 ++
 .../g++.dg/cpp1y/constexpr-lifetime4.C|  11 ++
 .../g++.dg/cpp1y/constexpr-lifetime5.C|  11 ++
 gcc/testsuite/g++.dg/cpp1y/constexpr-union5.C |   4 +-
 gcc/testsuite/g++.dg/cpp1y/pr68180.C  |   4 +-
 .../g++.dg/cpp1z/constexpr-lambda6.C  |   4 +-
 gcc/testsuite/g++.dg/cpp2a/bit-cast11.C   |  10 +-
 gcc/testsuite/g++.dg/cpp2a/bit-cast12.C   |  10 +-
 gcc/testsuite/g++.dg/cpp2a/bit-cast14.C   |  14 +-
 gcc/testsuite/g++.dg/cpp2a/constexpr-98122.C  |   4 +-
 .../g++.dg/cpp2a/constexpr-dynamic17.C|   5 +-
 gcc/testsuite/g++.dg/cpp2a/constexpr-init1.C  |   5 +-
 gcc/testsuite/g++.dg/cpp2a/constexpr-new12.C  |   6 +-
 gcc/testsuite/g++.dg/cpp2a/constexpr-new3.C   |  10 +-
 gcc/testsuite/g++.dg/ext/constexpr-vla2.C |   4 +-
 gcc/testsuite/g++.dg/ext/constexpr-vla3.C |   4 +-
 gcc/testsuite/g++.dg/ubsan/pr63956.C  |   4 +-
 .../g++.dg/warn/Wreturn-local-addr-6.C|   3 -
 .../25_algorithms/equal/constexpr_neg.cc  |   7 +-
 30 files changed, 246 insertions(+), 112 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime1.C
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime2.C
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime3.C
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime4.C
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime5.C

-- 
2.34.1



[PATCH v2 2/3] c++: Improve constexpr error for dangling local variables

2023-03-28 Thread Nathaniel Shead via Gcc-patches
Currently, when typeck discovers that a return statement will refer to a
local variable it rewrites to return a null pointer. This causes the
error messages for using the return value in a constant expression to be
unhelpful, especially for reference return values.

This patch removes this "optimisation". Relying on this raises a warning
by default and causes UB anyway, so there should be no issue in doing
so. We also suppress additional warnings from later passes that detect
this as a dangling pointer, since we've already indicated this anyway.

gcc/cp/ChangeLog:

* semantics.cc (finish_return_stmt): Suppress dangling pointer
reporting on return statement if already reported.
* typeck.cc (check_return_expr): Don't set return expression to
zero for dangling addresses.

gcc/testsuite/ChangeLog:

* g++.dg/cpp1y/constexpr-lifetime5.C: Test reported message is
correct.
* g++.dg/warn/Wreturn-local-addr-6.C: Remove check for return
value optimisation.

Signed-off-by: Nathaniel Shead 
---
 gcc/cp/semantics.cc  | 5 -
 gcc/cp/typeck.cc | 5 +++--
 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime5.C | 4 ++--
 gcc/testsuite/g++.dg/warn/Wreturn-local-addr-6.C | 3 ---
 4 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 87c2e8a7111..14b4b7f4ce1 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -1246,7 +1246,10 @@ finish_return_stmt (tree expr)
 
   r = build_stmt (input_location, RETURN_EXPR, expr);
   if (no_warning)
-suppress_warning (r, OPT_Wreturn_type);
+{
+  suppress_warning (r, OPT_Wreturn_type);
+  suppress_warning (r, OPT_Wdangling_pointer_);
+}
   r = maybe_cleanup_point_expr_void (r);
   r = add_stmt (r);
 
diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
index afb956087ce..a7d642e2029 100644
--- a/gcc/cp/typeck.cc
+++ b/gcc/cp/typeck.cc
@@ -11235,8 +11235,9 @@ check_return_expr (tree retval, bool *no_warning)
   else if (!processing_template_decl
   && maybe_warn_about_returning_address_of_local (retval, loc)
   && INDIRECT_TYPE_P (valtype))
-   retval = build2 (COMPOUND_EXPR, TREE_TYPE (retval), retval,
-build_zero_cst (TREE_TYPE (retval)));
+   /* Suppress the Wdangling-pointer warning in the return statement
+  that would otherwise occur.  */
+   *no_warning = true;
 }
 
   if (processing_template_decl)
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime5.C 
b/gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime5.C
index a4bc71d890a..ad3ef579f63 100644
--- a/gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime5.C
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime5.C
@@ -1,11 +1,11 @@
 // { dg-do compile { target c++14 } }
 // { dg-options "-Wno-return-local-addr" }
 
-constexpr const int& id(int x) { return x; }
+constexpr const int& id(int x) { return x; }  // { dg-message "note: declared 
here" }
 
 constexpr bool test() {
   const int& y = id(3);
   return y == 3;
 }
 
-constexpr bool x = test();  // { dg-error "" }
+constexpr bool x = test();  // { dg-error "accessing object outside its 
lifetime" }
diff --git a/gcc/testsuite/g++.dg/warn/Wreturn-local-addr-6.C 
b/gcc/testsuite/g++.dg/warn/Wreturn-local-addr-6.C
index fae8b7e766f..ec8e241d83e 100644
--- a/gcc/testsuite/g++.dg/warn/Wreturn-local-addr-6.C
+++ b/gcc/testsuite/g++.dg/warn/Wreturn-local-addr-6.C
@@ -24,6 +24,3 @@ return_addr_local_as_intref (void)
 
   return (const intptr_t&)a;   // { dg-warning "\\\[-Wreturn-local-addr]" } */
 }
-
-/* Verify that the return value has been replaced with zero:
-  { dg-final { scan-tree-dump-times "return 0;" 2 "optimized" } } */
-- 
2.34.1



Re: [PATCH 1/3] c++: Track lifetimes in constant evaluation [PR70331, PR96630, PR98675]

2023-03-28 Thread Nathaniel Shead via Gcc-patches
On Tue, Mar 28, 2023 at 10:50 PM Jakub Jelinek  wrote:
>
> On Tue, Mar 28, 2023 at 10:32:28PM +1100, Nathaniel Shead via Gcc-patches 
> wrote:
> >   * tree-core.h (struct tree_decl_common): New flag to check if
> > value lifetime has expired.
> >   * tree.h (DECL_EXPIRED): Access the new flag.
> >   * print-tree.cc (print_node): Print the new flag.
> > --- a/gcc/tree-core.h
> > +++ b/gcc/tree-core.h
> > @@ -1834,7 +1834,10 @@ struct GTY(()) tree_decl_common {
> >/* In FIELD_DECL, this is DECL_NOT_FLEXARRAY.  */
> >unsigned int decl_not_flexarray : 1;
> >
> > -  /* 13 bits unused.  */
> > +  /* In VAR_DECL, PARM_DECL, or RESULT_DECL, this is DECL_EXPIRED.  */
> > +  unsigned int decl_expired_flag : 1;
> > +
> > +  /* 12 bits unused.  */
> >
> >/* UID for points-to sets, stable over copying from inlining.  */
> >unsigned int pt_uid;
> > --- a/gcc/tree.h
> > +++ b/gcc/tree.h
> > @@ -2697,6 +2697,12 @@ extern tree vector_element_bits_tree (const_tree);
> > ??? Need to figure out some way to check this isn't a PARM_DECL.  */
> >  #define DECL_INITIAL(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.initial)
> >
> > +/* Used in a VAR_DECL, PARM_DECL, or RESULT_DECL to indicate whether
> > +   this declaration is currently in lifetime for constant evaluation
> > +   purposes.  */
> > +#define DECL_EXPIRED(NODE) \
> > +  (DECL_COMMON_CHECK(NODE)->decl_common.decl_expired_flag)
> > +
> >  /* Holds the size of the datum, in bits, as a tree expression.
> > Need not be constant and may be null.  May be less than TYPE_SIZE
> > for a C++ FIELD_DECL representing a base class subobject with its
>
> While it is true that tree_decl_common has some spare bits, this support
> is for an implementation detail of the C++ FE and as such, I think it is
> highly preferred to use some bit in the lang specific data structures
> rather than wasting bits that we could need later on for things that will
> be needed in the middle-end.
> struct lang_decl_base I think also has 12 spare bits...
>
> Rest I'll defer to C++ maintainers (also whether this is appropriate now
> or should be deferred for GCC 14 stage1).
>
> Jakub
>

Thanks, I didn't notice that there were lang specific data structures;
I'll take a look at using that instead.

>From my point of view I was expecting this would be too late for GCC13
(especially since it should only affect already invalid code, and the
risk of false positives), but I'm happy either way.


[PATCH 2/3] c++: Improve constexpr error for dangling local variables

2023-03-28 Thread Nathaniel Shead via Gcc-patches
Currently, when typeck discovers that a return statement will refer to a
local variable it rewrites to return a null pointer. This causes the
error messages for using the return value in a constant expression to be
unhelpful, especially for reference return values.

This patch removes this "optimisation". Relying on this raises a warning
by default and causes UB anyway, so there should be no issue in doing
so. We also suppress additional warnings from later passes that detect
this as a dangling pointer, since we've already indicated this anyway.

gcc/cp/ChangeLog:

* semantics.cc (finish_return_stmt): Suppress dangling pointer
reporting on return statement if already reported.
* typeck.cc (check_return_expr): Don't set return expression to
zero for dangling addresses.

gcc/testsuite/ChangeLog:

* g++.dg/cpp1y/constexpr-lifetime5.C: Test reported message is
correct.
* g++.dg/warn/Wreturn-local-addr-6.C: Remove check for return
value optimisation.

Signed-off-by: Nathaniel Shead 
---
 gcc/cp/semantics.cc  | 5 -
 gcc/cp/typeck.cc | 5 +++--
 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime5.C | 4 ++--
 gcc/testsuite/g++.dg/warn/Wreturn-local-addr-6.C | 3 ---
 4 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 87c2e8a7111..14b4b7f4ce1 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -1246,7 +1246,10 @@ finish_return_stmt (tree expr)
 
   r = build_stmt (input_location, RETURN_EXPR, expr);
   if (no_warning)
-suppress_warning (r, OPT_Wreturn_type);
+{
+  suppress_warning (r, OPT_Wreturn_type);
+  suppress_warning (r, OPT_Wdangling_pointer_);
+}
   r = maybe_cleanup_point_expr_void (r);
   r = add_stmt (r);
 
diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
index afb956087ce..a7d642e2029 100644
--- a/gcc/cp/typeck.cc
+++ b/gcc/cp/typeck.cc
@@ -11235,8 +11235,9 @@ check_return_expr (tree retval, bool *no_warning)
   else if (!processing_template_decl
   && maybe_warn_about_returning_address_of_local (retval, loc)
   && INDIRECT_TYPE_P (valtype))
-   retval = build2 (COMPOUND_EXPR, TREE_TYPE (retval), retval,
-build_zero_cst (TREE_TYPE (retval)));
+   /* Suppress the Wdangling-pointer warning in the return statement
+  that would otherwise occur.  */
+   *no_warning = true;
 }
 
   if (processing_template_decl)
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime5.C 
b/gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime5.C
index a4bc71d890a..ad3ef579f63 100644
--- a/gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime5.C
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime5.C
@@ -1,11 +1,11 @@
 // { dg-do compile { target c++14 } }
 // { dg-options "-Wno-return-local-addr" }
 
-constexpr const int& id(int x) { return x; }
+constexpr const int& id(int x) { return x; }  // { dg-message "note: declared 
here" }
 
 constexpr bool test() {
   const int& y = id(3);
   return y == 3;
 }
 
-constexpr bool x = test();  // { dg-error "" }
+constexpr bool x = test();  // { dg-error "accessing object outside its 
lifetime" }
diff --git a/gcc/testsuite/g++.dg/warn/Wreturn-local-addr-6.C 
b/gcc/testsuite/g++.dg/warn/Wreturn-local-addr-6.C
index fae8b7e766f..ec8e241d83e 100644
--- a/gcc/testsuite/g++.dg/warn/Wreturn-local-addr-6.C
+++ b/gcc/testsuite/g++.dg/warn/Wreturn-local-addr-6.C
@@ -24,6 +24,3 @@ return_addr_local_as_intref (void)
 
   return (const intptr_t&)a;   // { dg-warning "\\\[-Wreturn-local-addr]" } */
 }
-
-/* Verify that the return value has been replaced with zero:
-  { dg-final { scan-tree-dump-times "return 0;" 2 "optimized" } } */
-- 
2.34.1



[PATCH 1/3] c++: Track lifetimes in constant evaluation [PR70331, PR96630, PR98675]

2023-03-28 Thread Nathaniel Shead via Gcc-patches
This adds rudimentary lifetime tracking in C++ constexpr contexts,
allowing the compiler to report errors with using values after their
backing has gone out of scope. We don't yet handle other ways of ending
lifetimes (e.g. explicit destructor calls).

PR c++/70331
PR c++/96630
PR c++/98675

gcc/cp/ChangeLog:

* constexpr.cc (constexpr_global_ctx::put_value): Mark value as
in lifetime.
(constexpr_global_ctx::remove_value): Mark value as expired.
(cxx_eval_call_expression): Remove comment that is no longer
applicable.
(non_const_var_error): Add check for expired values.
(cxx_eval_constant_expression): Add checks for expired values.
Forget local variables at end of bind expressions. Forget
temporaries at end of cleanup points.
* module.cc (trees_out::core_bools): Write out the new flag.
(trees_in::core_bools): Read in the new flag.

gcc/ChangeLog:

* tree-core.h (struct tree_decl_common): New flag to check if
value lifetime has expired.
* tree.h (DECL_EXPIRED): Access the new flag.
* print-tree.cc (print_node): Print the new flag.

gcc/testsuite/ChangeLog:

* g++.dg/cpp0x/constexpr-ice20.C: Update error raised by test.
* g++.dg/cpp1y/constexpr-lifetime1.C: New test.
* g++.dg/cpp1y/constexpr-lifetime2.C: New test.
* g++.dg/cpp1y/constexpr-lifetime3.C: New test.
* g++.dg/cpp1y/constexpr-lifetime4.C: New test.
* g++.dg/cpp1y/constexpr-lifetime5.C: New test.

Signed-off-by: Nathaniel Shead 
---
 gcc/cp/constexpr.cc   | 66 +++
 gcc/cp/module.cc  |  2 +
 gcc/print-tree.cc |  4 ++
 gcc/testsuite/g++.dg/cpp0x/constexpr-ice20.C  |  2 +-
 .../g++.dg/cpp1y/constexpr-lifetime1.C| 13 
 .../g++.dg/cpp1y/constexpr-lifetime2.C| 20 ++
 .../g++.dg/cpp1y/constexpr-lifetime3.C| 13 
 .../g++.dg/cpp1y/constexpr-lifetime4.C| 11 
 .../g++.dg/cpp1y/constexpr-lifetime5.C| 11 
 gcc/tree-core.h   |  5 +-
 gcc/tree.h|  6 ++
 11 files changed, 138 insertions(+), 15 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime1.C
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime2.C
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime3.C
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime4.C
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime5.C

diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index 3de60cfd0f8..28e3f891fb8 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -1185,10 +1185,17 @@ public:
   void put_value (tree t, tree v)
   {
 bool already_in_map = values.put (t, v);
+if (!already_in_map && DECL_P (t))
+  DECL_EXPIRED (t) = false;
 if (!already_in_map && modifiable)
   modifiable->add (t);
   }
-  void remove_value (tree t) { values.remove (t); }
+  void remove_value (tree t)
+  {
+if (DECL_P (t))
+  DECL_EXPIRED (t) = true;
+values.remove (t);
+  }
 };
 
 /* Helper class for constexpr_global_ctx.  In some cases we want to avoid
@@ -3157,10 +3164,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree 
t,
  for (tree save_expr : save_exprs)
ctx->global->remove_value (save_expr);
 
- /* Remove the parms/result from the values map.  Is it worth
-bothering to do this when the map itself is only live for
-one constexpr evaluation?  If so, maybe also clear out
-other vars from call, maybe in BIND_EXPR handling?  */
+ /* Remove the parms/result from the values map.  */
  ctx->global->remove_value (res);
  for (tree parm = parms; parm; parm = TREE_CHAIN (parm))
ctx->global->remove_value (parm);
@@ -5708,6 +5712,13 @@ non_const_var_error (location_t loc, tree r, bool 
fundef_p)
inform (DECL_SOURCE_LOCATION (r), "allocated here");
   return;
 }
+  if (DECL_EXPIRED (r))
+{
+  if (constexpr_error (loc, fundef_p, "accessing object outside its "
+  "lifetime"))
+   inform (DECL_SOURCE_LOCATION (r), "declared here");
+  return;
+}
   if (!constexpr_error (loc, fundef_p, "the value of %qD is not usable in "
"a constant expression", r))
 return;
@@ -6995,7 +7006,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, 
tree t,
   else
{
  if (!ctx->quiet)
-   error ("%qE is not a constant expression", t);
+   non_const_var_error (loc, t, /*fundef_p*/false);
  *non_constant_p = true;
}
   break;
@@ -7048,6 +7059,13 @@ cxx_eval_constant_expression (const 

[PATCH 3/3] c++: Improve location information in constexpr evaluation

2023-03-28 Thread Nathaniel Shead via Gcc-patches
This patch caches the current expression's location information in the
constexpr_global_ctx struct, which allows subexpressions that have lost
location information to still provide accurate diagnostics. Also
rewrites a number of  'error' calls as 'error_at' to provide more
specific location information.

The primary effect of this change is that many errors within evaluation
of a constexpr function will now point at the offending expression (with
expansion tracing information) rather than just the outermost call.

gcc/cp/ChangeLog:

* constexpr.cc (constexpr_global_ctx): New field for cached
tree location, defaulting to input_location.
(cxx_eval_internal_function): Fall back to ctx->global->loc
rather than input_location.
(modifying_const_object_error): Likewise.
(cxx_eval_dynamic_cast_fn): Likewise.
(eval_and_check_array_index): Likewise.
(cxx_eval_array_reference): Likewise.
(cxx_eval_bit_field_ref): Likewise.
(cxx_eval_component_reference): Likewise.
(cxx_eval_indirect_ref): Likewise.
(cxx_eval_store_expression): Likewise.
(cxx_eval_increment_expression): Likewise.
(cxx_eval_loop_expr): Likewise.
(cxx_eval_binary_expression): Likewise.
(cxx_eval_constant_expression): Cache location of trees for use
in errors, and prefer it instead of input_location.

gcc/testsuite/ChangeLog:

* g++.dg/cpp0x/constexpr-48089.C: Updated diagnostic locations.
* g++.dg/cpp0x/constexpr-diag3.C: Likewise.
* g++.dg/cpp0x/constexpr-ice20.C: Likewise.
* g++.dg/cpp1y/constexpr-89481.C: Likewise.
* g++.dg/cpp1y/constexpr-lifetime1.C: Likewise.
* g++.dg/cpp1y/constexpr-lifetime2.C: Likewise.
* g++.dg/cpp1y/constexpr-lifetime3.C: Likewise.
* g++.dg/cpp1y/constexpr-lifetime4.C: Likewise.
* g++.dg/cpp1y/constexpr-lifetime5.C: Likewise.
* g++.dg/cpp1y/constexpr-union5.C: Likewise.
* g++.dg/cpp1y/pr68180.C: Likewise.
* g++.dg/cpp1z/constexpr-lambda6.C: Likewise.
* g++.dg/cpp2a/bit-cast11.C: Likewise.
* g++.dg/cpp2a/bit-cast12.C: Likewise.
* g++.dg/cpp2a/bit-cast14.C: Likewise.
* g++.dg/cpp2a/constexpr-98122.C: Likewise.
* g++.dg/cpp2a/constexpr-dynamic17.C: Likewise.
* g++.dg/cpp2a/constexpr-init1.C: Likewise.
* g++.dg/cpp2a/constexpr-new12.C: Likewise.
* g++.dg/cpp2a/constexpr-new3.C: Likewise.
* g++.dg/ext/constexpr-vla2.C: Likewise.
* g++.dg/ext/constexpr-vla3.C: Likewise.
* g++.dg/ubsan/pr63956.C: Likewise.

libstdc++/ChangeLog:

* testsuite/25_algorithms/equal/constexpr_neg.cc: Updated
diagnostics locations.

Signed-off-by: Nathaniel Shead 
---
 gcc/cp/constexpr.cc   | 83 +++
 gcc/testsuite/g++.dg/cpp0x/constexpr-48089.C  | 10 +--
 gcc/testsuite/g++.dg/cpp0x/constexpr-diag3.C  |  2 +-
 gcc/testsuite/g++.dg/cpp0x/constexpr-ice20.C  |  4 +-
 gcc/testsuite/g++.dg/cpp1y/constexpr-89481.C  |  3 +-
 .../g++.dg/cpp1y/constexpr-lifetime1.C|  1 +
 .../g++.dg/cpp1y/constexpr-lifetime2.C|  4 +-
 .../g++.dg/cpp1y/constexpr-lifetime3.C|  4 +-
 .../g++.dg/cpp1y/constexpr-lifetime4.C|  2 +-
 .../g++.dg/cpp1y/constexpr-lifetime5.C|  4 +-
 gcc/testsuite/g++.dg/cpp1y/constexpr-union5.C |  4 +-
 gcc/testsuite/g++.dg/cpp1y/pr68180.C  |  4 +-
 .../g++.dg/cpp1z/constexpr-lambda6.C  |  4 +-
 gcc/testsuite/g++.dg/cpp2a/bit-cast11.C   | 10 +--
 gcc/testsuite/g++.dg/cpp2a/bit-cast12.C   | 10 +--
 gcc/testsuite/g++.dg/cpp2a/bit-cast14.C   | 14 ++--
 gcc/testsuite/g++.dg/cpp2a/constexpr-98122.C  |  4 +-
 .../g++.dg/cpp2a/constexpr-dynamic17.C|  5 +-
 gcc/testsuite/g++.dg/cpp2a/constexpr-init1.C  |  5 +-
 gcc/testsuite/g++.dg/cpp2a/constexpr-new12.C  |  6 +-
 gcc/testsuite/g++.dg/cpp2a/constexpr-new3.C   | 10 +--
 gcc/testsuite/g++.dg/ext/constexpr-vla2.C |  4 +-
 gcc/testsuite/g++.dg/ext/constexpr-vla3.C |  4 +-
 gcc/testsuite/g++.dg/ubsan/pr63956.C  |  4 +-
 .../25_algorithms/equal/constexpr_neg.cc  |  7 +-
 25 files changed, 111 insertions(+), 101 deletions(-)

diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index 28e3f891fb8..31884220b4e 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -1165,10 +1165,12 @@ public:
   hash_set *modifiable;
   /* Number of heap VAR_DECL deallocations.  */
   unsigned heap_dealloc_count;
+  /* Current location in case subtree has no location information.  */
+  location_t loc;
   /* Constructor.  */
   constexpr_global_ctx ()
 : constexpr_ops_count (0), cleanups (NULL), modifiable (nullptr),
-  heap_dealloc_count (0) {}
+  heap_dealloc_count (0), loc (input_location) {}
 
  tree get_value (tree t)
   {
@@ -2108,7 +2110,7 @@ cxx_eval_internal_function (const constexpr_ctx *ctx, 
tree t,
 
 default:
   if (!ctx-

[PATCH 0/3] Track lifetimes in constant evaluation [PR70331,...]

2023-03-28 Thread Nathaniel Shead via Gcc-patches
The first patch fixes PR70331, PR96630, and PR98675 regarding
constexpr evaluation not correctly diagnosing uses of dangling
references and pointers. The following two patches clean up and improve
some of the errors that are generated by this change, but aren't
strictly necessary.

This is my first change to the frontend, so any feedback is welcome. In
particular, I'm not sure if the way I went about the fix was correct:
for simplicity and efficiency's sake I added a new flag to
tree_decl_common, but this feels somewhat overkill for what is otherwise
a very locally useful property. 

Another option here would be to add a new lookup table to
constexpr_global_ctx which tracks what decls are in lifetime, but I
expect that to negatively impact performance. I haven't done any
benchmarks on this however.

Bootstrapped and regression tested on x86_64 linux.

---

Nathaniel Shead (3):
  c++: Track lifetimes in constant evaluation [PR70331,PR96630,PR98675]
  c++: Improve constexpr error for dangling local variables
  c++: Improve location information in constexpr evaluation

 gcc/cp/constexpr.cc   | 149 --
 gcc/cp/module.cc  |   2 +
 gcc/cp/semantics.cc   |   5 +-
 gcc/cp/typeck.cc  |   5 +-
 gcc/print-tree.cc |   4 +
 gcc/testsuite/g++.dg/cpp0x/constexpr-48089.C  |  10 +-
 gcc/testsuite/g++.dg/cpp0x/constexpr-diag3.C  |   2 +-
 gcc/testsuite/g++.dg/cpp0x/constexpr-ice20.C  |   2 +-
 gcc/testsuite/g++.dg/cpp1y/constexpr-89481.C  |   3 +-
 .../g++.dg/cpp1y/constexpr-lifetime1.C|  14 ++
 .../g++.dg/cpp1y/constexpr-lifetime2.C|  20 +++
 .../g++.dg/cpp1y/constexpr-lifetime3.C|  13 ++
 .../g++.dg/cpp1y/constexpr-lifetime4.C|  11 ++
 .../g++.dg/cpp1y/constexpr-lifetime5.C|  11 ++
 gcc/testsuite/g++.dg/cpp1y/constexpr-union5.C |   4 +-
 gcc/testsuite/g++.dg/cpp1y/pr68180.C  |   4 +-
 .../g++.dg/cpp1z/constexpr-lambda6.C  |   4 +-
 gcc/testsuite/g++.dg/cpp2a/bit-cast11.C   |  10 +-
 gcc/testsuite/g++.dg/cpp2a/bit-cast12.C   |  10 +-
 gcc/testsuite/g++.dg/cpp2a/bit-cast14.C   |  14 +-
 gcc/testsuite/g++.dg/cpp2a/constexpr-98122.C  |   4 +-
 .../g++.dg/cpp2a/constexpr-dynamic17.C|   5 +-
 gcc/testsuite/g++.dg/cpp2a/constexpr-init1.C  |   5 +-
 gcc/testsuite/g++.dg/cpp2a/constexpr-new12.C  |   6 +-
 gcc/testsuite/g++.dg/cpp2a/constexpr-new3.C   |  10 +-
 gcc/testsuite/g++.dg/ext/constexpr-vla2.C |   4 +-
 gcc/testsuite/g++.dg/ext/constexpr-vla3.C |   4 +-
 gcc/testsuite/g++.dg/ubsan/pr63956.C  |   4 +-
 .../g++.dg/warn/Wreturn-local-addr-6.C|   3 -
 gcc/tree-core.h   |   5 +-
 gcc/tree.h|   6 +
 .../25_algorithms/equal/constexpr_neg.cc  |   7 +-
 32 files changed, 247 insertions(+), 113 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime1.C
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime2.C
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime3.C
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime4.C
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime5.C

-- 
2.34.1



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

2023-03-17 Thread Nathaniel Shead via Gcc-patches
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(...)`?

> +
> +  VERIFY( v2 == v );
> +}
> +
> +int main()
> +{
> +  test01();
> +}
> --
> 2.39.2
>


Re: [PATCH] libstdc++: Add missing functions to [PR79700]

2023-02-21 Thread Nathaniel Shead via Gcc-patches
On Mon, Feb 20, 2023 at 12:08:38PM +, Jonathan Wakely wrote:
> On Mon, 20 Feb 2023 at 11:57, Nathaniel Shead  
> wrote:
> >
> > On Mon, Feb 20, 2023 at 10:30 PM Jonathan Wakely  wrote:
> > >
> > > On Mon, 20 Feb 2023 at 11:23, Nathaniel Shead via Libstdc++
> > >  wrote:
> > > >
> > > > The comments on PR79700 mentioned that it was somewhat ambiguous whether
> > > > these functions were supposed to exist for C++11 or not. I chose to add
> > > > them there, since other resources (such as cppreference) seem to think
> > > > that C++11 should be the standard these functions were introduced, and I
> > > > don't know of any reason to do otherwise.
> > > >
> > > > Tested on x86_64-linux.
> > >
> > > Thanks for the patch, but this needs tests for the new declarations
> > > (which are tedious to write, which is the main reason I haven't
> > > already pushed my own very similar patch).
> > >
> >
> > Ah OK, fair enough. Where should the tests go? The only tests I could
> > find for the existing (non -f/l) functions was just tests for their
> > existence in testsuite/26_numerics/headers/cmath/functions_std_c++17.cc
> > which I just added the new functions to - I guess I'll add a new file
> > here and test that all the functions can be called and give the same
> > results as the relevant overloaded variants?
> 
> Yeah, that sounds great, thanks!
> 

How does this look?

-- 8< --

This patch adds the -f and -l variants of the C89  functions to
 under namespace std (so std::sqrtf, std::fabsl, etc.) for C++11
and up.

libstdc++-v3/ChangeLog:

PR libstdc++/79700
* include/c_global/cmath (acosf, acosl, asinf, asinl, atanf,
atanl, atan2f, atan2l, ceilf, ceill, cosf, cosl, coshf, coshl,
expf, expl, fabsf, fabsl, floorf, floorl, fmodf, fmodl, frexpf,
frexpl, ldexpf, ldexpl, logf, logl, log10f, log10l, modff,
modfl, powf, powl, sinf, sinl, sinhf, sinhl, sqrtf, sqrtl, tanf,
tanl, tanhf, tanhl): Add aliases in namespace std.
* testsuite/26_numerics/headers/cmath/equivalent_functions.cc:
New test.
* testsuite/26_numerics/headers/cmath/functions_std_c++17.cc:
Add checks for existence of above names.

Signed-off-by: Nathaniel Shead 
---
 libstdc++-v3/include/c_global/cmath   | 111 +
 .../headers/cmath/equivalent_functions.cc | 224 ++
 .../headers/cmath/functions_std_c++17.cc  |  45 
 3 files changed, 380 insertions(+)
 create mode 100644 
libstdc++-v3/testsuite/26_numerics/headers/cmath/equivalent_functions.cc

diff --git a/libstdc++-v3/include/c_global/cmath 
b/libstdc++-v3/include/c_global/cmath
index 568eb354c2d..eaebde33dee 100644
--- a/libstdc++-v3/include/c_global/cmath
+++ b/libstdc++-v3/include/c_global/cmath
@@ -1767,6 +1767,117 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 #if __cplusplus >= 201103L
 
+#undef acosf
+#undef acosl
+#undef asinf
+#undef asinl
+#undef atanf
+#undef atanl
+#undef atan2f
+#undef atan2l
+#undef ceilf
+#undef ceill
+#undef cosf
+#undef cosl
+#undef coshf
+#undef coshl
+#undef expf
+#undef expl
+#undef fabsf
+#undef fabsl
+#undef floorf
+#undef floorl
+#undef fmodf
+#undef fmodl
+#undef frexpf
+#undef frexpl
+#undef ldexpf
+#undef ldexpl
+#undef logf
+#undef logl
+#undef log10f
+#undef log10l
+#undef modff
+#undef modfl
+#undef powf
+#undef powl
+#undef sinf
+#undef sinl
+#undef sinhf
+#undef sinhl
+#undef sqrtf
+#undef sqrtl
+#undef tanf
+#undef tanl
+#undef tanhf
+#undef tanhl
+
+  using ::acosf;
+  using ::acosl;
+
+  using ::asinf;
+  using ::asinl;
+
+  using ::atanf;
+  using ::atanl;
+
+  using ::atan2f;
+  using ::atan2l;
+
+  using ::ceilf;
+  using ::ceill;
+
+  using ::cosf;
+  using ::cosl;
+
+  using ::coshf;
+  using ::coshl;
+
+  using ::expf;
+  using ::expl;
+
+  using ::fabsf;
+  using ::fabsl;
+
+  using ::floorf;
+  using ::floorl;
+
+  using ::fmodf;
+  using ::fmodl;
+
+  using ::frexpf;
+  using ::frexpl;
+
+  using ::ldexpf;
+  using ::ldexpl;
+
+  using ::logf;
+  using ::logl;
+
+  using ::log10f;
+  using ::log10l;
+
+  using ::modff;
+  using ::modfl;
+
+  using ::powf;
+  using ::powl;
+
+  using ::sinf;
+  using ::sinl;
+
+  using ::sinhf;
+  using ::sinhl;
+
+  using ::sqrtf;
+  using ::sqrtl;
+
+  using ::tanf;
+  using ::tanl;
+
+  using ::tanhf;
+  using ::tanhl;
+
 #ifdef _GLIBCXX_USE_C99_MATH_TR1
 
 #undef acosh
diff --git 
a/libstdc++-v3/testsuite/26_numerics/headers/cmath/equivalent_functions.cc 
b/libstdc++-v3/testsuite/26_numerics/headers/cmath/equivalent_functions.cc
new file mode 100644
index 000..8639279e8a1
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/headers/cmath/equivalent_functions.cc
@@ -0,0 +1,224 @@
+// Copyright (C) 2023 Free Software Foundation, Inc.
+//
+// 

Re: [PATCH] libstdc++: Add missing functions to [PR79700]

2023-02-20 Thread Nathaniel Shead via Gcc-patches
On Mon, Feb 20, 2023 at 10:30 PM Jonathan Wakely  wrote:
>
> On Mon, 20 Feb 2023 at 11:23, Nathaniel Shead via Libstdc++
>  wrote:
> >
> > The comments on PR79700 mentioned that it was somewhat ambiguous whether
> > these functions were supposed to exist for C++11 or not. I chose to add
> > them there, since other resources (such as cppreference) seem to think
> > that C++11 should be the standard these functions were introduced, and I
> > don't know of any reason to do otherwise.
> >
> > Tested on x86_64-linux.
>
> Thanks for the patch, but this needs tests for the new declarations
> (which are tedious to write, which is the main reason I haven't
> already pushed my own very similar patch).
>

Ah OK, fair enough. Where should the tests go? The only tests I could
find for the existing (non -f/l) functions was just tests for their
existence in testsuite/26_numerics/headers/cmath/functions_std_c++17.cc
which I just added the new functions to - I guess I'll add a new file
here and test that all the functions can be called and give the same
results as the relevant overloaded variants?

>
> >
> > -- 8< --
> >
> > This patch adds the -f and -l variants of the C89  functions to
> >  under namespace std (so std::sqrtf, std::fabsl, etc.) for C++11
> > and up.
> >
> > libstdc++-v3/ChangeLog:
> >
> > PR libstdc++/79700
> > * include/c_global/cmath (acosf, acosl, asinf, asinl, atanf,
> > atanl, atan2f, atan2l, ceilf, ceill, cosf, cosl, coshf, coshl,
> > expf, expl, fabsf, fabsl, floorf, floorl, fmodf, fmodl, frexpf,
> > frexpl, ldexpf, ldexpl, logf, logl, log10f, log10l, modff,
> > modfl, powf, powl, sinf, sinl, sinhf, sinhl, sqrtf, sqrtl, tanf,
> > tanl, tanhf, tanhl): Add aliases in namespace std.
> > * testsuite/26_numerics/headers/cmath/functions_std_c++17.cc:
> > Add checks for existence of above names.
> >
> > Signed-off-by: Nathaniel Shead 
> > ---
> >  libstdc++-v3/include/c_global/cmath   | 111 ++
> >  .../headers/cmath/functions_std_c++17.cc  |  45 +++
> >  2 files changed, 156 insertions(+)
> >
> > diff --git a/libstdc++-v3/include/c_global/cmath 
> > b/libstdc++-v3/include/c_global/cmath
> > index 568eb354c2d..eaebde33dee 100644
> > --- a/libstdc++-v3/include/c_global/cmath
> > +++ b/libstdc++-v3/include/c_global/cmath
> > @@ -1767,6 +1767,117 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> >
> >  #if __cplusplus >= 201103L
> >
> > +#undef acosf
> > +#undef acosl
> > +#undef asinf
> > +#undef asinl
> > +#undef atanf
> > +#undef atanl
> > +#undef atan2f
> > +#undef atan2l
> > +#undef ceilf
> > +#undef ceill
> > +#undef cosf
> > +#undef cosl
> > +#undef coshf
> > +#undef coshl
> > +#undef expf
> > +#undef expl
> > +#undef fabsf
> > +#undef fabsl
> > +#undef floorf
> > +#undef floorl
> > +#undef fmodf
> > +#undef fmodl
> > +#undef frexpf
> > +#undef frexpl
> > +#undef ldexpf
> > +#undef ldexpl
> > +#undef logf
> > +#undef logl
> > +#undef log10f
> > +#undef log10l
> > +#undef modff
> > +#undef modfl
> > +#undef powf
> > +#undef powl
> > +#undef sinf
> > +#undef sinl
> > +#undef sinhf
> > +#undef sinhl
> > +#undef sqrtf
> > +#undef sqrtl
> > +#undef tanf
> > +#undef tanl
> > +#undef tanhf
> > +#undef tanhl
> > +
> > +  using ::acosf;
> > +  using ::acosl;
> > +
> > +  using ::asinf;
> > +  using ::asinl;
> > +
> > +  using ::atanf;
> > +  using ::atanl;
> > +
> > +  using ::atan2f;
> > +  using ::atan2l;
> > +
> > +  using ::ceilf;
> > +  using ::ceill;
> > +
> > +  using ::cosf;
> > +  using ::cosl;
> > +
> > +  using ::coshf;
> > +  using ::coshl;
> > +
> > +  using ::expf;
> > +  using ::expl;
> > +
> > +  using ::fabsf;
> > +  using ::fabsl;
> > +
> > +  using ::floorf;
> > +  using ::floorl;
> > +
> > +  using ::fmodf;
> > +  using ::fmodl;
> > +
> > +  using ::frexpf;
> > +  using ::frexpl;
> > +
> > +  using ::ldexpf;
> > +  using ::ldexpl;
> > +
> > +  using ::logf;
> > +  using ::logl;
> > +
> > +  using ::log10f;
> > +  using ::log10l;
> > +
> > +  using ::modff;
> > +  using ::modfl;
> > +
> > +  using ::powf;
> > +  using ::powl;
> > +
> > +  using :

[PATCH] libstdc++: Add missing functions to [PR79700]

2023-02-20 Thread Nathaniel Shead via Gcc-patches
The comments on PR79700 mentioned that it was somewhat ambiguous whether
these functions were supposed to exist for C++11 or not. I chose to add
them there, since other resources (such as cppreference) seem to think
that C++11 should be the standard these functions were introduced, and I
don't know of any reason to do otherwise.

Tested on x86_64-linux.

-- 8< --

This patch adds the -f and -l variants of the C89  functions to
 under namespace std (so std::sqrtf, std::fabsl, etc.) for C++11
and up.

libstdc++-v3/ChangeLog:

PR libstdc++/79700
* include/c_global/cmath (acosf, acosl, asinf, asinl, atanf,
atanl, atan2f, atan2l, ceilf, ceill, cosf, cosl, coshf, coshl,
expf, expl, fabsf, fabsl, floorf, floorl, fmodf, fmodl, frexpf,
frexpl, ldexpf, ldexpl, logf, logl, log10f, log10l, modff,
modfl, powf, powl, sinf, sinl, sinhf, sinhl, sqrtf, sqrtl, tanf,
tanl, tanhf, tanhl): Add aliases in namespace std.
* testsuite/26_numerics/headers/cmath/functions_std_c++17.cc:
Add checks for existence of above names.

Signed-off-by: Nathaniel Shead 
---
 libstdc++-v3/include/c_global/cmath   | 111 ++
 .../headers/cmath/functions_std_c++17.cc  |  45 +++
 2 files changed, 156 insertions(+)

diff --git a/libstdc++-v3/include/c_global/cmath 
b/libstdc++-v3/include/c_global/cmath
index 568eb354c2d..eaebde33dee 100644
--- a/libstdc++-v3/include/c_global/cmath
+++ b/libstdc++-v3/include/c_global/cmath
@@ -1767,6 +1767,117 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 #if __cplusplus >= 201103L
 
+#undef acosf
+#undef acosl
+#undef asinf
+#undef asinl
+#undef atanf
+#undef atanl
+#undef atan2f
+#undef atan2l
+#undef ceilf
+#undef ceill
+#undef cosf
+#undef cosl
+#undef coshf
+#undef coshl
+#undef expf
+#undef expl
+#undef fabsf
+#undef fabsl
+#undef floorf
+#undef floorl
+#undef fmodf
+#undef fmodl
+#undef frexpf
+#undef frexpl
+#undef ldexpf
+#undef ldexpl
+#undef logf
+#undef logl
+#undef log10f
+#undef log10l
+#undef modff
+#undef modfl
+#undef powf
+#undef powl
+#undef sinf
+#undef sinl
+#undef sinhf
+#undef sinhl
+#undef sqrtf
+#undef sqrtl
+#undef tanf
+#undef tanl
+#undef tanhf
+#undef tanhl
+
+  using ::acosf;
+  using ::acosl;
+
+  using ::asinf;
+  using ::asinl;
+
+  using ::atanf;
+  using ::atanl;
+
+  using ::atan2f;
+  using ::atan2l;
+
+  using ::ceilf;
+  using ::ceill;
+
+  using ::cosf;
+  using ::cosl;
+
+  using ::coshf;
+  using ::coshl;
+
+  using ::expf;
+  using ::expl;
+
+  using ::fabsf;
+  using ::fabsl;
+
+  using ::floorf;
+  using ::floorl;
+
+  using ::fmodf;
+  using ::fmodl;
+
+  using ::frexpf;
+  using ::frexpl;
+
+  using ::ldexpf;
+  using ::ldexpl;
+
+  using ::logf;
+  using ::logl;
+
+  using ::log10f;
+  using ::log10l;
+
+  using ::modff;
+  using ::modfl;
+
+  using ::powf;
+  using ::powl;
+
+  using ::sinf;
+  using ::sinl;
+
+  using ::sinhf;
+  using ::sinhl;
+
+  using ::sqrtf;
+  using ::sqrtl;
+
+  using ::tanf;
+  using ::tanl;
+
+  using ::tanhf;
+  using ::tanhl;
+
 #ifdef _GLIBCXX_USE_C99_MATH_TR1
 
 #undef acosh
diff --git 
a/libstdc++-v3/testsuite/26_numerics/headers/cmath/functions_std_c++17.cc 
b/libstdc++-v3/testsuite/26_numerics/headers/cmath/functions_std_c++17.cc
index 3b4ada1a756..c6ec636c183 100644
--- a/libstdc++-v3/testsuite/26_numerics/headers/cmath/functions_std_c++17.cc
+++ b/libstdc++-v3/testsuite/26_numerics/headers/cmath/functions_std_c++17.cc
@@ -44,6 +44,51 @@ namespace gnu
   using std::tan;
   using std::tanh;
 
+  using std::acosf;
+  using std::acosl;
+  using std::asinf;
+  using std::asinl;
+  using std::atanf;
+  using std::atanl;
+  using std::atan2f;
+  using std::atan2l;
+  using std::ceilf;
+  using std::ceill;
+  using std::cosf;
+  using std::cosl;
+  using std::coshf;
+  using std::coshl;
+  using std::expf;
+  using std::expl;
+  using std::fabsf;
+  using std::fabsl;
+  using std::floorf;
+  using std::floorl;
+  using std::fmodf;
+  using std::fmodl;
+  using std::frexpf;
+  using std::frexpl;
+  using std::ldexpf;
+  using std::ldexpl;
+  using std::logf;
+  using std::logl;
+  using std::log10f;
+  using std::log10l;
+  using std::modff;
+  using std::modfl;
+  using std::powf;
+  using std::powl;
+  using std::sinf;
+  using std::sinl;
+  using std::sinhf;
+  using std::sinhl;
+  using std::sqrtf;
+  using std::sqrtl;
+  using std::tanf;
+  using std::tanl;
+  using std::tanhf;
+  using std::tanhl;
+
   using std::assoc_laguerre;
   using std::assoc_laguerref;
   using std::assoc_laguerrel;
-- 
2.34.1



[PATCH 2/2] libstdc++: Implement P1413R3 'deprecate aligned_storage and aligned_union'

2022-12-28 Thread Nathaniel Shead via Gcc-patches
These two patches implement P1413 (deprecate std::aligned_storage and
std::aligned_union) for C++23. Tested on x86_64-linux.

-- >8 --

Adds deprecated attributes for C++23, and makes use of it for
std::aligned_storage, std::aligned_storage_t, std::aligned_union, and
std::aligned_union_t.

libstdc++-v3/ChangeLog:

* doc/doxygen/user.cfg.in (PREDEFINED): Add new macros.
* include/bits/c++config (_GLIBCXX23_DEPRECATED)
(_GLIBCXX23_DEPRECATED_SUGGEST): New macros.
* include/std/type_traits (aligned_storage, aligned_union)
(aligned_storage_t, aligned_union_t): Deprecate for C++23.
* testsuite/20_util/aligned_storage/deprecated-2b.cc: New test.
* testsuite/20_util/aligned_union/deprecated-2b.cc: New test.

Signed-off-by: Nathaniel Shead 
---
 libstdc++-v3/doc/doxygen/user.cfg.in  |  2 ++
 libstdc++-v3/include/bits/c++config   | 10 +++
 libstdc++-v3/include/std/type_traits  | 17 +---
 .../20_util/aligned_storage/deprecated-2b.cc  | 26 +++
 .../20_util/aligned_union/deprecated-2b.cc| 26 +++
 5 files changed, 77 insertions(+), 4 deletions(-)
 create mode 100644 
libstdc++-v3/testsuite/20_util/aligned_storage/deprecated-2b.cc
 create mode 100644 
libstdc++-v3/testsuite/20_util/aligned_union/deprecated-2b.cc

diff --git a/libstdc++-v3/doc/doxygen/user.cfg.in 
b/libstdc++-v3/doc/doxygen/user.cfg.in
index fc46e722529..31613f51517 100644
--- a/libstdc++-v3/doc/doxygen/user.cfg.in
+++ b/libstdc++-v3/doc/doxygen/user.cfg.in
@@ -2396,6 +2396,8 @@ PREDEFINED = __cplusplus=202002L \
  "_GLIBCXX17_DEPRECATED_SUGGEST(E)= " \
  "_GLIBCXX20_DEPRECATED= " \
  "_GLIBCXX20_DEPRECATED_SUGGEST(E)= " \
+ "_GLIBCXX23_DEPRECATED= " \
+ "_GLIBCXX23_DEPRECATED_SUGGEST(E)= " \
  _GLIBCXX17_INLINE=inline \
  _GLIBCXX_CHRONO_INT64_T=int64_t \
  _GLIBCXX_DEFAULT_ABI_TAG \
diff --git a/libstdc++-v3/include/bits/c++config 
b/libstdc++-v3/include/bits/c++config
index d2b0cfa15ce..7cec5d3de2d 100644
--- a/libstdc++-v3/include/bits/c++config
+++ b/libstdc++-v3/include/bits/c++config
@@ -86,6 +86,8 @@
 //   _GLIBCXX17_DEPRECATED_SUGGEST( string-literal )
 //   _GLIBCXX20_DEPRECATED
 //   _GLIBCXX20_DEPRECATED_SUGGEST( string-literal )
+//   _GLIBCXX23_DEPRECATED
+//   _GLIBCXX23_DEPRECATED_SUGGEST( string-literal )
 #ifndef _GLIBCXX_USE_DEPRECATED
 # define _GLIBCXX_USE_DEPRECATED 1
 #endif
@@ -131,6 +133,14 @@
 # define _GLIBCXX20_DEPRECATED_SUGGEST(ALT)
 #endif
 
+#if defined(__DEPRECATED) && (__cplusplus >= 202100L)
+# define _GLIBCXX23_DEPRECATED [[__deprecated__]]
+# define _GLIBCXX23_DEPRECATED_SUGGEST(ALT) _GLIBCXX_DEPRECATED_SUGGEST(ALT)
+#else
+# define _GLIBCXX23_DEPRECATED
+# define _GLIBCXX23_DEPRECATED_SUGGEST(ALT)
+#endif
+
 // Macros for ABI tag attributes.
 #ifndef _GLIBCXX_ABI_TAG_CXX11
 # define _GLIBCXX_ABI_TAG_CXX11 __attribute ((__abi_tag__ ("cxx11")))
diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 2f4d4bb8d4d..9df833e82be 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -2088,10 +2088,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  type shall be a POD type suitable for use as uninitialized
*  storage for any object whose size is at most _Len and whose
*  alignment is a divisor of _Align.
+   *
+   *  @deprecated Deprecated in C++23. Uses can be replaced by an
+   *  array std::byte[_Len] declared with alignas(_Align).
   */
   template::__type)>
-struct aligned_storage
+struct
+_GLIBCXX23_DEPRECATED
+aligned_storage
 {
   union type
   {
@@ -2127,9 +2132,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  least size _Len.
*
*  @see aligned_storage
+   *
+   *  @deprecated Deprecated in C++23.
*/
   template 
-struct aligned_union
+struct
+_GLIBCXX23_DEPRECATED
+aligned_union
 {
 private:
   static_assert(sizeof...(_Types) != 0, "At least one type is required");
@@ -2580,10 +2589,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   /// Alias template for aligned_storage
   template::__type)>
-using aligned_storage_t = typename aligned_storage<_Len, _Align>::type;
+using aligned_storage_t _GLIBCXX23_DEPRECATED = typename 
aligned_storage<_Len, _Align>::type;
 
   template 
-using aligned_union_t = typename aligned_union<_Len, _Types...>::type;
+using aligned_union_t _GLIBCXX23_DEPRECATED = typename aligned_union<_Len, 
_Types...>::type;
 
   /// Alias template for decay
   template
diff --git a/libstdc++-v3/testsuite/20_util/aligned_storage/deprecated-2b.cc 
b/libstdc++-v3/testsuite/20_util/aligned_storage/depre

[PATCH 1/2] libstdc++: Normalise _GLIBCXX20_DEPRECATED macro

2022-12-28 Thread Nathaniel Shead via Gcc-patches
These two patches implement P1413 (deprecate std::aligned_storage and
std::aligned_union) for C++23. Tested on x86_64-linux.

-- >8 --

Updates _GLIBCXX20_DEPRECATED to be defined and behave the same as the
versions for other standards (e.g. _GLIBCXX17_DEPRECATED).

libstdc++-v3/ChangeLog:

* doc/doxygen/user.cfg.in (PREDEFINED): Update macros.
* include/bits/c++config (_GLIBCXX20_DEPRECATED): Make
consistent with other 'deprecated' macros.
* include/std/type_traits (is_pod, is_pod_v): Use
_GLIBCXX20_DEPRECATED_SUGGEST instead.

Signed-off-by: Nathaniel Shead 
---
 libstdc++-v3/doc/doxygen/user.cfg.in | 4 ++--
 libstdc++-v3/include/bits/c++config  | 6 +++---
 libstdc++-v3/include/std/type_traits | 4 ++--
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/libstdc++-v3/doc/doxygen/user.cfg.in 
b/libstdc++-v3/doc/doxygen/user.cfg.in
index 834ad9e4fd5..fc46e722529 100644
--- a/libstdc++-v3/doc/doxygen/user.cfg.in
+++ b/libstdc++-v3/doc/doxygen/user.cfg.in
@@ -2394,8 +2394,8 @@ PREDEFINED = __cplusplus=202002L \
  "_GLIBCXX11_DEPRECATED_SUGGEST(E)= " \
  "_GLIBCXX17_DEPRECATED= " \
  "_GLIBCXX17_DEPRECATED_SUGGEST(E)= " \
- "_GLIBCXX20_DEPRECATED(E)= " \
- "_GLIBCXX20_DEPRECATED(E)= " \
+ "_GLIBCXX20_DEPRECATED= " \
+ "_GLIBCXX20_DEPRECATED_SUGGEST(E)= " \
  _GLIBCXX17_INLINE=inline \
  _GLIBCXX_CHRONO_INT64_T=int64_t \
  _GLIBCXX_DEFAULT_ABI_TAG \
diff --git a/libstdc++-v3/include/bits/c++config 
b/libstdc++-v3/include/bits/c++config
index 50406066afe..d2b0cfa15ce 100644
--- a/libstdc++-v3/include/bits/c++config
+++ b/libstdc++-v3/include/bits/c++config
@@ -84,7 +84,7 @@
 //   _GLIBCXX14_DEPRECATED_SUGGEST( string-literal )
 //   _GLIBCXX17_DEPRECATED
 //   _GLIBCXX17_DEPRECATED_SUGGEST( string-literal )
-//   _GLIBCXX20_DEPRECATED( string-literal )
+//   _GLIBCXX20_DEPRECATED
 //   _GLIBCXX20_DEPRECATED_SUGGEST( string-literal )
 #ifndef _GLIBCXX_USE_DEPRECATED
 # define _GLIBCXX_USE_DEPRECATED 1
@@ -124,10 +124,10 @@
 #endif
 
 #if defined(__DEPRECATED) && (__cplusplus >= 202002L)
-# define _GLIBCXX20_DEPRECATED(MSG) [[deprecated(MSG)]]
+# define _GLIBCXX20_DEPRECATED [[__deprecated__]]
 # define _GLIBCXX20_DEPRECATED_SUGGEST(ALT) _GLIBCXX_DEPRECATED_SUGGEST(ALT)
 #else
-# define _GLIBCXX20_DEPRECATED(MSG)
+# define _GLIBCXX20_DEPRECATED
 # define _GLIBCXX20_DEPRECATED_SUGGEST(ALT)
 #endif
 
diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 5dc9e1b2921..2f4d4bb8d4d 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -815,7 +815,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // Could use is_standard_layout && is_trivial instead of the builtin.
   template
 struct
-_GLIBCXX20_DEPRECATED("use is_standard_layout && is_trivial instead")
+_GLIBCXX20_DEPRECATED_SUGGEST("is_standard_layout && is_trivial")
 is_pod
 : public integral_constant
 {
@@ -3210,7 +3210,7 @@ template 
 template 
   inline constexpr bool is_standard_layout_v = __is_standard_layout(_Tp);
 template 
-  _GLIBCXX20_DEPRECATED("use is_standard_layout_v && is_trivial_v instead")
+  _GLIBCXX20_DEPRECATED_SUGGEST("is_standard_layout_v && is_trivial_v")
   inline constexpr bool is_pod_v = __is_pod(_Tp);
 template 
   _GLIBCXX17_DEPRECATED
-- 
2.34.1



Re: [PATCH] libstdc++: Set active union member in constexpr std::string [PR103295]

2022-11-11 Thread Nathaniel Shead via Gcc-patches
Thanks for that. I'll keep your comments in mind for the future.

On Fri, Nov 11, 2022 at 05:59:33PM +, Jonathan Wakely wrote:
> On Fri, 11 Nov 2022 at 17:55, Patrick Palka  wrote:
> >
> > On Fri, 11 Nov 2022, Jonathan Wakely via Libstdc++ wrote:
> >
> > > On Fri, 11 Nov 2022 at 11:23, Nathaniel Shead via Libstdc++
> > >  wrote:
> > > >
> > > > Hi,
> > > >
> > > > Below is a patch to fix std::string in constexpr contexts on Clang. This
> > > > was originally fixed in the commits attached to PR103295, but a later
> > > > commit 98a0d72a seems to have mistakenly undone this.
> > > >
> > > > Tested on x86_64-linux. Verified using clang-14 and clang-15 that the
> > > > fix works. I haven't added anything to the test suite, since this issue
> > > > is only detected by clang.
> > > >
> > > > This is my first time contributing, so please let me know if I've done
> > > > anything wrong or missed something. Thanks!
> > >
> > > Thanks for the patch, I'll get this committed today.
> > >
> > > The only thing I had to fix was the indentation in the commit log. The
> > > second line of the ChangeLog should be aligned with the * not the text
> > > following it (so indented by a single tab).
> > >
> > >
> > > >
> > > > Nathaniel
> > > >
> > > > -- >8 --
> > > >
> > > > Clang still complains about using std::string in constexpr contexts due
> > > > to the changes made in commit 98a0d72a. This patch ensures that we set
> > > > the active member of the union as according to [class.union.general] p6.
> > > >
> > > > libstdc++-v3/ChangeLog:
> > > >
> > > > PR libstdc++/103295
> > > > * include/bits/basic_string.h (_M_use_local_data): Set active
> > > >   member to _M_local_buf.
> > > >
> > > > Signed-off-by: Nathaniel Shead 
> > > > ---
> > > >  libstdc++-v3/include/bits/basic_string.h | 4 ++--
> > > >  1 file changed, 2 insertions(+), 2 deletions(-)
> > > >
> > > > diff --git a/libstdc++-v3/include/bits/basic_string.h 
> > > > b/libstdc++-v3/include/bits/basic_string.h
> > > > index 9c2b57f5a1d..2790fd49b05 100644
> > > > --- a/libstdc++-v3/include/bits/basic_string.h
> > > > +++ b/libstdc++-v3/include/bits/basic_string.h
> > > > @@ -352,8 +352,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
> > > >{
> > > >  #if __cpp_lib_is_constant_evaluated
> > > > if (std::is_constant_evaluated())
> > > > - for (_CharT& __c : _M_local_buf)
> > > > -   __c = _CharT();
> > > > + for (size_type i = 0; i <= _S_local_capacity; ++i)
> > > > +   _M_local_buf[i] = _CharT();
> >
> > Just a minor nit, but we should probably uglify i to __i here.
> 
> Good catch, thanks. Fixed and pushed.
> 


[PATCH] libstdc++: Set active union member in constexpr std::string [PR103295]

2022-11-11 Thread Nathaniel Shead via Gcc-patches
Hi,

Below is a patch to fix std::string in constexpr contexts on Clang. This
was originally fixed in the commits attached to PR103295, but a later
commit 98a0d72a seems to have mistakenly undone this.

Tested on x86_64-linux. Verified using clang-14 and clang-15 that the
fix works. I haven't added anything to the test suite, since this issue
is only detected by clang.

This is my first time contributing, so please let me know if I've done
anything wrong or missed something. Thanks!

Nathaniel

-- >8 --

Clang still complains about using std::string in constexpr contexts due
to the changes made in commit 98a0d72a. This patch ensures that we set
the active member of the union as according to [class.union.general] p6.

libstdc++-v3/ChangeLog:

PR libstdc++/103295
* include/bits/basic_string.h (_M_use_local_data): Set active
  member to _M_local_buf.

Signed-off-by: Nathaniel Shead 
---
 libstdc++-v3/include/bits/basic_string.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/include/bits/basic_string.h 
b/libstdc++-v3/include/bits/basic_string.h
index 9c2b57f5a1d..2790fd49b05 100644
--- a/libstdc++-v3/include/bits/basic_string.h
+++ b/libstdc++-v3/include/bits/basic_string.h
@@ -352,8 +352,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
   {
 #if __cpp_lib_is_constant_evaluated
if (std::is_constant_evaluated())
- for (_CharT& __c : _M_local_buf)
-   __c = _CharT();
+ for (size_type i = 0; i <= _S_local_capacity; ++i)
+   _M_local_buf[i] = _CharT();
 #endif
return _M_local_data();
   }
-- 
2.34.1



<    1   2   3