[PATCH] c++: Implement LWG3396 Clarify point of reference for source_location::current() [PR80780, PR93093]

Jonathan Wakely jwakely@redhat.com
Tue Dec 1 13:03:52 GMT 2020


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.




More information about the Gcc-patches mailing list