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
+// .
+
+/** @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
+#include
+
+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(__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
+// .
+
+// 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
+#include
+
+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
+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
+// .
+
+#include
+
+constexpr std::source_location
+h ()
+{
+ std::source_location a = std::source_location::current();
+ return a;
+}