On Tue, Dec 01, 2020 at 01:03:52PM +0000, Jonathan Wakely wrote: > Most of them pass now, but this case fails: > > using namespace std; > > struct S { > const char* func; > unsigned line = 0; > source_location loc = source_location::current(); > > S(int l, source_location loc = source_location::current()) > : func(__FUNCTION__), line(l), loc(loc) // values of loc will be from > call-site > {} > > S(void*) > : func(__FUNCTION__), line(__LINE__) // values of loc should be hereabouts > {} > }; > > int main() > { > S s0(__LINE__); >// ... > }
Ah, I see what is going on here. using namespace std; struct S { const char *func; unsigned line = 0; source_location loc = source_location::current (); S (int l, source_location); S (void *) : func(__FUNCTION__), line(__LINE__) // values of loc should be hereabouts {} }; S::S (int l, source_location loc = source_location::current ()) : func(__FUNCTION__), line(l), loc(loc) // values of loc will be from call-site {} int main () { S s0(__LINE__); ///... } would work fine. We have (since this patch, but before that it was already mostly like that too): && DECL_IMMEDIATE_FUNCTION_P (fndecl) && cp_unevaluated_operand == 0 && (current_function_decl == NULL_TREE || !DECL_IMMEDIATE_FUNCTION_P (current_function_decl)) && (current_binding_level->kind != sk_function_parms || (!current_binding_level->immediate_fn_ctx_p && !source_location_current_p (fndecl))) && (!parsing_nsdmi () || !source_location_current_p (fndecl))) as the condition whether to evaluate an immediate function right away or not. The intent is do not evaluate it in default arguments of immediate functions (will be done at constant expression evaluation time instead), and (newly) for std::source_location::current () not evaluated in nsdmis and in default arguments. The problem is that with your/JeanHeyd's testcase above, the default argument parsing is deferred until the whole class is parsed and then cp_parser_late_parsing_default_args performs that deferred parsing. Except at this point nothing creates the sk_function_params scope. So, I think we need some way for the build_over_call code to know if it is called from within cp_parser_late_parsing_default_args and whether for an immediate function or not, and take that into account too. I see cp_parser_late_parsing_default_args calls push_defarg_context, so perhaps it could check default_arg_context vector, except that convert_default_arg calls that too around calling break_out_target_exprs which in the patch is used to perform the late evaluation of the std::source_location::current() calls. So it might need to temporarily pop_defarg_context before break_out_target_exprs and push it again? Jason, any thoughts on that? And guess we need some tests if it works as expected also in templates; I bet we create scope for the default params in that case, but I could be wrong. Thanks Jakub