On 01/12/20 09:59 +0100, Jakub Jelinek wrote:
Hi!
While std::source_location::current () is static consteval source_location
current() noexcept; in the standard, it also says with LWG3396:
"Any call to current that appears as a default member initializer
([class.mem]), or as a subexpression thereof, should correspond to the
location of the constructor definition or aggregate initialization that uses
the default member initializer. Any call to current that appears as a
default argument ([dcl.fct.default]), or as a subexpression thereof, should
correspond to the location of the invocation of the function that uses the
default argument ([expr.call])."
so it must work as compiler magic rather than normal immediate functions,
in particular we need to defer its evaluation when parsing default arguments
or nsdmis.
The following patch implements that.
Nice.
Bootstrapped/regtested on x86_64-linux and i686-linux.
Jon, does it fix all the library testcases you and JeanHeyd had?
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__);
assert( s0.loc.line() == s0.line );
assert( !__builtin_strcmp(s0.loc.file_name(), __FILE__) );
assert( !__builtin_strcmp(s0.loc.function_name(), __FUNCTION__) );
}
The location is the constructor parameter list, but it should be in
main() where the default argument is evaluated.
JeanHeyd's test also verify that the function_name() for the NSDMI
cases is "s::s" but that fails because __FUNCTION__ is only "s".
I mentioned in PR 80780 that a __builtin__PRETTY_FUNCTION would have
been nice, because __FUNCTION__ isn't very useful for C++, because of
overloading and namespace/class scopes. There are an unlimited number
of functions that have __FUNCTION__ == "s", e.g. "ns::s(int)" and
"ns::s()" and "another_scope::s::s<T...>(T...)" etc.
Since __builtin_source_location() can do whatever it wants (without
needing to add __builtin__PRETTY_FUNCTION) it might be nice to use the
__PRETTY_FUNCTION__ string. JeanHeyd's tests would still need changes,
because the name would be "s::s(void*)" not "s::s" but that still
seems better for users.