public inbox for libstdc++@gcc.gnu.org
 help / color / mirror / Atom feed
* [ PATCH ] [ C++ ] [ libstdc++ ] P1208r6 Merge source_location
@ 2019-12-27 19:27 JeanHeyd Meneide
  2019-12-27 19:33 ` Jakub Jelinek
  0 siblings, 1 reply; 8+ messages in thread
From: JeanHeyd Meneide @ 2019-12-27 19:27 UTC (permalink / raw)
  To: gcc-patches, libstdc++, Jonathan Wakely, Jakub Jelinek

[-- Attachment #1: Type: text/plain, Size: 804 bytes --]

     This patch implements std::source_location. There's a couple
cases where the builtin implemented does not do what is expected of
it, and so the bottom 3 batches of test cases fails. I'm still
including the patch so that others can pick up on what might need to
change about the __builtin_source_location implementation (CC:
Jonathan Wakely, Jakub Jelinek).

2019-12-27  JeanHeyd "ThePhD" Meneide  <phdofthehouse@gmail.com>

        * include/Makefile.in: add source_location header
        * include/bits/c++config: Add new detection macros for
          LINE, COLUMN, and SOURCE_LOCATION builtins.
        * include/std/source_location: New.
        * testuite/std/support/srcloc/std.n4842.C (new): test source_location
        * testuite/std/support/srcloc/std.n4842.h (new): test source_location

[-- Attachment #2: p1208r6.patch.txt --]
[-- Type: text/plain, Size: 14601 bytes --]

diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index 6300de9e96d..fc593c7c461 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -70,6 +70,7 @@ std_headers = \
 	${std_srcdir}/scoped_allocator \
 	${std_srcdir}/set \
 	${std_srcdir}/shared_mutex \
+	${std_srcdir}/source_location \
 	${std_srcdir}/span \
 	${std_srcdir}/sstream \
 	${std_srcdir}/stack \
diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in
index ae4a493ea65..c104ffb28ab 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -414,6 +414,7 @@ std_headers = \
 	${std_srcdir}/scoped_allocator \
 	${std_srcdir}/set \
 	${std_srcdir}/shared_mutex \
+	${std_srcdir}/source_location \
 	${std_srcdir}/span \
 	${std_srcdir}/sstream \
 	${std_srcdir}/stack \
diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config
index 7ccfc5f199d..2d2ec96a925 100644
--- a/libstdc++-v3/include/bits/c++config
+++ b/libstdc++-v3/include/bits/c++config
@@ -630,6 +630,7 @@ namespace std
 
 #if __GNUC__ >= 7
 // Assume these are available if the compiler claims to be a recent GCC:
+# define _GLIBCXX_HAVE_BUILTIN_LINE 1
 # define _GLIBCXX_HAVE_BUILTIN_HAS_UNIQ_OBJ_REP 1
 # define _GLIBCXX_HAVE_BUILTIN_IS_AGGREGATE 1
 # define _GLIBCXX_HAVE_BUILTIN_LAUNDER 1
@@ -637,6 +638,9 @@ namespace std
 # if __GNUC__ >= 9
 #  define _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED 1
 # endif
+# if __GNUC__ >= 10
+#  define _GLIBCXX_HAVE_BUILTIN_SOURCE_LOCATION 1
+# endif
 #elif defined(__is_identifier) && defined(__has_builtin)
 // For non-GNU compilers:
 # if ! __is_identifier(__has_unique_object_representations)
@@ -654,6 +658,15 @@ namespace std
 # if ! __is_identifier(__is_same)
 #  define _GLIBCXX_BUILTIN_IS_SAME_AS(T, U) __is_same(T, U)
 # endif
+# if __has_builtin(__builtin_source_location)
+#  define _GLIBCXX_HAVE_BUILTIN_SOURCE_LOCATION 1
+# endif
+# if __has_builtin(__builtin_LINE)
+#  define _GLIBCXX_HAVE_BUILTIN_LINE 1
+# endif
+# if __has_builtin(__builtin_COLUMN)
+#  define _GLIBCXX_HAVE_BUILTIN_COLUMN 1
+# endif
 #endif // GCC
 
 // PSTL configuration
diff --git a/libstdc++-v3/include/std/source_location b/libstdc++-v3/include/std/source_location
new file mode 100644
index 00000000000..3bf219efa81
--- /dev/null
+++ b/libstdc++-v3/include/std/source_location
@@ -0,0 +1,172 @@
+// Component for retrieving function, line and column source info. -*- C++ -*-
+
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file source_location
+ *  This is a Standard C++ Library header.
+ */
+
+//
+// P1208 source_location library
+// Contributed by ThePhD with <3
+//
+
+#ifndef _GLIBCXX_SOURCE_LOCATION
+#define _GLIBCXX_SOURCE_LOCATION 1
+
+#pragma GCC system_header
+
+#if __cplusplus > 201703L
+
+#include <bits/c++config.h>
+#include <cstdint>
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+#define __cpp_lib_source_location 201907L
+
+// use by-pointer for GCC-style __builtin_source_location;
+// use by-value for Clang-style builtins.
+#ifdef _GLIBCXX_HAVE_BUILTIN_SOURCE_LOCATION
+
+  struct source_location
+  {
+  private:
+    struct __impl
+    {
+      const char *_M_file_name;
+      const char *_M_function_name;
+      unsigned int _M_line, _M_column;
+    };
+
+  public:
+    static consteval source_location
+    current (const void *__src_loc_impl =
+	       __builtin_source_location ()) noexcept
+    {
+      source_location __ret;
+      __ret._M_data = static_cast<const __impl *>(__src_loc_impl);
+      return __ret;
+    }
+
+    constexpr
+    source_location () noexcept
+    : _M_data ()
+    { }
+
+    constexpr const char *
+    file_name () const noexcept
+    { return _M_data ? _M_data->_M_file_name : ""; }
+
+    constexpr const char *
+    function_name () const noexcept
+    { return _M_data ? _M_data->_M_function_name : ""; }
+
+    constexpr uint_least32_t
+    line () const noexcept
+    { return _M_data ? _M_data->_M_line : 0; }
+  
+    constexpr uint_least32_t
+    column () const noexcept
+    { return _M_data ? _M_data->_M_column : 0; }
+
+  private:
+    const __impl *_M_data;
+  };
+
+#elif defined(_GLIBCXX_HAVE_BUILTIN_LINE)
+
+  struct source_location
+  {
+  private:
+    struct __impl
+    {
+      const char *_M_file_name;
+      const char *_M_function_name;
+      uint_least32_t _M_line, _M_column;
+    };
+
+  public:
+    static consteval source_location
+    current (uint_least32_t __line = __builtin_LINE (),
+#ifdef _GLIBCXX_HAVE_BUILTIN_COLUMN
+	     uint_least32_t __column = __builtin_COLUMN (),
+#else
+	     uint_least32_t __column = 0,
+#endif // __builtin_COLUMN from Clang 9+
+	     const char* __file = __builtin_FILE (),
+	     const char* __function = __builtin_FUNCTION ()) noexcept
+    {
+      return source_location (__line, __column, __file, __function);
+    }
+
+    constexpr
+    source_location () noexcept
+    : _M_data()
+    {
+      _M_data._M_file_name = "";
+      _M_data._M_function_name = "";
+      _M_data._M_line = 0;
+      _M_data._M_column = 0;
+    }
+
+    constexpr const char *
+    file_name () const
+    { return _M_data._M_file_name; }
+
+    constexpr const char *
+    function_name () const
+    { return _M_data._M_function_name; }
+
+    constexpr uint_least32_t
+    line () const
+    { return _M_data._M_line; }
+  
+    constexpr uint_least32_t
+    column () const
+    { return _M_data._M_column; }
+
+  private:
+    constexpr
+    source_location (uint_least32_t __line, uint_least32_t __column,
+		     const char* __file, const char* __function) noexcept
+    : _M_data ()
+    {
+      this->_M_data._M_file_name = __file;
+      this->_M_data._M_function_name = __function;
+      this->_M_data._M_line = __line;
+      this->_M_data._M_column = __column;
+    }
+
+    const __impl _M_data;
+  };
+
+#endif // __builtin_source_location vs. __builtin_LINE + __builtin_COLUMN
+
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace std
+#endif // C++20
+#endif // _GLIBCXX_SOURCE_LOCATION
diff --git a/libstdc++-v3/include/std/version b/libstdc++-v3/include/std/version
index e55a092eb89..4357d7de71c 100644
--- a/libstdc++-v3/include/std/version
+++ b/libstdc++-v3/include/std/version
@@ -196,6 +196,11 @@
 #endif
 #define __cpp_lib_to_array 201907L
 #endif
+#if defined(_GLIBCXX_HAVE_BUILTIN_SOURCE_LOCATION)
+# define __cpp_lib_is_constant_evaluated 201907L
+#elif defined(_GLIBCXX_HAVE_BUILTIN_LINE) && defined(_GLIBCXX_HAVE_BUILTIN_COLUMN)
+# define __cpp_lib_is_constant_evaluated 201907L
+#endif
 #endif // C++2a
 #endif // C++17
 #endif // C++14
diff --git a/libstdc++-v3/testsuite/std/support/srcloc/std.n4842.C b/libstdc++-v3/testsuite/std/support/srcloc/std.n4842.C
new file mode 100644
index 00000000000..b3b6e5c5125
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/support/srcloc/std.n4842.C
@@ -0,0 +1,137 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// Example from C++ Standard Working Draft N4842, November 2019 Mailing
+// Adapted for testing.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <source_location>
+#include <string_view>
+
+struct s {
+  std::source_location member = std::source_location::current();
+  int other_member = 1;
+  
+  constexpr s(std::source_location loc = std::source_location::current())
+    : member(loc) // values of member refer to calling function
+  { }
+
+  constexpr s(int blather) : // values of member refer to this location
+    other_member(blather)
+  { }
+};
+
+constexpr std::source_location
+f(std::source_location a = std::source_location::current())
+{ return a; }
+
+constexpr std::source_location
+g()
+{
+  std::source_location c = std::source_location::current();
+  return f(c);
+}
+
+#include "std.n4842.h"
+#include <iostream>
+int main ()
+{
+  constexpr std::source_location main_sl = std::source_location::current();
+  constexpr std::source_location f_arg_sl = f(main_sl);
+  constexpr std::source_location g_sl = g();
+  constexpr std::source_location f_sl = f();
+  constexpr std::source_location h_sl = h();
+  constexpr s member_main_sl(main_sl);
+  constexpr s member_defaulted_sl(1);
+  constexpr s member_sl = s{};
+
+  using namespace std::string_view_literals;
+
+  constexpr std::string_view main_sl_fn_name(main_sl.function_name());
+  constexpr std::string_view main_sl_fi_name(main_sl.file_name());
+  static_assert(main_sl.line() == 55);
+  // closing paren of call
+  static_assert(main_sl.column() == 74);
+  static_assert(main_sl_fn_name.ends_with("main"sv));
+  static_assert(main_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  constexpr std::string_view f_arg_sl_fn_name(f_arg_sl.function_name());
+  constexpr std::string_view f_arg_sl_fi_name(f_arg_sl.file_name());
+  static_assert(f_arg_sl.line() == 55);
+  // closing paren of call
+  static_assert(f_arg_sl.column() == 74);
+  static_assert(f_arg_sl_fn_name.ends_with("main"sv));
+  static_assert(f_arg_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  constexpr std::string_view g_sl_fn_name(g_sl.function_name());
+  constexpr std::string_view g_sl_fi_name(g_sl.file_name());
+  static_assert(g_sl.line() == 47);
+  static_assert(g_sl.column() == 58); // closing paren of call
+  static_assert(g_sl_fn_name.ends_with("g"sv));
+  static_assert(g_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  constexpr std::string_view h_sl_fn_name(h_sl.function_name());
+  constexpr std::string_view h_sl_fi_name(h_sl.file_name());
+  static_assert(h_sl.line() == 23);
+  static_assert(h_sl.column() == 58); // closing paren of call
+  static_assert(h_sl_fn_name.ends_with("h"sv));
+  static_assert(h_sl_fi_name.ends_with("std.n4842.h"sv));
+
+  constexpr std::string_view member_main_sl_fn_name(member_main_sl.member.function_name());
+  constexpr std::string_view member_main_sl_fi_name(member_main_sl.member.file_name());
+  static_assert(member_main_sl.member.line() == 55);
+  static_assert(member_main_sl.member.column() == 74);
+  static_assert(member_main_sl_fn_name.ends_with("main"sv));
+  static_assert(member_main_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  // FIXME: Jakub's patch does not
+  // properly get the name of the calling function
+  // when used as a default argument,
+  // nor does it follow the example in the std
+  // FIXME: All 3 cases below are busted
+  constexpr std::string_view member_defaulted_sl_fn_name(
+    member_defaulted_sl.member.function_name());
+  constexpr std::string_view member_defaulted_sl_fi_name(
+    member_defaulted_sl.member.file_name());
+  static_assert(member_defaulted_sl.member.line() == 59);
+  // closing brace/paren of constructor
+  static_assert(member_defaulted_sl.member.column() == 29);
+  static_assert(member_defaulted_sl_fn_name.ends_with("main"sv));
+  static_assert(member_defaulted_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  constexpr std::string_view member_sl_fn_name(
+    member_sl.member.function_name());
+  constexpr std::string_view member_sl_fi_name(
+    member_sl.member.file_name());
+  static_assert(member_sl.member.line() == 59);
+  // closing brace/paren of constructor
+  static_assert(member_sl.member.column() == 29);
+  static_assert(member_sl_fn_name.ends_with("main"sv));
+  static_assert(member_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  constexpr std::string_view f_sl_fn_name(f_sl.function_name());
+  constexpr std::string_view f_sl_fi_name(f_sl.file_name());
+  static_assert(f_sl.line() == 58);
+  // closing paren of call
+  static_assert(f_sl.column() == 43);
+  static_assert(f_sl_fn_name.ends_with("main"sv));
+  static_assert(f_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/std/support/srcloc/std.n4842.h b/libstdc++-v3/testsuite/std/support/srcloc/std.n4842.h
new file mode 100644
index 00000000000..50ff5c41bea
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/support/srcloc/std.n4842.h
@@ -0,0 +1,25 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <source_location>
+
+constexpr std::source_location
+h ()
+{
+  std::source_location a = std::source_location::current();
+  return a;
+}

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [ PATCH ] [ C++ ] [ libstdc++ ] P1208r6 Merge source_location
  2019-12-27 19:27 [ PATCH ] [ C++ ] [ libstdc++ ] P1208r6 Merge source_location JeanHeyd Meneide
@ 2019-12-27 19:33 ` Jakub Jelinek
  2019-12-28  3:28   ` JeanHeyd Meneide
  0 siblings, 1 reply; 8+ messages in thread
From: Jakub Jelinek @ 2019-12-27 19:33 UTC (permalink / raw)
  To: JeanHeyd Meneide; +Cc: gcc-patches, libstdc++, Jonathan Wakely

On Fri, Dec 27, 2019 at 02:27:12PM -0500, JeanHeyd Meneide wrote:
>      This patch implements std::source_location. There's a couple
> cases where the builtin implemented does not do what is expected of
> it, and so the bottom 3 batches of test cases fails. I'm still
> including the patch so that others can pick up on what might need to
> change about the __builtin_source_location implementation (CC:
> Jonathan Wakely, Jakub Jelinek).
> 
> 2019-12-27  JeanHeyd "ThePhD" Meneide  <phdofthehouse@gmail.com>
> 
>         * include/Makefile.in: add source_location header
>         * include/bits/c++config: Add new detection macros for
>           LINE, COLUMN, and SOURCE_LOCATION builtins.
>         * include/std/source_location: New.
>         * testuite/std/support/srcloc/std.n4842.C (new): test source_location
>         * testuite/std/support/srcloc/std.n4842.h (new): test source_location

This will be ABI incompatible between GCC and Clang, that doesn't look like
a good idea to me.  I thought the plan is to use what you have in the
_GLIBCXX_HAVE_BUILTIN_SOURCE_LOCATION case always, except that if
__builtin_source_location isn't available, initialize _M_data to nullptr.

	Jakub

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [ PATCH ] [ C++ ] [ libstdc++ ] P1208r6 Merge source_location
  2019-12-27 19:33 ` Jakub Jelinek
@ 2019-12-28  3:28   ` JeanHeyd Meneide
  2020-01-02 10:28     ` Jonathan Wakely
  0 siblings, 1 reply; 8+ messages in thread
From: JeanHeyd Meneide @ 2019-12-28  3:28 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: gcc-patches, libstdc++, Jonathan Wakely

[-- Attachment #1: Type: text/plain, Size: 1301 bytes --]

On Fri, Dec 27, 2019 at 2:33 PM Jakub Jelinek <jakub@redhat.com> wrote:
>
> This will be ABI incompatible between GCC and Clang, that doesn't look like
> a good idea to me.  I thought the plan is to use what you have in the
> _GLIBCXX_HAVE_BUILTIN_SOURCE_LOCATION case always, except that if
> __builtin_source_location isn't available, initialize _M_data to nullptr.

You're right, it's probably bad to have an implementation that
switches. I guess that means clang folks will have to implement the
builtin too at some point (but Jonathan's comment in the
__builtin_source_location patch said they might not, so I'm not sure
what to do for Clang here I guess?).

To more clearly explain the test failures and the static_assert
failures, there are cases where -- when the default argument can be
manifestly constant evaluated -- it does not report the a function
name or anything at all. It also uses the line of where the Nonstatic
Data Member Initializer is for initialization of class members, rather
than the line of the constructor where the initialization happens.
These are things that the Standard's examples say *should* work, but I
don't know how normative Examples are in the standard that use
comments to explain things:
http://eel.is/c++draft/support.srcloc#cons-4

Best Wishes,
JeanHeyd

[-- Attachment #2: p1208r6.patch.txt --]
[-- Type: text/plain, Size: 18280 bytes --]

diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index 6300de9e96d..fc593c7c461 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -70,6 +70,7 @@ std_headers = \
 	${std_srcdir}/scoped_allocator \
 	${std_srcdir}/set \
 	${std_srcdir}/shared_mutex \
+	${std_srcdir}/source_location \
 	${std_srcdir}/span \
 	${std_srcdir}/sstream \
 	${std_srcdir}/stack \
diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in
index ae4a493ea65..c104ffb28ab 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -414,6 +414,7 @@ std_headers = \
 	${std_srcdir}/scoped_allocator \
 	${std_srcdir}/set \
 	${std_srcdir}/shared_mutex \
+	${std_srcdir}/source_location \
 	${std_srcdir}/span \
 	${std_srcdir}/sstream \
 	${std_srcdir}/stack \
diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config
index 7ccfc5f199d..2d2ec96a925 100644
--- a/libstdc++-v3/include/bits/c++config
+++ b/libstdc++-v3/include/bits/c++config
@@ -630,6 +630,7 @@ namespace std
 
 #if __GNUC__ >= 7
 // Assume these are available if the compiler claims to be a recent GCC:
+# define _GLIBCXX_HAVE_BUILTIN_LINE 1
 # define _GLIBCXX_HAVE_BUILTIN_HAS_UNIQ_OBJ_REP 1
 # define _GLIBCXX_HAVE_BUILTIN_IS_AGGREGATE 1
 # define _GLIBCXX_HAVE_BUILTIN_LAUNDER 1
@@ -637,6 +638,9 @@ namespace std
 # if __GNUC__ >= 9
 #  define _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED 1
 # endif
+# if __GNUC__ >= 10
+#  define _GLIBCXX_HAVE_BUILTIN_SOURCE_LOCATION 1
+# endif
 #elif defined(__is_identifier) && defined(__has_builtin)
 // For non-GNU compilers:
 # if ! __is_identifier(__has_unique_object_representations)
@@ -654,6 +658,15 @@ namespace std
 # if ! __is_identifier(__is_same)
 #  define _GLIBCXX_BUILTIN_IS_SAME_AS(T, U) __is_same(T, U)
 # endif
+# if __has_builtin(__builtin_source_location)
+#  define _GLIBCXX_HAVE_BUILTIN_SOURCE_LOCATION 1
+# endif
+# if __has_builtin(__builtin_LINE)
+#  define _GLIBCXX_HAVE_BUILTIN_LINE 1
+# endif
+# if __has_builtin(__builtin_COLUMN)
+#  define _GLIBCXX_HAVE_BUILTIN_COLUMN 1
+# endif
 #endif // GCC
 
 // PSTL configuration
diff --git a/libstdc++-v3/include/std/source_location b/libstdc++-v3/include/std/source_location
new file mode 100644
index 00000000000..e2727ebd196
--- /dev/null
+++ b/libstdc++-v3/include/std/source_location
@@ -0,0 +1,103 @@
+// Component for retrieving function, line and column source info. -*- C++ -*-
+
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file source_location
+ *  This is a Standard C++ Library header.
+ */
+
+//
+// P1208 source_location library
+// Contributed by ThePhD with <3
+//
+
+#ifndef _GLIBCXX_SOURCE_LOCATION
+#define _GLIBCXX_SOURCE_LOCATION 1
+
+#pragma GCC system_header
+
+#if __cplusplus > 201703L
+
+#include <bits/c++config.h>
+#include <cstdint>
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+#define __cpp_lib_source_location 201907L
+
+  struct source_location
+  {
+  private:
+    struct __impl
+    {
+      const char *_M_file_name;
+      const char *_M_function_name;
+      unsigned int _M_line, _M_column;
+    };
+
+  public:
+    static consteval source_location
+    current (const void *__src_loc_impl =
+#ifdef _GLIBCXX_HAVE_BUILTIN_SOURCE_LOCATION
+	       __builtin_source_location ()
+#else
+	       nullptr
+#endif
+    ) noexcept
+    {
+      source_location __ret;
+      __ret._M_data = static_cast<const __impl *>(__src_loc_impl);
+      return __ret;
+    }
+
+    constexpr
+    source_location () noexcept
+    : _M_data ()
+    { }
+
+    constexpr const char *
+    file_name () const noexcept
+    { return _M_data ? _M_data->_M_file_name : ""; }
+
+    constexpr const char *
+    function_name () const noexcept
+    { return _M_data ? _M_data->_M_function_name : ""; }
+
+    constexpr uint_least32_t
+    line () const noexcept
+    { return _M_data ? _M_data->_M_line : 0; }
+  
+    constexpr uint_least32_t
+    column () const noexcept
+    { return _M_data ? _M_data->_M_column : 0; }
+
+  private:
+    const __impl *_M_data;
+  };
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace std
+#endif // C++20
+#endif // _GLIBCXX_SOURCE_LOCATION
diff --git a/libstdc++-v3/include/std/version b/libstdc++-v3/include/std/version
index e55a092eb89..4357d7de71c 100644
--- a/libstdc++-v3/include/std/version
+++ b/libstdc++-v3/include/std/version
@@ -196,6 +196,11 @@
 #endif
 #define __cpp_lib_to_array 201907L
 #endif
+#if defined(_GLIBCXX_HAVE_BUILTIN_SOURCE_LOCATION)
+# define __cpp_lib_is_constant_evaluated 201907L
+#elif defined(_GLIBCXX_HAVE_BUILTIN_LINE) && defined(_GLIBCXX_HAVE_BUILTIN_COLUMN)
+# define __cpp_lib_is_constant_evaluated 201907L
+#endif
 #endif // C++2a
 #endif // C++17
 #endif // C++14
diff --git a/libstdc++-v3/testsuite/std/support/srcloc/consteval.std.n4842.C b/libstdc++-v3/testsuite/std/support/srcloc/consteval.std.n4842.C
new file mode 100644
index 00000000000..7ae135394d5
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/support/srcloc/consteval.std.n4842.C
@@ -0,0 +1,142 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// Example from C++ Standard Working Draft N4842, November 2019 Mailing
+// Adapted for testing.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <source_location>
+#include <string_view>
+
+struct s {
+  std::source_location member = std::source_location::current();
+  int other_member = 1;
+  
+  constexpr s(std::source_location loc = std::source_location::current())
+    : member(loc) // values of member refer to calling function
+  { }
+
+  constexpr s(int blather) : // values of member refer to this location
+    other_member(blather)
+  { }
+};
+
+constexpr std::source_location
+f(std::source_location a = std::source_location::current())
+{ return a; }
+
+constexpr std::source_location
+g()
+{
+  std::source_location c = std::source_location::current();
+  return f(c);
+}
+
+#include "std.n4842.h"
+
+int main ()
+{
+  constexpr std::source_location main_sl = std::source_location::current();
+  constexpr std::source_location f_arg_sl = f(main_sl);
+  constexpr std::source_location g_sl = g();
+  constexpr std::source_location f_sl = f();
+  constexpr std::source_location h_sl = h();
+  constexpr s member_main_sl(main_sl);
+  constexpr s member_defaulted_sl(1);
+  constexpr s member_sl = s{};
+
+  using namespace std::string_view_literals;
+
+
+  static_assert (std::source_location::current ().line () == __LINE__);
+  static_assert (std::source_location::current ().column () == 49);
+
+
+  constexpr std::string_view main_sl_fn_name(main_sl.function_name());
+  constexpr std::string_view main_sl_fi_name(main_sl.file_name());
+  static_assert(main_sl.line() == 55);
+  // closing paren of call
+  static_assert(main_sl.column() == 74);
+  static_assert(main_sl_fn_name.ends_with("main"sv));
+  static_assert(main_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  constexpr std::string_view f_arg_sl_fn_name(f_arg_sl.function_name());
+  constexpr std::string_view f_arg_sl_fi_name(f_arg_sl.file_name());
+  static_assert(f_arg_sl.line() == 55);
+  // closing paren of call
+  static_assert(f_arg_sl.column() == 74);
+  static_assert(f_arg_sl_fn_name.ends_with("main"sv));
+  static_assert(f_arg_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  constexpr std::string_view g_sl_fn_name(g_sl.function_name());
+  constexpr std::string_view g_sl_fi_name(g_sl.file_name());
+  static_assert(g_sl.line() == 47);
+  static_assert(g_sl.column() == 58); // closing paren of call
+  static_assert(g_sl_fn_name.ends_with("g"sv));
+  static_assert(g_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  constexpr std::string_view h_sl_fn_name(h_sl.function_name());
+  constexpr std::string_view h_sl_fi_name(h_sl.file_name());
+  static_assert(h_sl.line() == 23);
+  static_assert(h_sl.column() == 58); // closing paren of call
+  static_assert(h_sl_fn_name.ends_with("h"sv));
+  static_assert(h_sl_fi_name.ends_with("std.n4842.h"sv));
+
+  constexpr std::string_view member_main_sl_fn_name(member_main_sl.member.function_name());
+  constexpr std::string_view member_main_sl_fi_name(member_main_sl.member.file_name());
+  static_assert(member_main_sl.member.line() == 55);
+  static_assert(member_main_sl.member.column() == 74);
+  static_assert(member_main_sl_fn_name.ends_with("main"sv));
+  static_assert(member_main_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  // FIXME: Jakub's patch does not
+  // properly get the name of the calling function
+  // when used as a default argument,
+  // nor does it follow the example in the std
+  // FIXME: All 3 cases below are busted
+  constexpr std::string_view member_defaulted_sl_fn_name(
+    member_defaulted_sl.member.function_name());
+  constexpr std::string_view member_defaulted_sl_fi_name(
+    member_defaulted_sl.member.file_name());
+  static_assert(member_defaulted_sl.member.line() == 35);
+  // closing paren of constructor declaration
+  static_assert(member_defaulted_sl.member.column() == 26);
+  static_assert(member_defaulted_sl_fn_name.ends_with("s::s"sv));
+  static_assert(member_defaulted_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  constexpr std::string_view member_sl_fn_name(
+    member_sl.member.function_name());
+  constexpr std::string_view member_sl_fi_name(
+    member_sl.member.file_name());
+  static_assert(member_sl.member.line() == 62);
+  // closing brace/paren of constructor
+  static_assert(member_sl.member.column() == 29);
+  static_assert(member_sl_fn_name.ends_with("main"sv));
+  static_assert(member_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  constexpr std::string_view f_sl_fn_name(f_sl.function_name());
+  constexpr std::string_view f_sl_fi_name(f_sl.file_name());
+  static_assert(f_sl.line() == 58);
+  // closing paren of call
+  static_assert(f_sl.column() == 43);
+  static_assert(f_sl_fn_name.ends_with("main"sv));
+  static_assert(f_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/std/support/srcloc/std.n4842.C b/libstdc++-v3/testsuite/std/support/srcloc/std.n4842.C
new file mode 100644
index 00000000000..78b6da0c88e
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/support/srcloc/std.n4842.C
@@ -0,0 +1,139 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// Example from C++ Standard Working Draft N4842, November 2019 Mailing
+// Adapted for testing.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+
+#include <source_location>
+#include <string_view>
+#include <testsuite_hooks.h>
+#include "std.n4842.h"
+
+struct s {
+  std::source_location member = std::source_location::current();
+  int other_member = 1;
+  
+  s(std::source_location loc = std::source_location::current())
+    : member(loc) // values of member refer to calling function
+  { }
+
+  s(int blather) : // values of member refer to this location
+    other_member(blather)
+  { }
+};
+
+std::source_location
+f(std::source_location a = std::source_location::current());
+
+std::source_location
+f(std::source_location a)
+{ return a; }
+
+std::source_location
+g()
+{
+  std::source_location c = std::source_location::current();
+  return f(c);
+}
+#include <iostream>
+int main ()
+{
+  std::source_location main_sl = std::source_location::current();
+  std::source_location f_arg_sl = f(main_sl);
+  std::source_location g_sl = g();
+  std::source_location f_sl = f();
+  std::source_location h_sl = h();
+  s member_main_sl(main_sl);
+  s member_defaulted_sl(1);
+  s member_sl = s{};
+
+  using namespace std::string_view_literals;
+
+  std::string_view main_sl_fn_name(main_sl.function_name());
+  std::string_view main_sl_fi_name(main_sl.file_name());
+  VERIFY(main_sl.line() == 58);
+  // closing paren of call
+  VERIFY(main_sl.column() == 64);
+  VERIFY(main_sl_fn_name.ends_with("main"sv));
+  VERIFY(main_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  std::string_view f_arg_sl_fn_name(f_arg_sl.function_name());
+  std::string_view f_arg_sl_fi_name(f_arg_sl.file_name());
+  VERIFY(f_arg_sl.line() == 58);
+  // closing paren of call
+  VERIFY(f_arg_sl.column() == 64);
+  VERIFY(f_arg_sl_fn_name.ends_with("main"sv));
+  VERIFY(f_arg_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  std::string_view g_sl_fn_name(g_sl.function_name());
+  std::string_view g_sl_fi_name(g_sl.file_name());
+  VERIFY(g_sl.line() == 52);
+  VERIFY(g_sl.column() == 58); // closing paren of call
+  VERIFY(g_sl_fn_name.ends_with("g"sv));
+  VERIFY(g_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  std::string_view h_sl_fn_name(h_sl.function_name());
+  std::string_view h_sl_fi_name(h_sl.file_name());
+  VERIFY(h_sl.line() == 23);
+  VERIFY(h_sl.column() == 58); // closing paren of call
+  VERIFY(h_sl_fn_name.ends_with("h"sv));
+  VERIFY(h_sl_fi_name.ends_with("std.n4842.h"sv));
+
+  std::string_view member_main_sl_fn_name(member_main_sl.member.function_name());
+  std::string_view member_main_sl_fi_name(member_main_sl.member.file_name());
+  VERIFY(member_main_sl.member.line() == 58);
+  VERIFY(member_main_sl.member.column() == 64);
+  VERIFY(member_main_sl_fn_name.ends_with("main"sv));
+  VERIFY(member_main_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  std::string_view member_defaulted_sl_fn_name(
+    member_defaulted_sl.member.function_name());
+  std::string_view member_defaulted_sl_fi_name(
+    member_defaulted_sl.member.file_name());
+  std::cout << member_defaulted_sl.member.line() << std::endl;
+  std::cout << member_defaulted_sl.member.column() << std::endl;
+  std::cout << member_defaulted_sl_fn_name << std::endl;
+  std::cout << member_defaulted_sl_fi_name << std::endl;
+  VERIFY(member_defaulted_sl.member.line() == 37);
+  // closing paren of constructor declaration
+  VERIFY(member_defaulted_sl.member.column() == 26);
+  VERIFY(member_defaulted_sl_fn_name.ends_with("s::s"sv));
+  VERIFY(member_defaulted_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  std::string_view member_sl_fn_name(
+    member_sl.member.function_name());
+  std::string_view member_sl_fi_name(
+    member_sl.member.file_name());
+  VERIFY(member_sl.member.line() == 62);
+  // closing brace/paren of constructor
+  VERIFY(member_sl.member.column() == 29);
+  VERIFY(member_sl_fn_name.ends_with("main"sv));
+  VERIFY(member_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  std::string_view f_sl_fn_name(f_sl.function_name());
+  std::string_view f_sl_fi_name(f_sl.file_name());
+  VERIFY(f_sl.line() == 58);
+  // closing paren of call
+  VERIFY(f_sl.column() == 43);
+  VERIFY(f_sl_fn_name.ends_with("main"sv));
+  VERIFY(f_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/std/support/srcloc/std.n4842.h b/libstdc++-v3/testsuite/std/support/srcloc/std.n4842.h
new file mode 100644
index 00000000000..50ff5c41bea
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/support/srcloc/std.n4842.h
@@ -0,0 +1,25 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <source_location>
+
+constexpr std::source_location
+h ()
+{
+  std::source_location a = std::source_location::current();
+  return a;
+}

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [ PATCH ] [ C++ ] [ libstdc++ ] P1208r6 Merge source_location
  2019-12-28  3:28   ` JeanHeyd Meneide
@ 2020-01-02 10:28     ` Jonathan Wakely
  2020-01-02 21:57       ` JeanHeyd Meneide
  0 siblings, 1 reply; 8+ messages in thread
From: Jonathan Wakely @ 2020-01-02 10:28 UTC (permalink / raw)
  To: JeanHeyd Meneide; +Cc: Jakub Jelinek, gcc-patches, libstdc++

On 27/12/19 22:27 -0500, JeanHeyd Meneide wrote:
>On Fri, Dec 27, 2019 at 2:33 PM Jakub Jelinek <jakub@redhat.com> wrote:
>>
>> This will be ABI incompatible between GCC and Clang, that doesn't look like
>> a good idea to me.  I thought the plan is to use what you have in the
>> _GLIBCXX_HAVE_BUILTIN_SOURCE_LOCATION case always, except that if
>> __builtin_source_location isn't available, initialize _M_data to nullptr.
>
>You're right, it's probably bad to have an implementation that
>switches. I guess that means clang folks will have to implement the
>builtin too at some point (but Jonathan's comment in the
>__builtin_source_location patch said they might not, so I'm not sure
>what to do for Clang here I guess?).

Do nothing - compiling with Clang won't define std::source_location at
all.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [ PATCH ] [ C++ ] [ libstdc++ ] P1208r6 Merge source_location
  2020-01-02 10:28     ` Jonathan Wakely
@ 2020-01-02 21:57       ` JeanHeyd Meneide
  2020-01-02 22:07         ` Jakub Jelinek
  0 siblings, 1 reply; 8+ messages in thread
From: JeanHeyd Meneide @ 2020-01-02 21:57 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: Jakub Jelinek, gcc-patches, libstdc++

[-- Attachment #1: Type: text/plain, Size: 822 bytes --]

On Thu, Jan 2, 2020 at 5:28 AM Jonathan Wakely <jwakely@redhat.com> wrote:
>
> Do nothing - compiling with Clang won't define std::source_location at
> all.

You got it! Patch re-done after discussion here
(https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93093) and recommended
no-Clang change.

2020-01-02  JeanHeyd "ThePhD" Meneide  <phdofthehouse@gmail.com>

        * include/Makefile.in: add source_location header
        * include/bits/c++config: Add new detection macros for
          LINE, COLUMN, and SOURCE_LOCATION builtins.
        * include/std/source_location: New.
        * testuite/std/support/srcloc/consteval.std.n4842.h (new):
test source_location
        * testuite/std/support/srcloc/std.n4842.C (new): test source_location
        * testuite/std/support/srcloc/std.n4842.h (new): test source_location

[-- Attachment #2: p1208r6.patch.txt --]
[-- Type: text/plain, Size: 37166 bytes --]

diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in
index ae4a493ea65..c104ffb28ab 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -414,6 +414,7 @@ std_headers = \
 	${std_srcdir}/scoped_allocator \
 	${std_srcdir}/set \
 	${std_srcdir}/shared_mutex \
+	${std_srcdir}/source_location \
 	${std_srcdir}/span \
 	${std_srcdir}/sstream \
 	${std_srcdir}/stack \
diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config
index f983743b052..6ca431b24ee 100644
--- a/libstdc++-v3/include/bits/c++config
+++ b/libstdc++-v3/include/bits/c++config
@@ -630,6 +630,7 @@ namespace std
 
 #if __GNUC__ >= 7
 // Assume these are available if the compiler claims to be a recent GCC:
+# define _GLIBCXX_HAVE_BUILTIN_LINE 1
 # define _GLIBCXX_HAVE_BUILTIN_HAS_UNIQ_OBJ_REP 1
 # define _GLIBCXX_HAVE_BUILTIN_IS_AGGREGATE 1
 # define _GLIBCXX_HAVE_BUILTIN_LAUNDER 1
@@ -637,6 +638,9 @@ namespace std
 # if __GNUC__ >= 9
 #  define _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED 1
 # endif
+# if __GNUC__ >= 10
+#  define _GLIBCXX_HAVE_BUILTIN_SOURCE_LOCATION 1
+# endif
 #elif defined(__is_identifier) && defined(__has_builtin)
 // For non-GNU compilers:
 # if ! __is_identifier(__has_unique_object_representations)
@@ -654,6 +658,15 @@ namespace std
 # if ! __is_identifier(__is_same)
 #  define _GLIBCXX_BUILTIN_IS_SAME_AS(T, U) __is_same(T, U)
 # endif
+# if __has_builtin(__builtin_source_location)
+#  define _GLIBCXX_HAVE_BUILTIN_SOURCE_LOCATION 1
+# endif
+# if __has_builtin(__builtin_LINE)
+#  define _GLIBCXX_HAVE_BUILTIN_LINE 1
+# endif
+# if __has_builtin(__builtin_COLUMN)
+#  define _GLIBCXX_HAVE_BUILTIN_COLUMN 1
+# endif
 #endif // GCC
 
 // PSTL configuration
diff --git a/libstdc++-v3/include/std/source_location b/libstdc++-v3/include/std/source_location
new file mode 100644
index 00000000000..4c805df0dfa
--- /dev/null
+++ b/libstdc++-v3/include/std/source_location
@@ -0,0 +1,101 @@
+// Component for retrieving function, line and column source info. -*- C++ -*-
+
+// Copyright (C) 2019-2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file source_location
+ *  This is a Standard C++ Library header.
+ */
+
+//
+// P1208 source_location library
+// Contributed by ThePhD with <3
+//
+
+#ifndef _GLIBCXX_SOURCE_LOCATION
+#define _GLIBCXX_SOURCE_LOCATION 1
+
+#pragma GCC system_header
+
+#include <bits/c++config.h>
+#include <cstdint>
+
+#if __cplusplus > 201703L
+#ifdef _GLIBCXX_HAVE_BUILTIN_SOURCE_LOCATION
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+#define __cpp_lib_source_location 201907L
+
+  struct source_location
+  {
+  private:
+    struct __impl
+    {
+      const char *_M_file_name;
+      const char *_M_function_name;
+      unsigned int _M_line, _M_column;
+    };
+
+  public:
+    static consteval source_location
+    current (const void *__src_loc_impl = __builtin_source_location ()) noexcept
+    {
+      source_location __ret;
+      __ret._M_data = static_cast<const __impl *>(__src_loc_impl);
+      return __ret;
+    }
+
+    constexpr
+    source_location () noexcept
+    : _M_data ()
+    { }
+
+    constexpr const char *
+    file_name () const noexcept
+    { return _M_data ? _M_data->_M_file_name : ""; }
+
+    constexpr const char *
+    function_name () const noexcept
+    { return _M_data ? _M_data->_M_function_name : ""; }
+
+    constexpr uint_least32_t
+    line () const noexcept
+    { return _M_data ? _M_data->_M_line : 0; }
+  
+    constexpr uint_least32_t
+    column () const noexcept
+    { return _M_data ? _M_data->_M_column : 0; }
+
+  private:
+    const __impl *_M_data;
+  };
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace std
+
+#endif // has __builtin_source_location
+#endif // C++20
+
+#endif // _GLIBCXX_SOURCE_LOCATION
diff --git a/libstdc++-v3/include/std/version b/libstdc++-v3/include/std/version
index ab8111468e4..e482c87ac36 100644
--- a/libstdc++-v3/include/std/version
+++ b/libstdc++-v3/include/std/version
@@ -196,6 +196,11 @@
 #endif
 #define __cpp_lib_to_array 201907L
 #endif
+#if defined(_GLIBCXX_HAVE_BUILTIN_SOURCE_LOCATION)
+# define __cpp_lib_source_location 201907L
+#elif defined(_GLIBCXX_HAVE_BUILTIN_LINE) && defined(_GLIBCXX_HAVE_BUILTIN_COLUMN)
+# define __cpp_lib_is_constant_evaluated 201907L
+#endif
 #endif // C++2a
 #endif // C++17
 #endif // C++14
diff --git a/libstdc++-v3/testsuite/std/support/srcloc/consteval.std.n4842.C b/libstdc++-v3/testsuite/std/support/srcloc/consteval.std.n4842.C
new file mode 100644
index 00000000000..7c057b60e48
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/support/srcloc/consteval.std.n4842.C
@@ -0,0 +1,147 @@
+// Copyright (C) 2019-2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// Example from C++ Standard Working Draft N4842, November 2019 Mailing
+// Adapted for testing.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <source_location>
+#include <string_view>
+
+struct s {
+  std::source_location member = std::source_location::current();
+  int other_member = 1;
+  
+  constexpr s(std::source_location loc = std::source_location::current())
+    : member(loc) // values of member refer to calling function
+  { }
+
+  constexpr s(int blather) : // values of member refer to this location
+    other_member(blather)
+  { }
+};
+
+constexpr std::source_location
+f(std::source_location a = std::source_location::current())
+{ return a; }
+
+constexpr std::source_location
+g()
+{
+  std::source_location c = std::source_location::current();
+  return f(c);
+}
+
+#include "std.n4842.h"
+
+int main ()
+{
+  constexpr std::source_location main_sl = std::source_location::current();
+  constexpr std::source_location f_arg_sl = f(main_sl);
+  constexpr std::source_location g_sl = g();
+  constexpr std::source_location f_sl = f();
+  constexpr std::source_location h_sl = h();
+  constexpr s member_main_sl(main_sl);
+  constexpr s member_defaulted_sl(1);
+  constexpr s member_sl = s{};
+
+  using namespace std::string_view_literals;
+
+
+  static_assert (std::source_location::current ().line () == __LINE__);
+  static_assert (std::source_location::current ().column () == 49);
+
+
+  constexpr std::string_view main_sl_fn_name(main_sl.function_name());
+  constexpr std::string_view main_sl_fi_name(main_sl.file_name());
+  static_assert(main_sl.line() == 55);
+  // closing paren of call
+  static_assert(main_sl.column() == 74);
+  static_assert(main_sl_fn_name.ends_with("main"sv));
+  static_assert(main_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  constexpr std::string_view f_arg_sl_fn_name(f_arg_sl.function_name());
+  constexpr std::string_view f_arg_sl_fi_name(f_arg_sl.file_name());
+  static_assert(f_arg_sl.line() == 55);
+  // closing paren of call
+  static_assert(f_arg_sl.column() == 74);
+  static_assert(f_arg_sl_fn_name.ends_with("main"sv));
+  static_assert(f_arg_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  constexpr std::string_view g_sl_fn_name(g_sl.function_name());
+  constexpr std::string_view g_sl_fi_name(g_sl.file_name());
+  static_assert(g_sl.line() == 47);
+  static_assert(g_sl.column() == 58); // closing paren of call
+  static_assert(g_sl_fn_name.ends_with("g"sv));
+  static_assert(g_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  constexpr std::string_view h_sl_fn_name(h_sl.function_name());
+  constexpr std::string_view h_sl_fi_name(h_sl.file_name());
+  static_assert(h_sl.line() == 23);
+  static_assert(h_sl.column() == 58); // closing paren of call
+  static_assert(h_sl_fn_name.ends_with("h"sv));
+  static_assert(h_sl_fi_name.ends_with("std.n4842.h"sv));
+
+  constexpr std::string_view member_main_sl_fn_name(member_main_sl.member.function_name());
+  constexpr std::string_view member_main_sl_fi_name(member_main_sl.member.file_name());
+  static_assert(member_main_sl.member.line() == 55);
+  static_assert(member_main_sl.member.column() == 74);
+  static_assert(member_main_sl_fn_name.ends_with("main"sv));
+  static_assert(member_main_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  // FIXME: All 3 cases below are busted
+  // Which is user-hostile, but right now
+  // constant evaluation evaluates the call immediately
+  // and without call stack information...
+  constexpr std::string_view member_defaulted_sl_fi_name(
+    member_defaulted_sl.member.file_name());
+#if 0
+  constexpr std::string_view member_defaulted_sl_fn_name(
+    member_defaulted_sl.member.function_name());
+  static_assert(member_defaulted_sl.member.line() == 35);
+  // closing paren of constructor declaration
+  static_assert(member_defaulted_sl.member.column() == 26);
+  static_assert(member_defaulted_sl_fn_name.ends_with("s::s"sv));
+#endif
+  static_assert(member_defaulted_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  constexpr std::string_view member_sl_fi_name(
+    member_sl.member.file_name());
+#if 0
+  constexpr std::string_view member_sl_fn_name(
+    member_sl.member.function_name());
+  static_assert(member_sl.member.line() == 62);
+  // closing brace/paren of constructor
+  static_assert(member_sl.member.column() == 29);
+  static_assert(member_sl_fn_name.ends_with("main"sv));
+#endif
+  static_assert(member_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  constexpr std::string_view f_sl_fi_name(f_sl.file_name());
+#if 0
+  constexpr std::string_view f_sl_fn_name(f_sl.function_name());
+  static_assert(f_sl.line() == 58);
+  // closing paren of call
+  static_assert(f_sl.column() == 43);
+  static_assert(f_sl_fn_name.ends_with("main"sv));
+#endif
+  static_assert(f_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/std/support/srcloc/std.n4842.C b/libstdc++-v3/testsuite/std/support/srcloc/std.n4842.C
new file mode 100644
index 00000000000..fecd79d139a
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/support/srcloc/std.n4842.C
@@ -0,0 +1,149 @@
+// Copyright (C) 2019-2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// Example from C++ Standard Working Draft N4842, November 2019 Mailing
+// Adapted for testing.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+
+#include <source_location>
+#include <string_view>
+#include <testsuite_hooks.h>
+#include "std.n4842.h"
+
+struct s {
+  std::source_location member = std::source_location::current();
+  int other_member = 1;
+  
+  s(std::source_location loc = std::source_location::current())
+    : member(loc) // values of member refer to calling function
+  { }
+
+  s(int blather) : // values of member refer to this location
+    other_member(blather)
+  { }
+};
+
+std::source_location
+f(std::source_location a = std::source_location::current());
+
+std::source_location
+f(std::source_location a)
+{ return a; }
+
+std::source_location
+g()
+{
+  std::source_location c = std::source_location::current();
+  return f(c);
+}
+
+int main ()
+{
+  std::source_location main_sl = std::source_location::current();
+  std::source_location f_arg_sl = f(main_sl);
+  std::source_location g_sl = g();
+  std::source_location f_sl = f();
+  std::source_location h_sl = h();
+  s member_main_sl(main_sl);
+  s member_defaulted_sl(1);
+  s member_sl = s{};
+
+  using namespace std::string_view_literals;
+
+  std::string_view main_sl_fn_name(main_sl.function_name());
+  std::string_view main_sl_fi_name(main_sl.file_name());
+  VERIFY(main_sl.line() == 58);
+  // closing paren of call
+  VERIFY(main_sl.column() == 64);
+  VERIFY(main_sl_fn_name.ends_with("main"sv));
+  VERIFY(main_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  std::string_view f_arg_sl_fn_name(f_arg_sl.function_name());
+  std::string_view f_arg_sl_fi_name(f_arg_sl.file_name());
+  VERIFY(f_arg_sl.line() == 58);
+  // closing paren of call
+  VERIFY(f_arg_sl.column() == 64);
+  VERIFY(f_arg_sl_fn_name.ends_with("main"sv));
+  VERIFY(f_arg_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  std::string_view g_sl_fn_name(g_sl.function_name());
+  std::string_view g_sl_fi_name(g_sl.file_name());
+  VERIFY(g_sl.line() == 52);
+  VERIFY(g_sl.column() == 58); // closing paren of call
+  VERIFY(g_sl_fn_name.ends_with("g"sv));
+  VERIFY(g_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  std::string_view h_sl_fn_name(h_sl.function_name());
+  std::string_view h_sl_fi_name(h_sl.file_name());
+  VERIFY(h_sl.line() == 23);
+  VERIFY(h_sl.column() == 58); // closing paren of call
+  VERIFY(h_sl_fn_name.ends_with("h"sv));
+  VERIFY(h_sl_fi_name.ends_with("std.n4842.h"sv));
+
+  std::string_view member_main_sl_fn_name(member_main_sl.member.function_name());
+  std::string_view member_main_sl_fi_name(member_main_sl.member.file_name());
+  VERIFY(member_main_sl.member.line() == 58);
+  VERIFY(member_main_sl.member.column() == 64);
+  VERIFY(member_main_sl_fn_name.ends_with("main"sv));
+  VERIFY(member_main_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  // FIXME: the following cases are all busted
+  // despite the standard giving examples to the contrary.
+  // Unfortunately GCC's constant folder / evaluator
+  // (and the standard's) manifestly constant evaluates
+  // default arguments, and at that point GCC has no
+  // call stack information for anyone to
+  // produce additional information.
+  // It will require extra work to make these work with it.
+  std::string_view member_defaulted_sl_fi_name(
+    member_defaulted_sl.member.file_name());
+#if 0
+  std::string_view member_defaulted_sl_fn_name(
+    member_defaulted_sl.member.function_name());
+  VERIFY(member_defaulted_sl.member.line() == 37);
+  // closing paren of constructor declaration
+  VERIFY(member_defaulted_sl.member.column() == 26);
+  VERIFY(member_defaulted_sl_fn_name.ends_with("s::s"sv));
+#endif
+  VERIFY(member_defaulted_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  std::string_view member_sl_fi_name(
+    member_sl.member.file_name());
+#if 0
+  std::string_view member_sl_fn_name(
+    member_sl.member.function_name());
+  VERIFY(member_sl.member.line() == 62);
+  // closing brace/paren of constructor
+  VERIFY(member_sl.member.column() == 29);
+  VERIFY(member_sl_fn_name.ends_with("main"sv));
+#endif
+  VERIFY(member_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  std::string_view f_sl_fi_name(f_sl.file_name());
+#if 0
+  std::string_view f_sl_fn_name(f_sl.function_name());
+  VERIFY(f_sl.line() == 58);
+  // closing paren of call
+  VERIFY(f_sl.column() == 43);
+  VERIFY(f_sl_fn_name.ends_with("main"sv));
+#endif
+  VERIFY(f_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/std/support/srcloc/std.n4842.h b/libstdc++-v3/testsuite/std/support/srcloc/std.n4842.h
new file mode 100644
index 00000000000..50ff5c41bea
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/support/srcloc/std.n4842.h
@@ -0,0 +1,25 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <source_location>
+
+constexpr std::source_location
+h ()
+{
+  std::source_location a = std::source_location::current();
+  return a;
+}

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [ PATCH ] [ C++ ] [ libstdc++ ] P1208r6 Merge source_location
  2020-01-02 21:57       ` JeanHeyd Meneide
@ 2020-01-02 22:07         ` Jakub Jelinek
  2020-01-02 22:21           ` JeanHeyd Meneide
  0 siblings, 1 reply; 8+ messages in thread
From: Jakub Jelinek @ 2020-01-02 22:07 UTC (permalink / raw)
  To: JeanHeyd Meneide; +Cc: Jonathan Wakely, gcc-patches, libstdc++

On Thu, Jan 02, 2020 at 04:57:01PM -0500, JeanHeyd Meneide wrote:
> +#if defined(_GLIBCXX_HAVE_BUILTIN_SOURCE_LOCATION)
> +# define __cpp_lib_source_location 201907L
> +#elif defined(_GLIBCXX_HAVE_BUILTIN_LINE) && defined(_GLIBCXX_HAVE_BUILTIN_COLUMN)
> +# define __cpp_lib_is_constant_evaluated 201907L

How is __cpp_lib_is_constant_evaluated related to presence of __builtin_LINE
and __builtin_COLUMN?  I believe you don't want the #elif and following
line at all, and then you don't need everything related to
_GLIBCXX_HAVE_BUILTIN_{LINE,COLUMN} either.

	Jakub

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [ PATCH ] [ C++ ] [ libstdc++ ] P1208r6 Merge source_location
  2020-01-02 22:07         ` Jakub Jelinek
@ 2020-01-02 22:21           ` JeanHeyd Meneide
  2020-12-03 19:25             ` Jonathan Wakely
  0 siblings, 1 reply; 8+ messages in thread
From: JeanHeyd Meneide @ 2020-01-02 22:21 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Jonathan Wakely, gcc-patches, libstdc++

[-- Attachment #1: Type: text/plain, Size: 538 bytes --]

On Thu, Jan 2, 2020 at 5:07 PM Jakub Jelinek <jakub@redhat.com> wrote:
>
> On Thu, Jan 02, 2020 at 04:57:01PM -0500, JeanHeyd Meneide wrote:
> > +#if defined(_GLIBCXX_HAVE_BUILTIN_SOURCE_LOCATION)
> > +# define __cpp_lib_source_location 201907L
> > +#elif defined(_GLIBCXX_HAVE_BUILTIN_LINE) && defined(_GLIBCXX_HAVE_BUILTIN_COLUMN)
> > +# define __cpp_lib_is_constant_evaluated 201907L
>
> How is __cpp_lib_is_constant_evaluated related to presence of __builtin_LINE
> and __builtin_COLUMN?

Oops. Sorry; fat-fingered the diff a little!

[-- Attachment #2: p1208r6.patch.txt --]
[-- Type: text/plain, Size: 36454 bytes --]

diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in
index ae4a493ea65..c104ffb28ab 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -414,6 +414,7 @@ std_headers = \
 	${std_srcdir}/scoped_allocator \
 	${std_srcdir}/set \
 	${std_srcdir}/shared_mutex \
+	${std_srcdir}/source_location \
 	${std_srcdir}/span \
 	${std_srcdir}/sstream \
 	${std_srcdir}/stack \
diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config
index f983743b052..6ca431b24ee 100644
--- a/libstdc++-v3/include/bits/c++config
+++ b/libstdc++-v3/include/bits/c++config
@@ -630,6 +630,7 @@ namespace std
 
 #if __GNUC__ >= 7
 // Assume these are available if the compiler claims to be a recent GCC:
 # define _GLIBCXX_HAVE_BUILTIN_HAS_UNIQ_OBJ_REP 1
 # define _GLIBCXX_HAVE_BUILTIN_IS_AGGREGATE 1
 # define _GLIBCXX_HAVE_BUILTIN_LAUNDER 1
@@ -637,6 +638,9 @@ namespace std
 # if __GNUC__ >= 9
 #  define _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED 1
 # endif
+# if __GNUC__ >= 10
+#  define _GLIBCXX_HAVE_BUILTIN_SOURCE_LOCATION 1
+# endif
 #elif defined(__is_identifier) && defined(__has_builtin)
 // For non-GNU compilers:
 # if ! __is_identifier(__has_unique_object_representations)
@@ -654,6 +658,15 @@ namespace std
 # if ! __is_identifier(__is_same)
 #  define _GLIBCXX_BUILTIN_IS_SAME_AS(T, U) __is_same(T, U)
 # endif
+# if __has_builtin(__builtin_source_location)
+#  define _GLIBCXX_HAVE_BUILTIN_SOURCE_LOCATION 1
+# endif
 #endif // GCC
 
 // PSTL configuration
diff --git a/libstdc++-v3/include/std/source_location b/libstdc++-v3/include/std/source_location
new file mode 100644
index 00000000000..4c805df0dfa
--- /dev/null
+++ b/libstdc++-v3/include/std/source_location
@@ -0,0 +1,101 @@
+// Component for retrieving function, line and column source info. -*- C++ -*-
+
+// Copyright (C) 2019-2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file source_location
+ *  This is a Standard C++ Library header.
+ */
+
+//
+// P1208 source_location library
+// Contributed by ThePhD with <3
+//
+
+#ifndef _GLIBCXX_SOURCE_LOCATION
+#define _GLIBCXX_SOURCE_LOCATION 1
+
+#pragma GCC system_header
+
+#include <bits/c++config.h>
+#include <cstdint>
+
+#if __cplusplus > 201703L
+#ifdef _GLIBCXX_HAVE_BUILTIN_SOURCE_LOCATION
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+#define __cpp_lib_source_location 201907L
+
+  struct source_location
+  {
+  private:
+    struct __impl
+    {
+      const char *_M_file_name;
+      const char *_M_function_name;
+      unsigned int _M_line, _M_column;
+    };
+
+  public:
+    static consteval source_location
+    current (const void *__src_loc_impl = __builtin_source_location ()) noexcept
+    {
+      source_location __ret;
+      __ret._M_data = static_cast<const __impl *>(__src_loc_impl);
+      return __ret;
+    }
+
+    constexpr
+    source_location () noexcept
+    : _M_data ()
+    { }
+
+    constexpr const char *
+    file_name () const noexcept
+    { return _M_data ? _M_data->_M_file_name : ""; }
+
+    constexpr const char *
+    function_name () const noexcept
+    { return _M_data ? _M_data->_M_function_name : ""; }
+
+    constexpr uint_least32_t
+    line () const noexcept
+    { return _M_data ? _M_data->_M_line : 0; }
+  
+    constexpr uint_least32_t
+    column () const noexcept
+    { return _M_data ? _M_data->_M_column : 0; }
+
+  private:
+    const __impl *_M_data;
+  };
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace std
+
+#endif // has __builtin_source_location
+#endif // C++20
+
+#endif // _GLIBCXX_SOURCE_LOCATION
diff --git a/libstdc++-v3/include/std/version b/libstdc++-v3/include/std/version
index ab8111468e4..e482c87ac36 100644
--- a/libstdc++-v3/include/std/version
+++ b/libstdc++-v3/include/std/version
@@ -196,6 +196,11 @@
 #endif
 #define __cpp_lib_to_array 201907L
 #endif
+#if defined(_GLIBCXX_HAVE_BUILTIN_SOURCE_LOCATION)
+# define __cpp_lib_source_location 201907L
+#endif
 #endif // C++2a
 #endif // C++17
 #endif // C++14
diff --git a/libstdc++-v3/testsuite/std/support/srcloc/consteval.std.n4842.C b/libstdc++-v3/testsuite/std/support/srcloc/consteval.std.n4842.C
new file mode 100644
index 00000000000..7c057b60e48
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/support/srcloc/consteval.std.n4842.C
@@ -0,0 +1,147 @@
+// Copyright (C) 2019-2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// Example from C++ Standard Working Draft N4842, November 2019 Mailing
+// Adapted for testing.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <source_location>
+#include <string_view>
+
+struct s {
+  std::source_location member = std::source_location::current();
+  int other_member = 1;
+  
+  constexpr s(std::source_location loc = std::source_location::current())
+    : member(loc) // values of member refer to calling function
+  { }
+
+  constexpr s(int blather) : // values of member refer to this location
+    other_member(blather)
+  { }
+};
+
+constexpr std::source_location
+f(std::source_location a = std::source_location::current())
+{ return a; }
+
+constexpr std::source_location
+g()
+{
+  std::source_location c = std::source_location::current();
+  return f(c);
+}
+
+#include "std.n4842.h"
+
+int main ()
+{
+  constexpr std::source_location main_sl = std::source_location::current();
+  constexpr std::source_location f_arg_sl = f(main_sl);
+  constexpr std::source_location g_sl = g();
+  constexpr std::source_location f_sl = f();
+  constexpr std::source_location h_sl = h();
+  constexpr s member_main_sl(main_sl);
+  constexpr s member_defaulted_sl(1);
+  constexpr s member_sl = s{};
+
+  using namespace std::string_view_literals;
+
+
+  static_assert (std::source_location::current ().line () == __LINE__);
+  static_assert (std::source_location::current ().column () == 49);
+
+
+  constexpr std::string_view main_sl_fn_name(main_sl.function_name());
+  constexpr std::string_view main_sl_fi_name(main_sl.file_name());
+  static_assert(main_sl.line() == 55);
+  // closing paren of call
+  static_assert(main_sl.column() == 74);
+  static_assert(main_sl_fn_name.ends_with("main"sv));
+  static_assert(main_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  constexpr std::string_view f_arg_sl_fn_name(f_arg_sl.function_name());
+  constexpr std::string_view f_arg_sl_fi_name(f_arg_sl.file_name());
+  static_assert(f_arg_sl.line() == 55);
+  // closing paren of call
+  static_assert(f_arg_sl.column() == 74);
+  static_assert(f_arg_sl_fn_name.ends_with("main"sv));
+  static_assert(f_arg_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  constexpr std::string_view g_sl_fn_name(g_sl.function_name());
+  constexpr std::string_view g_sl_fi_name(g_sl.file_name());
+  static_assert(g_sl.line() == 47);
+  static_assert(g_sl.column() == 58); // closing paren of call
+  static_assert(g_sl_fn_name.ends_with("g"sv));
+  static_assert(g_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  constexpr std::string_view h_sl_fn_name(h_sl.function_name());
+  constexpr std::string_view h_sl_fi_name(h_sl.file_name());
+  static_assert(h_sl.line() == 23);
+  static_assert(h_sl.column() == 58); // closing paren of call
+  static_assert(h_sl_fn_name.ends_with("h"sv));
+  static_assert(h_sl_fi_name.ends_with("std.n4842.h"sv));
+
+  constexpr std::string_view member_main_sl_fn_name(member_main_sl.member.function_name());
+  constexpr std::string_view member_main_sl_fi_name(member_main_sl.member.file_name());
+  static_assert(member_main_sl.member.line() == 55);
+  static_assert(member_main_sl.member.column() == 74);
+  static_assert(member_main_sl_fn_name.ends_with("main"sv));
+  static_assert(member_main_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  // FIXME: All 3 cases below are busted
+  // Which is user-hostile, but right now
+  // constant evaluation evaluates the call immediately
+  // and without call stack information...
+  constexpr std::string_view member_defaulted_sl_fi_name(
+    member_defaulted_sl.member.file_name());
+#if 0
+  constexpr std::string_view member_defaulted_sl_fn_name(
+    member_defaulted_sl.member.function_name());
+  static_assert(member_defaulted_sl.member.line() == 35);
+  // closing paren of constructor declaration
+  static_assert(member_defaulted_sl.member.column() == 26);
+  static_assert(member_defaulted_sl_fn_name.ends_with("s::s"sv));
+#endif
+  static_assert(member_defaulted_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  constexpr std::string_view member_sl_fi_name(
+    member_sl.member.file_name());
+#if 0
+  constexpr std::string_view member_sl_fn_name(
+    member_sl.member.function_name());
+  static_assert(member_sl.member.line() == 62);
+  // closing brace/paren of constructor
+  static_assert(member_sl.member.column() == 29);
+  static_assert(member_sl_fn_name.ends_with("main"sv));
+#endif
+  static_assert(member_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  constexpr std::string_view f_sl_fi_name(f_sl.file_name());
+#if 0
+  constexpr std::string_view f_sl_fn_name(f_sl.function_name());
+  static_assert(f_sl.line() == 58);
+  // closing paren of call
+  static_assert(f_sl.column() == 43);
+  static_assert(f_sl_fn_name.ends_with("main"sv));
+#endif
+  static_assert(f_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/std/support/srcloc/std.n4842.C b/libstdc++-v3/testsuite/std/support/srcloc/std.n4842.C
new file mode 100644
index 00000000000..fecd79d139a
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/support/srcloc/std.n4842.C
@@ -0,0 +1,149 @@
+// Copyright (C) 2019-2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// Example from C++ Standard Working Draft N4842, November 2019 Mailing
+// Adapted for testing.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+
+#include <source_location>
+#include <string_view>
+#include <testsuite_hooks.h>
+#include "std.n4842.h"
+
+struct s {
+  std::source_location member = std::source_location::current();
+  int other_member = 1;
+  
+  s(std::source_location loc = std::source_location::current())
+    : member(loc) // values of member refer to calling function
+  { }
+
+  s(int blather) : // values of member refer to this location
+    other_member(blather)
+  { }
+};
+
+std::source_location
+f(std::source_location a = std::source_location::current());
+
+std::source_location
+f(std::source_location a)
+{ return a; }
+
+std::source_location
+g()
+{
+  std::source_location c = std::source_location::current();
+  return f(c);
+}
+
+int main ()
+{
+  std::source_location main_sl = std::source_location::current();
+  std::source_location f_arg_sl = f(main_sl);
+  std::source_location g_sl = g();
+  std::source_location f_sl = f();
+  std::source_location h_sl = h();
+  s member_main_sl(main_sl);
+  s member_defaulted_sl(1);
+  s member_sl = s{};
+
+  using namespace std::string_view_literals;
+
+  std::string_view main_sl_fn_name(main_sl.function_name());
+  std::string_view main_sl_fi_name(main_sl.file_name());
+  VERIFY(main_sl.line() == 58);
+  // closing paren of call
+  VERIFY(main_sl.column() == 64);
+  VERIFY(main_sl_fn_name.ends_with("main"sv));
+  VERIFY(main_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  std::string_view f_arg_sl_fn_name(f_arg_sl.function_name());
+  std::string_view f_arg_sl_fi_name(f_arg_sl.file_name());
+  VERIFY(f_arg_sl.line() == 58);
+  // closing paren of call
+  VERIFY(f_arg_sl.column() == 64);
+  VERIFY(f_arg_sl_fn_name.ends_with("main"sv));
+  VERIFY(f_arg_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  std::string_view g_sl_fn_name(g_sl.function_name());
+  std::string_view g_sl_fi_name(g_sl.file_name());
+  VERIFY(g_sl.line() == 52);
+  VERIFY(g_sl.column() == 58); // closing paren of call
+  VERIFY(g_sl_fn_name.ends_with("g"sv));
+  VERIFY(g_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  std::string_view h_sl_fn_name(h_sl.function_name());
+  std::string_view h_sl_fi_name(h_sl.file_name());
+  VERIFY(h_sl.line() == 23);
+  VERIFY(h_sl.column() == 58); // closing paren of call
+  VERIFY(h_sl_fn_name.ends_with("h"sv));
+  VERIFY(h_sl_fi_name.ends_with("std.n4842.h"sv));
+
+  std::string_view member_main_sl_fn_name(member_main_sl.member.function_name());
+  std::string_view member_main_sl_fi_name(member_main_sl.member.file_name());
+  VERIFY(member_main_sl.member.line() == 58);
+  VERIFY(member_main_sl.member.column() == 64);
+  VERIFY(member_main_sl_fn_name.ends_with("main"sv));
+  VERIFY(member_main_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  // FIXME: the following cases are all busted
+  // despite the standard giving examples to the contrary.
+  // Unfortunately GCC's constant folder / evaluator
+  // (and the standard's) manifestly constant evaluates
+  // default arguments, and at that point GCC has no
+  // call stack information for anyone to
+  // produce additional information.
+  // It will require extra work to make these work with it.
+  std::string_view member_defaulted_sl_fi_name(
+    member_defaulted_sl.member.file_name());
+#if 0
+  std::string_view member_defaulted_sl_fn_name(
+    member_defaulted_sl.member.function_name());
+  VERIFY(member_defaulted_sl.member.line() == 37);
+  // closing paren of constructor declaration
+  VERIFY(member_defaulted_sl.member.column() == 26);
+  VERIFY(member_defaulted_sl_fn_name.ends_with("s::s"sv));
+#endif
+  VERIFY(member_defaulted_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  std::string_view member_sl_fi_name(
+    member_sl.member.file_name());
+#if 0
+  std::string_view member_sl_fn_name(
+    member_sl.member.function_name());
+  VERIFY(member_sl.member.line() == 62);
+  // closing brace/paren of constructor
+  VERIFY(member_sl.member.column() == 29);
+  VERIFY(member_sl_fn_name.ends_with("main"sv));
+#endif
+  VERIFY(member_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  std::string_view f_sl_fi_name(f_sl.file_name());
+#if 0
+  std::string_view f_sl_fn_name(f_sl.function_name());
+  VERIFY(f_sl.line() == 58);
+  // closing paren of call
+  VERIFY(f_sl.column() == 43);
+  VERIFY(f_sl_fn_name.ends_with("main"sv));
+#endif
+  VERIFY(f_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/std/support/srcloc/std.n4842.h b/libstdc++-v3/testsuite/std/support/srcloc/std.n4842.h
new file mode 100644
index 00000000000..50ff5c41bea
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/support/srcloc/std.n4842.h
@@ -0,0 +1,25 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <source_location>
+
+constexpr std::source_location
+h ()
+{
+  std::source_location a = std::source_location::current();
+  return a;
+}

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [ PATCH ] [ C++ ] [ libstdc++ ] P1208r6 Merge source_location
  2020-01-02 22:21           ` JeanHeyd Meneide
@ 2020-12-03 19:25             ` Jonathan Wakely
  0 siblings, 0 replies; 8+ messages in thread
From: Jonathan Wakely @ 2020-12-03 19:25 UTC (permalink / raw)
  To: JeanHeyd Meneide; +Cc: Jakub Jelinek, gcc-patches, libstdc++

[-- Attachment #1: Type: text/plain, Size: 979 bytes --]

On 02/01/20 17:20 -0500, JeanHeyd Meneide wrote:
>On Thu, Jan 2, 2020 at 5:07 PM Jakub Jelinek <jakub@redhat.com> wrote:
>>
>> On Thu, Jan 02, 2020 at 04:57:01PM -0500, JeanHeyd Meneide wrote:
>> > +#if defined(_GLIBCXX_HAVE_BUILTIN_SOURCE_LOCATION)
>> > +# define __cpp_lib_source_location 201907L
>> > +#elif defined(_GLIBCXX_HAVE_BUILTIN_LINE) && defined(_GLIBCXX_HAVE_BUILTIN_COLUMN)
>> > +# define __cpp_lib_is_constant_evaluated 201907L
>>
>> How is __cpp_lib_is_constant_evaluated related to presence of __builtin_LINE
>> and __builtin_COLUMN?
>
>Oops. Sorry; fat-fingered the diff a little!

I've committed a slightly reworked version of JeanHeyd's
<source_location> patch (see attached). Jakub has improved the
built-in so all the commented out tests work now. There's one more
compiler patch coming to use __PRETTY_FUNCTION__ for the function
name, so I'll tweak the new tests after than has gone in.

Tested powerpc64le-linux, committed to trunk.

Thanks, JeanHeyd!



[-- Attachment #2: patch.txt --]
[-- Type: text/x-patch, Size: 20089 bytes --]

commit 57d76ee9cf6265e012fad6286adfaeaba9414c11
Author: JeanHeyd Meneide <phdofthehouse@gmail.com>
Date:   Thu Dec 3 19:17:13 2020

    libtdc++: Define std::source_location for C++20
    
    This doesn't define a new _GLIBCXX_HAVE_BUILTIN_SOURCE_LOCATION macro.
    because using __has_builtin(__builtin_source_location) is sufficient.
    Currently only GCC supports it, but if/when Clang and Intel add it the
    __has_builtin check should for them too.
    
    Co-authored-by: Jonathan Wakely <jwakely@redhat.com>
    
    libstdc++-v3/ChangeLog:
    
            * doc/doxygen/user.cfg.in (INPUT): Add <source_location>.
            * include/Makefile.am: Add <source_location>.
            * include/Makefile.in: Regenerate.
            * include/std/version (__cpp_lib_source_location): Define.
            * include/std/source_location: New file.
            * testsuite/18_support/source_location/1.cc: New test.
            * testsuite/18_support/source_location/consteval.cc: New test.
            * testsuite/18_support/source_location/srcloc.h: New test.
            * testsuite/18_support/source_location/version.cc: New test.

diff --git a/libstdc++-v3/doc/doxygen/user.cfg.in b/libstdc++-v3/doc/doxygen/user.cfg.in
index 1966055e675..2261d572efb 100644
--- a/libstdc++-v3/doc/doxygen/user.cfg.in
+++ b/libstdc++-v3/doc/doxygen/user.cfg.in
@@ -891,6 +891,7 @@ INPUT                  = @srcdir@/doc/doxygen/doxygroups.cc \
                          include/semaphore \
                          include/set \
                          include/shared_mutex \
+                         include/source_location \
                          include/span \
                          include/sstream \
                          include/stack \
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index ca413b8fdfe..9dbc7dcb32d 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -73,6 +73,7 @@ std_headers = \
 	${std_srcdir}/semaphore \
 	${std_srcdir}/set \
 	${std_srcdir}/shared_mutex \
+	${std_srcdir}/source_location \
 	${std_srcdir}/span \
 	${std_srcdir}/sstream \
 	${std_srcdir}/syncstream \
diff --git a/libstdc++-v3/include/std/source_location b/libstdc++-v3/include/std/source_location
new file mode 100644
index 00000000000..13d4bd48857
--- /dev/null
+++ b/libstdc++-v3/include/std/source_location
@@ -0,0 +1,92 @@
+// <source_location> -*- C++ -*-
+
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file include/source_location
+ *  This is a Standard C++ Library header.
+ */
+
+#ifndef _GLIBCXX_SRCLOC
+#define _GLIBCXX_SRCLOC 1
+
+#if __cplusplus > 201703L && __has_builtin(__builtin_source_location)
+#include <bits/c++config.h>
+
+namespace std
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+#define __cpp_lib_source_location 201907L
+
+  /// A class that describes a location in source code.
+  struct source_location
+  {
+  private:
+    using uint_least32_t = __UINT_LEAST32_TYPE__;
+
+  public:
+
+    // [support.srcloc.cons], creation
+    static consteval source_location
+    current(const void* __p = __builtin_source_location()) noexcept
+    {
+      source_location __ret;
+      __ret._M_impl = static_cast <const __impl*>(__p);
+      return __ret;
+    }
+
+    constexpr source_location() noexcept { }
+
+    // [support.srcloc.obs], observers
+    constexpr uint_least32_t
+    line() const noexcept
+    { return _M_impl ? _M_impl->_M_line : 0u; }
+
+    constexpr uint_least32_t
+    column() const noexcept
+    { return _M_impl ? _M_impl->_M_column : 0u; }
+
+    constexpr const char*
+    file_name() const noexcept
+    { return _M_impl ? _M_impl->_M_file_name : ""; }
+
+    constexpr const char*
+    function_name() const noexcept
+    { return _M_impl ? _M_impl->_M_function_name : ""; }
+
+  private:
+    struct __impl
+    {
+      const char* _M_file_name;
+      const char* _M_function_name;
+      unsigned _M_line;
+      unsigned _M_column;
+    };
+
+    const __impl* _M_impl = nullptr;
+  };
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace std
+#endif // C++20 && __builtin_source_location
+#endif // _GLIBCXX_SRCLOC
diff --git a/libstdc++-v3/include/std/version b/libstdc++-v3/include/std/version
index 6e4bd99b361..e4a8bed52ab 100644
--- a/libstdc++-v3/include/std/version
+++ b/libstdc++-v3/include/std/version
@@ -238,6 +238,9 @@
 # define __cpp_lib_semaphore 201907L
 #endif
 #define __cpp_lib_shift 201806L
+#if __has_builtin(__builtin_source_location)
+# define __cpp_lib_source_location 201907L
+#endif
 #if __cpp_lib_concepts
 # define __cpp_lib_span 202002L
 #endif
diff --git a/libstdc++-v3/testsuite/18_support/source_location/1.cc b/libstdc++-v3/testsuite/18_support/source_location/1.cc
new file mode 100644
index 00000000000..c945aaa4d97
--- /dev/null
+++ b/libstdc++-v3/testsuite/18_support/source_location/1.cc
@@ -0,0 +1,155 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// Example from C++ Standard Working Draft N4842, November 2019 Mailing
+// Adapted for testing.
+
+// { dg-options "-std=gnu++2a -include string -include stdexcept" }
+// { dg-do run { target c++2a } }
+
+#include <source_location>
+
+#ifndef __cpp_lib_source_location
+# error "Feature-test macro for source_location missing in <source_location>"
+#elif __cpp_lib_source_location != 201907L
+# error "Feature-test macro for source_location has wrong value in <source_location>"
+#endif
+
+#include <string_view>
+#include <testsuite_hooks.h>
+#include "srcloc.h"
+
+
+struct s {
+  std::source_location member = std::source_location::current();
+  int other_member = 1;
+
+  s(std::source_location loc = std::source_location::current())
+    : member(loc) // values of member refer to calling function
+  { }
+
+  s(int blather) : // values of member refer to this location
+    other_member(blather)
+  { }
+};
+
+std::source_location
+f(std::source_location a = std::source_location::current());
+
+std::source_location
+f(std::source_location a)
+{ return a; }
+
+auto
+g()
+{
+  struct srcloc_and_line
+  {
+    std::source_location sl;
+    unsigned line;
+  };
+
+  std::source_location c = std::source_location::current();
+  return srcloc_and_line{ f(c), __LINE__ - 1 };
+}
+
+int main ()
+{
+  std::source_location main_sl = std::source_location::current();
+  unsigned main_sl_line = __LINE__ - 1;
+  std::source_location f_arg_sl = f(main_sl);
+  unsigned f_arg_sl_line = main_sl_line;
+  auto [g_sl, g_sl_line] = g();
+  std::source_location f_sl = f();
+  unsigned f_sl_line = __LINE__ - 1;
+  std::source_location h_sl = h(); // defined in ./srcloc.h
+  s member_main_sl(main_sl);
+  s member_defaulted_sl(1);
+  s member_sl = s{};
+  const unsigned member_sl_line = __LINE__ - 1;
+
+  using namespace std::string_view_literals;
+
+  std::string_view main_sl_fn_name(main_sl.function_name());
+  std::string_view main_sl_fi_name(main_sl.file_name());
+  VERIFY(main_sl.line() == main_sl_line);
+  // closing paren of call
+  VERIFY(main_sl.column() == 64);
+  VERIFY(main_sl_fn_name.ends_with("main"sv));
+  VERIFY(main_sl_fi_name.ends_with("1.cc"sv));
+
+  std::string_view f_arg_sl_fn_name(f_arg_sl.function_name());
+  std::string_view f_arg_sl_fi_name(f_arg_sl.file_name());
+  VERIFY(f_arg_sl.line() == f_arg_sl_line);
+  // closing paren of call
+  VERIFY(f_arg_sl.column() == 64);
+  VERIFY(f_arg_sl_fn_name.ends_with("main"sv));
+  VERIFY(f_arg_sl_fi_name.ends_with("1.cc"sv));
+
+  std::string_view g_sl_fn_name(g_sl.function_name());
+  std::string_view g_sl_fi_name(g_sl.file_name());
+  VERIFY(g_sl.line() == g_sl_line);
+  VERIFY(g_sl.column() == 58); // closing paren of call
+  VERIFY(g_sl_fn_name.ends_with("g"sv));
+  VERIFY(g_sl_fi_name.ends_with("1.cc"sv));
+
+  std::string_view h_sl_fn_name(h_sl.function_name());
+  std::string_view h_sl_fi_name(h_sl.file_name());
+  VERIFY(h_sl.line() == 23);
+  VERIFY(h_sl.column() == 58); // closing paren of call
+  VERIFY(h_sl_fn_name.ends_with("h"sv));
+  VERIFY(h_sl_fi_name.ends_with("srcloc.h"sv));
+
+  std::string_view member_main_sl_fn_name(member_main_sl.member.function_name());
+  std::string_view member_main_sl_fi_name(member_main_sl.member.file_name());
+  VERIFY(member_main_sl.member.line() == main_sl_line);
+  VERIFY(member_main_sl.member.column() == 64);
+  VERIFY(member_main_sl_fn_name.ends_with("main"sv));
+  VERIFY(member_main_sl_fi_name.ends_with("1.cc"sv));
+
+  std::string_view member_defaulted_sl_fi_name(
+    member_defaulted_sl.member.file_name());
+  std::string_view member_defaulted_sl_fn_name(
+    member_defaulted_sl.member.function_name());
+  VERIFY(member_defaulted_sl.member.line() == 46);
+  // closing paren of constructor declaration
+  VERIFY(member_defaulted_sl.member.column() == 25);
+#if 0
+  VERIFY(member_defaulted_sl_fn_name.starts_with("s::s(int)"sv));
+#endif
+  VERIFY(member_defaulted_sl_fi_name.ends_with("1.cc"sv));
+
+  std::string_view member_sl_fi_name(
+    member_sl.member.file_name());
+  std::string_view member_sl_fn_name(
+    member_sl.member.function_name());
+  VERIFY(member_sl.member.line() == member_sl_line);
+  // closing brace/paren of constructor
+  VERIFY(member_sl.member.column() == 19);
+  VERIFY(member_sl_fn_name.starts_with("main"sv));
+  VERIFY(member_sl_fi_name.ends_with("1.cc"sv));
+
+  std::string_view f_sl_fi_name(f_sl.file_name());
+  std::string_view f_sl_fn_name(f_sl.function_name());
+  VERIFY(f_sl.line() == f_sl_line);
+  // closing paren of call
+  VERIFY(f_sl.column() == 33);
+  VERIFY(f_sl_fn_name.ends_with("main"sv));
+  VERIFY(f_sl_fi_name.ends_with("1.cc"sv));
+
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/18_support/source_location/consteval.cc b/libstdc++-v3/testsuite/18_support/source_location/consteval.cc
new file mode 100644
index 00000000000..9b137f8641d
--- /dev/null
+++ b/libstdc++-v3/testsuite/18_support/source_location/consteval.cc
@@ -0,0 +1,149 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// Example from C++ Standard Working Draft N4842, November 2019 Mailing
+// Adapted for testing.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <source_location>
+#include <string_view>
+
+struct s {
+  std::source_location member = std::source_location::current();
+  int other_member = 1;
+
+  constexpr s(std::source_location loc = std::source_location::current())
+    : member(loc) // values of member refer to calling function
+  { }
+
+  constexpr s(int blather) : // values of member refer to this location
+    other_member(blather)
+  { }
+};
+
+constexpr std::source_location
+f(std::source_location a = std::source_location::current())
+{ return a; }
+
+constexpr auto
+g()
+{
+  struct srcloc_and_line
+  {
+    std::source_location sl;
+    unsigned line;
+  };
+
+  std::source_location c = std::source_location::current();
+  return srcloc_and_line{ f(c), __LINE__ - 1 };
+}
+
+#include "srcloc.h"
+
+int main ()
+{
+  constexpr std::source_location main_sl = std::source_location::current();
+  constexpr unsigned main_sl_line = __LINE__ - 1;
+  constexpr std::source_location f_arg_sl = f(main_sl);
+  constexpr unsigned f_arg_sl_line = main_sl_line;
+  constexpr std::source_location g_sl = g().sl;
+  constexpr unsigned g_sl_line = g().line;
+  constexpr std::source_location f_sl = f();
+  constexpr unsigned f_sl_line = __LINE__ - 1;
+  constexpr std::source_location h_sl = h(); // defined in ./srcloc.h
+  constexpr s member_main_sl(main_sl);
+  constexpr s member_defaulted_sl(1);
+  constexpr s member_sl = s{};
+  constexpr unsigned member_sl_line = __LINE__ - 1;
+
+  using namespace std::string_view_literals;
+
+  static_assert (std::source_location::current ().line () == __LINE__);
+  static_assert (std::source_location::current ().column () == 49);
+
+
+  constexpr std::string_view main_sl_fn_name(main_sl.function_name());
+  constexpr std::string_view main_sl_fi_name(main_sl.file_name());
+  static_assert(main_sl.line() == main_sl_line);
+  // closing paren of call
+  static_assert(main_sl.column() == 74);
+  static_assert(main_sl_fn_name.ends_with("main"sv));
+  static_assert(main_sl_fi_name.ends_with("consteval.cc"sv));
+
+  constexpr std::string_view f_arg_sl_fn_name(f_arg_sl.function_name());
+  constexpr std::string_view f_arg_sl_fi_name(f_arg_sl.file_name());
+  static_assert(f_arg_sl.line() == f_arg_sl_line);
+  // closing paren of call
+  static_assert(f_arg_sl.column() == 74);
+  static_assert(f_arg_sl_fn_name.ends_with("main"sv));
+  static_assert(f_arg_sl_fi_name.ends_with("consteval.cc"sv));
+
+  constexpr std::string_view g_sl_fn_name(g_sl.function_name());
+  constexpr std::string_view g_sl_fi_name(g_sl.file_name());
+  static_assert(g_sl.line() == g_sl_line);
+  static_assert(g_sl.column() == 58); // closing paren of call
+  static_assert(g_sl_fn_name.ends_with("g"sv));
+  static_assert(g_sl_fi_name.ends_with("consteval.cc"sv));
+
+  constexpr std::string_view h_sl_fn_name(h_sl.function_name());
+  constexpr std::string_view h_sl_fi_name(h_sl.file_name());
+  static_assert(h_sl.line() == 23);
+  static_assert(h_sl.column() == 58); // closing paren of call
+  static_assert(h_sl_fn_name.ends_with("h"sv));
+  static_assert(h_sl_fi_name.ends_with("srcloc.h"sv));
+
+  constexpr std::string_view member_main_sl_fn_name(member_main_sl.member.function_name());
+  constexpr std::string_view member_main_sl_fi_name(member_main_sl.member.file_name());
+  static_assert(member_main_sl.member.line() == main_sl_line);
+  static_assert(member_main_sl.member.column() == 74);
+  static_assert(member_main_sl_fn_name.ends_with("main"sv));
+  static_assert(member_main_sl_fi_name.ends_with("consteval.cc"sv));
+
+  constexpr std::string_view member_defaulted_sl_fi_name(
+    member_defaulted_sl.member.file_name());
+  constexpr std::string_view member_defaulted_sl_fn_name(
+    member_defaulted_sl.member.function_name());
+  static_assert(member_defaulted_sl.member.line() == 36);
+  // closing paren of constructor declaration
+  static_assert(member_defaulted_sl.member.column() == 25);
+#if 0
+  static_assert(member_defaulted_sl_fn_name.ends_with("s::s(int)"sv));
+#endif
+  static_assert(member_defaulted_sl_fi_name.ends_with("consteval.cc"sv));
+
+  constexpr std::string_view member_sl_fi_name(
+    member_sl.member.file_name());
+  constexpr std::string_view member_sl_fn_name(
+    member_sl.member.function_name());
+  static_assert(member_sl.member.line() == member_sl_line);
+  // closing brace/paren of constructor
+  static_assert(member_sl.member.column() == 29);
+  static_assert(member_sl_fn_name.starts_with("main"sv));
+  static_assert(member_sl_fi_name.ends_with("consteval.cc"sv));
+
+  constexpr std::string_view f_sl_fi_name(f_sl.file_name());
+  constexpr std::string_view f_sl_fn_name(f_sl.function_name());
+  static_assert(f_sl.line() == f_sl_line);
+  // closing paren of call
+  static_assert(f_sl.column() == 43);
+  static_assert(f_sl_fn_name.ends_with("main"sv));
+  static_assert(f_sl_fi_name.ends_with("consteval.cc"sv));
+
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/18_support/source_location/srcloc.h b/libstdc++-v3/testsuite/18_support/source_location/srcloc.h
new file mode 100644
index 00000000000..9b05458ee2f
--- /dev/null
+++ b/libstdc++-v3/testsuite/18_support/source_location/srcloc.h
@@ -0,0 +1,25 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <source_location>
+
+constexpr std::source_location
+h()
+{
+  std::source_location a = std::source_location::current();
+  return a;
+}
diff --git a/libstdc++-v3/testsuite/18_support/source_location/version.cc b/libstdc++-v3/testsuite/18_support/source_location/version.cc
new file mode 100644
index 00000000000..f2b3bf6fa1e
--- /dev/null
+++ b/libstdc++-v3/testsuite/18_support/source_location/version.cc
@@ -0,0 +1,27 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do preprocess { target c++2a } }
+
+#include <version>
+
+#ifndef __cpp_lib_source_location
+# error "Feature-test macro for source_location missing in <version>"
+#elif __cpp_lib_source_location != 201907L
+# error "Feature-test macro for source_location has wrong value in <version>"
+#endif

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2020-12-03 19:27 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-27 19:27 [ PATCH ] [ C++ ] [ libstdc++ ] P1208r6 Merge source_location JeanHeyd Meneide
2019-12-27 19:33 ` Jakub Jelinek
2019-12-28  3:28   ` JeanHeyd Meneide
2020-01-02 10:28     ` Jonathan Wakely
2020-01-02 21:57       ` JeanHeyd Meneide
2020-01-02 22:07         ` Jakub Jelinek
2020-01-02 22:21           ` JeanHeyd Meneide
2020-12-03 19:25             ` Jonathan Wakely

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).