On Tue, Oct 22, 2019 at 10:41 AM Jakub Jelinek <ja...@redhat.com> wrote:
>
> On Tue, Oct 22, 2019 at 09:55:06AM -0400, Jason Merrill wrote:
> > On Mon, Oct 21, 2019 at 1:59 PM Jason Merrill <ja...@redhat.com> wrote:
> > > On 10/15/19 1:04 PM, Jakub Jelinek wrote:
> >
> > > > Unlike the previous implementation, this doesn't invoke consteval 
> > > > function
> > > > already during parsing, but later on, so there aren't issues with say
> > > > consteval constructors or consteval in default arguments.
> > >
> > > Right, we can't immediately evaluate a class prvalue before we know what
> > > object it's initializing.
> >
> > Actually, I'm not sure about this.  There's no way to consistently
> > know what object is being initialized soon enough for the evaluation
> > to be immediate, so I think we need to always create a temporary for
> > immediate invocations of class type, so we could go ahead and do
> > immediate evaluation in build_cxx_call.  I think this also follows
> > from an immediate invocation being a full-expression.
>
> So, do you prefer to do it the other way during build_cxx_call?

It seems more straightforward.

> The issues that need to be resolved are the default arguments,
> which from my understanding are not full expressions and thus for them we do
> not know whether they will appear in immediate function context or not,
> so would we need some global flag (in_default_argument?) and just don't
> handle it in build_cxx_call if it is set, and then have something like
> cxx_eval_consteval in the recent patch invoked on the default arguments
> before adding it to function calls?

It seems to me that an immediate invocation in a default argument is
not in immediate function context, so we can handle it normally.  The
only reason we need to handle immediate function context specially is
to allow uses of parameters of the immediate function in calls to
other immediate functions, and we can't refer to parameters in a
default argument anyway.

> How would I create a temporary into which construct the var?

The build_cplus_new in build_cxx_call creates a TARGET_EXPR,
evaluating that should be sufficient.  Note that you'll need to change
the condition there so that the decltype semantics don't apply to
immediate functions.

> Wouldn't it affect also what constructors are invoked?  Say if some class
> has consteval constructor with int argument and non-consteval copy
> constructor:
> struct S { consteval S (int x) : s (x) {} S (const S &); int s; };
> should
> void foo () { S s = 5; }
> then invoke first the consteval ctor constructing some temporary and then
> the copy constructor?

Yes, I think that follows.

> And last, wouldn't handling it in build_cxx_call already affect then
> discarded statements?  The patch I posted today would most likely not
> consteval evaluate much in discarded contexts, perhaps with the exception
> of variable initializers.  But build_cxx_call is called even if
> in_discarded_stmt, right?  Aren't some constant expressions evaluated even
> in discarded statements though?
> constexpr bool foo (int i) { if (i == 1) throw 1; return i == 0; }
> template <typename T>
> void
> foo ()
> {
>   if constexpr (foo (2))
>     {
>       if constexpr (foo (1))
>         ;
>     }
> }
> so, shouldn't immediate functions be called too?

Yes, true.  I wasn't thinking of non-dependent discarded statements.

Jason

Reply via email to