On Thu, 3 Apr 2025, Jason Merrill wrote:

> On 4/2/25 2:28 PM, Patrick Palka wrote:
> > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look
> > OK for trunk/14?
> 
> OK for 14.
> 
> For 15, what happens if we remove that error entirely?  Do we still give other
> errors in that case?  That seems to be the expectation of
> https://eel.is/c++draft/basic.scope.param#note-1 and I'd expect that in a
> constant-evaluated (and therefore evaluated) context we would complain about
> it not being constant.

Indeed, it seems we do reliably error elsewhere if we remove that error,
e.g. for parse/parameter-declaration-2.C we instead emit give:

  error: size of array ‘p’ is not an integral constant-expression

But regtesting revealed that error path is also used to disambiguate
vexing parses -- removing it causes us to now reject parse/ambig7.C:

  parse/ambig7.C:16:36: error: no matching function for call to 
‘Helper::Helper(int, <unresolved overloaded function type>)’

So I guess we can't remove it outright just yet.

> 
> I think the current rule that corresponds to that error is
> https://eel.is/c++draft/basic.def.odr#10 -- odr-using a variable that isn't
> odr-usable.  process_outer_var_ref/mark_use make that distinction for
> variables from an enclosing function, but I think for references outside of
> any function constant-evaluation should handle it.
> 
> > -- >8 --
> > 
> > Here we wrongly reject the requires-expression requirement at parse time
> > due to the use of the constraint variable 't' within a template argument
> > (an evaluated context).  Fix this simply by refining the "use of parameter
> > outside function body" code path to exclude constraint variables.
> > 
> > PR c++/104255 tracks the same issue for function parameters, but fixing
> > that would be more involved, requiring changes to the PARM_DECL case of
> > tsubst_expr.
> > 
> >     PR c++/117849
> > 
> > gcc/cp/ChangeLog:
> > 
> >     * semantics.cc (finish_id_expression_1): Allow use of constraint
> >     variable outside in an evaluated context.
> > 
> > gcc/testsuite/ChangeLog:
> > 
> >     * g++.dg/cpp2a/concepts-requires41.C: New test.
> > ---
> >   gcc/cp/semantics.cc                           |  1 +
> >   .../g++.dg/cpp2a/concepts-requires41.C        | 23 +++++++++++++++++++
> >   2 files changed, 24 insertions(+)
> >   create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-requires41.C
> > 
> > diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
> > index 7d8beb8833d..a10ef34383c 100644
> > --- a/gcc/cp/semantics.cc
> > +++ b/gcc/cp/semantics.cc
> > @@ -4755,6 +4755,7 @@ finish_id_expression_1 (tree id_expression,
> >      body, except inside an unevaluated context (i.e. decltype).  */
> >         if (TREE_CODE (decl) == PARM_DECL
> >       && DECL_CONTEXT (decl) == NULL_TREE
> > +     && !CONSTRAINT_VAR_P (decl)
> >       && !cp_unevaluated_operand
> >       && !processing_contract_condition
> >       && !processing_omp_trait_property_expr)
> > diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-requires41.C
> > b/gcc/testsuite/g++.dg/cpp2a/concepts-requires41.C
> > new file mode 100644
> > index 00000000000..840ed86c4ac
> > --- /dev/null
> > +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-requires41.C
> > @@ -0,0 +1,23 @@
> > +// PR c++/117849
> > +// { dg-do compile { target c++20 } }
> > +
> > +template<int N> struct array {
> > +  constexpr int size() const { return N; }
> > +};
> > +
> > +struct vector {
> > +  int _size = 3;
> > +  constexpr int size() const { return _size; }
> > +};
> > +
> > +template<int N> struct integral_constant {
> > +  constexpr operator int() const { return N; }
> > +};
> > +
> > +template<class T>
> > +concept StaticSize = requires (T& t) {
> > +  typename integral_constant<t.size()>;
> > +};
> > +
> > +static_assert(StaticSize<array<5>>);
> > +static_assert(!StaticSize<vector>);
> 
> 

Reply via email to