On Tue, Oct 22, 2019 at 11:20 AM Jakub Jelinek <ja...@redhat.com> wrote: > > On Tue, Oct 22, 2019 at 10:57:42AM -0400, Jason Merrill wrote: > > > So, do you prefer to do it the other way during build_cxx_call? > > > > It seems more straightforward. > > Ok. > > > > 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. > > Well, [expr.const]/(10.4) contains an example that requires it to work: > consteval int f() { return 42; } > consteval auto g() { return f; } > consteval int h(int (*p)() = g()) { return p(); } > constexpr int r = h(); // OK > constexpr auto e = g(); // ill-formed: a pointer to an immediate function is > // not a permitted result of a constant expression > When parsing the g() expression as default argument, we don't know it will > be a default argument of a consteval function.
g() is in immediate function context because h is consteval; clearly we can't rely on current_function_decl for that. The standard says immediate function context is when "its innermost non-block scope is a function parameter scope of an immediate function", which is the case here. > > > 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. > > But in that case whether the temporary is created or not is no longer an > implementation detail, so is it clear and can be clarified in the standard > that a temporary must be created, so that other implementations will handle > it the same? Yes, I've already sent mail to the list. Jason