On Thu, Nov 14, 2019 at 08:34:26PM +0100, Jakub Jelinek wrote:
> The following WIP patch implements __builtin_source_location (),
> which returns const void pointer to a std::source_location::__impl
> struct that is required to contain __file, __function, __line and __column
> fields, the first two with const char * type, the latter some integral type.

Here is hopefully final version, with the hashing implemented,
__file renamed to __file_name and __function to __function_name to match
how the standard names the methods and with testsuite coverage.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2019-11-15  Jakub Jelinek  <ja...@redhat.com>

        * cp-tree.h (enum cp_tree_index): Add CPTI_SOURCE_LOCATION_IMPL.
        (source_location_impl): Define.
        (enum cp_built_in_function): Add CP_BUILT_IN_SOURCE_LOCATION.
        (fold_builtin_source_location): Declare.
        * cp-gimplify.c: Include output.h, file-prefix-map.h and cgraph.h.
        (cp_gimplify_expr, cp_fold): Handle CP_BUILT_IN_SOURCE_LOCATION.
        Formatting fix.
        (get_source_location_impl): New function.
        (struct source_location_table_entry,
        struct source_location_table_entry_hash): New types.
        (source_location_table, source_location_id): New variables.
        (fold_builtin_source_location): New function.
        * constexpr.c (cxx_eval_builtin_function_call): Handle
        CP_BUILT_IN_SOURCE_LOCATION.
        * tree.c (builtin_valid_in_constant_expr_p): Likewise.  Formatting
        fix.
        * decl.c (cxx_init_decl_processing): Register
        __builtin_source_location.
        * name-lookup.c (get_std_name_hint): Add source_location entry.

        * g++.dg/cpp2a/srcloc1.C: New test.
        * g++.dg/cpp2a/srcloc2.C: New test.
        * g++.dg/cpp2a/srcloc3.C: New test.
        * g++.dg/cpp2a/srcloc4.C: New test.
        * g++.dg/cpp2a/srcloc5.C: New test.
        * g++.dg/cpp2a/srcloc6.C: New test.
        * g++.dg/cpp2a/srcloc7.C: New test.
        * g++.dg/cpp2a/srcloc8.C: New test.
        * g++.dg/cpp2a/srcloc9.C: New test.
        * g++.dg/cpp2a/srcloc10.C: New test.
        * g++.dg/cpp2a/srcloc11.C: New test.
        * g++.dg/cpp2a/srcloc12.C: New test.
        * g++.dg/cpp2a/srcloc13.C: New test.
        * g++.dg/cpp2a/srcloc14.C: New test.

--- gcc/cp/cp-tree.h.jj 2019-11-15 00:37:14.282250695 +0100
+++ gcc/cp/cp-tree.h    2019-11-15 09:39:58.514862699 +0100
@@ -204,6 +204,8 @@ enum cp_tree_index
 
     CPTI_ANY_TARG,
 
+    CPTI_SOURCE_LOCATION_IMPL,
+
     CPTI_MAX
 };
 
@@ -356,6 +358,9 @@ extern GTY(()) tree cp_global_trees[CPTI
 /* A node which matches any template argument.  */
 #define any_targ_node                  cp_global_trees[CPTI_ANY_TARG]
 
+/* std::source_location::__impl class.  */
+#define source_location_impl           
cp_global_trees[CPTI_SOURCE_LOCATION_IMPL]
+
 /* Node to indicate default access. This must be distinct from the
    access nodes in tree.h.  */
 
@@ -6175,6 +6180,7 @@ struct GTY((chain_next ("%h.next"))) tin
 enum cp_built_in_function {
   CP_BUILT_IN_IS_CONSTANT_EVALUATED,
   CP_BUILT_IN_INTEGER_PACK,
+  CP_BUILT_IN_SOURCE_LOCATION,
   CP_BUILT_IN_LAST
 };
 
@@ -7723,6 +7729,7 @@ extern void clear_fold_cache                      (void);
 extern tree lookup_hotness_attribute           (tree);
 extern tree process_stmt_hotness_attribute     (tree, location_t);
 extern bool simple_empty_class_p               (tree, tree, tree_code);
+extern tree fold_builtin_source_location       (location_t);
 
 /* in name-lookup.c */
 extern tree strip_using_decl                    (tree);
--- gcc/cp/cp-gimplify.c.jj     2019-11-15 00:37:14.511247252 +0100
+++ gcc/cp/cp-gimplify.c        2019-11-15 11:23:50.574203292 +0100
@@ -35,6 +35,9 @@ along with GCC; see the file COPYING3.
 #include "attribs.h"
 #include "asan.h"
 #include "gcc-rich-location.h"
+#include "output.h"
+#include "file-prefix-map.h"
+#include "cgraph.h"
 
 /* Forward declarations.  */
 
@@ -896,8 +899,12 @@ cp_gimplify_expr (tree *expr_p, gimple_s
          tree decl = cp_get_callee_fndecl_nofold (*expr_p);
          if (decl
              && fndecl_built_in_p (decl, CP_BUILT_IN_IS_CONSTANT_EVALUATED,
-                                 BUILT_IN_FRONTEND))
+                                   BUILT_IN_FRONTEND))
            *expr_p = boolean_false_node;
+         else if (decl
+                  && fndecl_built_in_p (decl, CP_BUILT_IN_SOURCE_LOCATION,
+                                        BUILT_IN_FRONTEND))
+           *expr_p = fold_builtin_source_location (EXPR_LOCATION (*expr_p));
        }
       break;
 
@@ -2641,9 +2648,17 @@ cp_fold (tree x)
        /* Defer folding __builtin_is_constant_evaluated.  */
        if (callee
            && fndecl_built_in_p (callee, CP_BUILT_IN_IS_CONSTANT_EVALUATED,
-                               BUILT_IN_FRONTEND))
+                                 BUILT_IN_FRONTEND))
          break;
 
+       if (callee
+           && fndecl_built_in_p (callee, CP_BUILT_IN_SOURCE_LOCATION,
+                                 BUILT_IN_FRONTEND))
+         {
+           x = fold_builtin_source_location (EXPR_LOCATION (x));
+           break;
+         }
+
        x = copy_node (x);
 
        m = call_expr_nargs (x);
@@ -2868,4 +2883,246 @@ process_stmt_hotness_attribute (tree std
   return std_attrs;
 }
 
+/* Helper of fold_builtin_source_location, return the
+   std::source_location::__impl type after performing verification
+   on it.  */
+
+static tree
+get_source_location_impl (location_t loc)
+{
+  tree name = get_identifier ("source_location");
+  tree decl = lookup_qualified_name (std_node, name);
+  if (TREE_CODE (decl) != TYPE_DECL)
+    {
+      auto_diagnostic_group d;
+      if (decl == error_mark_node || TREE_CODE (decl) == TREE_LIST)
+       qualified_name_lookup_error (std_node, name, decl, loc);
+      else
+       error ("%qD is not a type", decl);
+      return error_mark_node;
+    }
+  name = get_identifier ("__impl");
+  tree type = TREE_TYPE (decl);
+  decl = lookup_qualified_name (type, name);
+  if (TREE_CODE (decl) != TYPE_DECL)
+    {
+      auto_diagnostic_group d;
+      if (decl == error_mark_node || TREE_CODE (decl) == TREE_LIST)
+       qualified_name_lookup_error (type, name, decl, loc);
+      else
+       error ("%qD is not a type", decl);
+      return error_mark_node;
+    }
+  type = TREE_TYPE (decl);
+  if (TREE_CODE (type) != RECORD_TYPE)
+    {
+      error ("%qD is not a class type", decl);
+      return error_mark_node;
+    }
+
+  int cnt = 0;
+  for (tree field = TYPE_FIELDS (type);
+       (field = next_initializable_field (field)) != NULL_TREE;
+       field = DECL_CHAIN (field))
+    {
+      if (DECL_NAME (field) != NULL_TREE)
+       {
+         const char *n = IDENTIFIER_POINTER (DECL_NAME (field));
+         if (strcmp (n, "__file_name") == 0
+             || strcmp (n, "__function_name") == 0)
+           {
+             if (TREE_TYPE (field) != const_string_type_node)
+               {
+                 error ("%qD does not have %<const char *%> type", field);
+                 return error_mark_node;
+               }
+             cnt++;
+             continue;
+           }
+         else if (strcmp (n, "__line") == 0 || strcmp (n, "__column") == 0)
+           {
+             if (TREE_CODE (TREE_TYPE (field)) != INTEGER_TYPE)
+               {
+                 error ("%qD does not have integral type", field);
+                 return error_mark_node;
+               }
+             cnt++;
+             continue;
+           }
+       }
+      cnt = 0;
+      break;
+    }
+  if (cnt != 4)
+    {
+      error ("%<std::source_location::__impl%> does not contain only "
+            "non-static data members %<__file_name%>, %<__function_name%>, "
+            "%<__line%> and %<__column%>");
+      return error_mark_node;
+    }
+  return build_qualified_type (type, TYPE_QUAL_CONST);
+}
+
+/* Type for source_location_table hash_set.  */
+struct GTY((for_user)) source_location_table_entry {
+  location_t loc;
+  unsigned uid;
+  tree var;
+};
+
+/* Traits class for function start hash maps below.  */
+
+struct source_location_table_entry_hash
+  : ggc_remove <source_location_table_entry>
+{
+  typedef source_location_table_entry value_type;
+  typedef source_location_table_entry compare_type;
+
+  static hashval_t
+  hash (const source_location_table_entry &ref)
+  {
+    inchash::hash hstate (0);
+    hstate.add_int (ref.loc);
+    hstate.add_int (ref.uid);
+    return hstate.end ();
+  }
+
+  static bool
+  equal (const source_location_table_entry &ref1,
+        const source_location_table_entry &ref2)
+  {
+    return ref1.loc == ref2.loc && ref1.uid == ref2.uid;
+  }
+
+  static void
+  mark_deleted (source_location_table_entry &ref)
+  {
+    ref.loc = UNKNOWN_LOCATION;
+    ref.uid = -1U;
+    ref.var = NULL_TREE;
+  }
+
+  static void
+  mark_empty (source_location_table_entry &ref)
+  {
+    ref.loc = UNKNOWN_LOCATION;
+    ref.uid = 0;
+    ref.var = NULL_TREE;
+  }
+
+  static bool
+  is_deleted (const source_location_table_entry &ref)
+  {
+    return (ref.loc == UNKNOWN_LOCATION
+           && ref.uid == -1U
+           && ref.var == NULL_TREE);
+  }
+
+  static bool
+  is_empty (const source_location_table_entry &ref)
+  {
+    return (ref.loc == UNKNOWN_LOCATION
+           && ref.uid == 0
+           && ref.var == NULL_TREE);
+  }
+};
+
+static GTY(()) hash_table <source_location_table_entry_hash>
+  *source_location_table;
+static GTY(()) unsigned int source_location_id;
+
+/* Fold __builtin_source_location () call.  LOC is the location
+   of the call.  */
+
+tree
+fold_builtin_source_location (location_t loc)
+{
+  if (source_location_impl == NULL_TREE)
+    {
+      auto_diagnostic_group d;
+      source_location_impl = get_source_location_impl (loc);
+      if (source_location_impl == error_mark_node)
+       inform (loc, "evaluating %qs", "__builtin_source_location");
+    }
+  if (source_location_impl == error_mark_node)
+    return build_zero_cst (const_ptr_type_node);
+  if (source_location_table == NULL)
+    source_location_table
+      = hash_table <source_location_table_entry_hash>::create_ggc (64);
+  loc = LOCATION_LOCUS (loc);
+  const line_map_ordinary *map;
+  source_location_table_entry entry;
+  entry.loc
+    = linemap_resolve_location (line_table, loc, LRK_MACRO_EXPANSION_POINT,
+                               &map);
+  entry.uid = current_function_decl ? DECL_UID (current_function_decl) : -1;
+  entry.var = error_mark_node;
+  source_location_table_entry *entryp
+    = source_location_table->find_slot (entry, INSERT);
+  tree var;
+  if (entryp->var)
+    var = entryp->var;
+  else
+    {
+      char tmp_name[32];
+      ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lsrc_loc", source_location_id++);
+      var = build_decl (loc, VAR_DECL, get_identifier (tmp_name),
+                       source_location_impl);
+      TREE_STATIC (var) = 1;
+      TREE_PUBLIC (var) = 0;
+      DECL_ARTIFICIAL (var) = 1;
+      DECL_IGNORED_P (var) = 1;
+      DECL_EXTERNAL (var) = 0;
+      DECL_DECLARED_CONSTEXPR_P (var) = 1;
+      DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (var) = 1;
+      layout_decl (var, 0);
+
+      vec<constructor_elt, va_gc> *v = NULL;
+      vec_alloc (v, 4);
+      for (tree field = TYPE_FIELDS (source_location_impl);
+          (field = next_initializable_field (field)) != NULL_TREE;
+          field = DECL_CHAIN (field))
+       {
+         const char *n = IDENTIFIER_POINTER (DECL_NAME (field));
+         tree val = NULL_TREE;
+         if (strcmp (n, "__file_name") == 0)
+           {
+             if (const char *fname = LOCATION_FILE (loc))
+               {
+                 fname = remap_macro_filename (fname);
+                 val = build_string_literal (strlen (fname) + 1, fname);
+               }
+             else
+               val = build_string_literal (1, "");
+           }
+         else if (strcmp (n, "__function_name") == 0)
+           {
+             const char *name = "";
+
+             if (current_function_decl)
+               name = cxx_printable_name (current_function_decl, 0);
+
+             val = build_string_literal (strlen (name) + 1, name);
+           }
+         else if (strcmp (n, "__line") == 0)
+           val = build_int_cst (TREE_TYPE (field), LOCATION_LINE (loc));
+         else if (strcmp (n, "__column") == 0)
+           val = build_int_cst (TREE_TYPE (field), LOCATION_COLUMN (loc));
+         else
+           gcc_unreachable ();
+         CONSTRUCTOR_APPEND_ELT (v, field, val);
+       }
+
+      tree ctor = build_constructor (source_location_impl, v);
+      TREE_CONSTANT (ctor) = 1;
+      TREE_STATIC (ctor) = 1;
+      DECL_INITIAL (var) = ctor;
+      varpool_node::finalize_decl (var);
+      *entryp = entry;
+      entryp->var = var;
+    }
+
+  return build_fold_addr_expr_with_type_loc (loc, var, const_ptr_type_node);
+}
+
 #include "gt-cp-cp-gimplify.h"
--- gcc/cp/constexpr.c.jj       2019-11-15 00:37:14.239251341 +0100
+++ gcc/cp/constexpr.c  2019-11-15 09:39:58.509862775 +0100
@@ -1238,6 +1238,9 @@ cxx_eval_builtin_function_call (const co
       return boolean_true_node;
     }
 
+  if (fndecl_built_in_p (fun, CP_BUILT_IN_SOURCE_LOCATION, BUILT_IN_FRONTEND))
+    return fold_builtin_source_location (EXPR_LOCATION (t));
+
   /* Be permissive for arguments to built-ins; __builtin_constant_p should
      return constant false for a non-constant argument.  */
   constexpr_ctx new_ctx = *ctx;
--- gcc/cp/tree.c.jj    2019-11-15 00:37:14.452248140 +0100
+++ gcc/cp/tree.c       2019-11-15 09:39:58.507862806 +0100
@@ -445,7 +445,9 @@ builtin_valid_in_constant_expr_p (const_
   if (DECL_BUILT_IN_CLASS (decl) != BUILT_IN_NORMAL)
     {
       if (fndecl_built_in_p (decl, CP_BUILT_IN_IS_CONSTANT_EVALUATED,
-                          BUILT_IN_FRONTEND))
+                            BUILT_IN_FRONTEND)
+         || fndecl_built_in_p (decl, CP_BUILT_IN_SOURCE_LOCATION,
+                               BUILT_IN_FRONTEND))
        return true;
       /* Not a built-in.  */
       return false;
--- gcc/cp/decl.c.jj    2019-11-15 00:37:14.355249597 +0100
+++ gcc/cp/decl.c       2019-11-15 09:39:58.516862669 +0100
@@ -4290,6 +4290,12 @@ cxx_init_decl_processing (void)
                            BUILT_IN_FRONTEND, NULL, NULL_TREE);
   set_call_expr_flags (decl, ECF_CONST | ECF_NOTHROW | ECF_LEAF);
 
+  tree cptr_ftype = build_function_type_list (const_ptr_type_node, NULL_TREE);
+  decl = add_builtin_function ("__builtin_source_location",
+                              cptr_ftype, CP_BUILT_IN_SOURCE_LOCATION,
+                              BUILT_IN_FRONTEND, NULL, NULL_TREE);
+  set_call_expr_flags (decl, ECF_CONST | ECF_NOTHROW | ECF_LEAF);
+
   integer_two_node = build_int_cst (NULL_TREE, 2);
 
   /* Guess at the initial static decls size.  */
--- gcc/cp/name-lookup.c.jj     2019-11-15 00:37:14.410248771 +0100
+++ gcc/cp/name-lookup.c        2019-11-15 09:39:58.511862745 +0100
@@ -5747,6 +5747,8 @@ get_std_name_hint (const char *name)
     {"shared_lock", "<shared_mutex>", cxx14},
     {"shared_mutex", "<shared_mutex>", cxx17},
     {"shared_timed_mutex", "<shared_mutex>", cxx14},
+    /* <source_location>.  */
+    {"source_location", "<source_location>", cxx2a},
     /* <sstream>.  */
     {"basic_stringbuf", "<sstream>", cxx98},
     {"basic_istringstream", "<sstream>", cxx98},
--- gcc/testsuite/g++.dg/cpp2a/srcloc1.C.jj     2019-11-15 10:49:47.705194823 
+0100
+++ gcc/testsuite/g++.dg/cpp2a/srcloc1.C        2019-11-15 11:43:33.203286115 
+0100
@@ -0,0 +1,114 @@
+// { dg-do compile { target c++2a } }
+
+namespace std {
+  struct source_location {
+    struct __impl {
+      const char *__file_name;
+      const char *__function_name;
+      unsigned int __line, __column;
+    };
+    const __impl *__ptr;
+    constexpr source_location () : __ptr (nullptr) {}
+    static consteval source_location
+    current (const void *__p = __builtin_source_location ()) {
+      source_location __ret;
+      __ret.__ptr = static_cast <const __impl *> (__p);
+      return __ret;
+    }
+    constexpr const char *file_name () const {
+      return __ptr ? __ptr->__file_name : "";
+    }
+    constexpr const char *function_name () const {
+      return __ptr ? __ptr->__function_name : "";
+    }
+    constexpr unsigned line () const {
+      return __ptr ? __ptr->__line : 0;
+    }
+    constexpr unsigned column () const {
+      return __ptr ? __ptr->__column : 0;
+    }
+  };
+}
+
+using namespace std;
+
+consteval source_location
+bar (const source_location x = source_location::current ())
+{
+  return x;
+}
+
+void
+foo (const char **p, unsigned *q)
+{
+  constexpr source_location s = source_location::current ();
+  constexpr source_location t = bar ();
+  p[0] = s.file_name ();
+  p[1] = s.function_name ();
+  q[0] = s.line ();
+  q[1] = s.column ();
+  p[2] = t.file_name ();
+  p[3] = t.function_name ();
+  q[2] = t.line ();
+  q[3] = t.column ();
+  constexpr const char *r = s.file_name ();
+}
+
+source_location s3 = source_location::current ();
+
+template <int N>
+constexpr source_location
+baz ()
+{
+  return source_location::current ();
+}
+
+#define A \
+  source_location s[3] = { source_location::current (), \
+                          source_location::current (), \
+                          source_location::current () }
+
+source_location *
+boo ()
+{
+  static A;
+  return &s[0];
+}
+
+constexpr source_location s1 = baz <0> ();
+constexpr source_location s2 = baz <1> ();
+const source_location *p1 = &s1;
+const source_location *p2 = &s2;
+static_assert (source_location::current ().line () == __LINE__);
+static_assert (source_location::current ().column () == 42);
+
+constexpr bool
+quux ()
+{
+  const char *file1 = source_location::current ().file_name ();
+  const char *file2 = __FILE__;
+  const char *function1 = source_location::current ().function_name ();
+  const char *function2 = __FUNCTION__;
+  int line1 = source_location::current ().line ();
+  int line2 = __LINE__ - 1;
+  int column
+    = source_location::current ().column ();
+  int i = 0;
+  for (; file1[i]; i++)
+    if (file1[i] != file2[i])
+      return false;
+  if (file2[i])
+    return false;
+  for (i = 0; function1[i]; i++)
+    if (function1[i] != function2[i])
+      return false;
+  if (function2[i])
+    return false;
+  if (line1 != line2)
+    return false;
+  if (column != 33)
+    return false;
+  return true;
+}
+
+static_assert (quux ());
--- gcc/testsuite/g++.dg/cpp2a/srcloc2.C.jj     2019-11-15 10:50:58.372122068 
+0100
+++ gcc/testsuite/g++.dg/cpp2a/srcloc2.C        2019-11-15 11:44:12.267694376 
+0100
@@ -0,0 +1,118 @@
+// { dg-do compile { target c++2a } }
+
+namespace std {
+  inline namespace _8 { }
+  namespace _8 {
+  struct source_location {
+    struct __impl {
+      const char *__file_name;
+      const char *__function_name;
+      unsigned int __line, __column;
+    };
+    const __impl *__ptr;
+    constexpr source_location () : __ptr (nullptr) {}
+    static consteval source_location
+    current (const void *__p = __builtin_source_location ()) {
+      source_location __ret;
+      __ret.__ptr = static_cast <const __impl *> (__p);
+      return __ret;
+    }
+    constexpr const char *file_name () const {
+      return __ptr ? __ptr->__file_name : "";
+    }
+    constexpr const char *function_name () const {
+      return __ptr ? __ptr->__function_name : "";
+    }
+    constexpr unsigned line () const {
+      return __ptr ? __ptr->__line : 0;
+    }
+    constexpr unsigned column () const {
+      return __ptr ? __ptr->__column : 0;
+    }
+  };
+  }
+}
+
+using namespace std;
+
+consteval source_location
+bar (const source_location x = source_location::current ())
+{
+  return x;
+}
+
+void
+foo (const char **p, unsigned *q)
+{
+  constexpr source_location s = source_location::current ();
+  constexpr source_location t = bar ();
+  p[0] = s.file_name ();
+  p[1] = s.function_name ();
+  q[0] = s.line ();
+  q[1] = s.column ();
+  p[2] = t.file_name ();
+  p[3] = t.function_name ();
+  q[2] = t.line ();
+  q[3] = t.column ();
+  constexpr const char *r = s.file_name ();
+}
+
+source_location s3 = source_location::current ();
+
+template <int N>
+constexpr source_location
+baz ()
+{
+  return source_location::current ();
+}
+
+#define A \
+  source_location s[3] = { source_location::current (), \
+                          source_location::current (), \
+                          source_location::current () }
+
+source_location *
+boo ()
+{
+  static A;
+  return &s[0];
+}
+
+constexpr source_location s1 = baz <0> ();
+constexpr source_location s2 = baz <1> ();
+const source_location *p1 = &s1;
+const source_location *p2 = &s2;
+
+static_assert (source_location::current ().line () == __LINE__);
+static_assert (source_location::current ().column () == 42);
+
+constexpr bool
+quux ()
+{
+  const char *file1 = source_location::current ().file_name ();
+  const char *file2 = __FILE__;
+  const char *function1 = source_location::current ().function_name ();
+  const char *function2 = __FUNCTION__;
+  int line1 = source_location::current ().line ();
+  int line2 = __LINE__ - 1;
+  int column
+    = source_location::current ().column ();
+  int i = 0;
+  for (; file1[i]; i++)
+    if (file1[i] != file2[i])
+      return false;
+  if (file2[i])
+    return false;
+  for (i = 0; function1[i]; i++)
+    if (function1[i] != function2[i])
+      return false;
+  if (function2[i])
+    return false;
+  if (line1 != line2)
+    return false;
+  if (column != 33)
+    return false;
+  return true;
+}
+
+static_assert (quux ());
--- gcc/testsuite/g++.dg/cpp2a/srcloc3.C.jj     2019-11-15 10:53:14.183060484 
+0100
+++ gcc/testsuite/g++.dg/cpp2a/srcloc3.C        2019-11-15 11:25:03.541097184 
+0100
@@ -0,0 +1,5 @@
+// { dg-do compile { target c++2a } }
+
+auto x = __builtin_source_location (); // { dg-error "'source_location' is not 
a member of 'std'" }
+// { dg-message "std::source_location' is defined in header 
'<source_location>'; did you forget to '#include <source_location>'" "" { 
target *-*-* } .-1 }
+// { dg-message "evaluating '__builtin_source_location'" "" { target *-*-* } 
.-2 }
--- gcc/testsuite/g++.dg/cpp2a/srcloc4.C.jj     2019-11-15 10:56:23.052193749 
+0100
+++ gcc/testsuite/g++.dg/cpp2a/srcloc4.C        2019-11-15 11:25:03.541097184 
+0100
@@ -0,0 +1,8 @@
+// { dg-do compile { target c++2a } }
+
+namespace std {
+  void source_location ();
+}
+
+auto x = __builtin_source_location (); // { dg-error "'void 
std::source_location\\(\\)' is not a type" }
+// { dg-message "evaluating '__builtin_source_location'" "" { target *-*-* } 
.-1 }
--- gcc/testsuite/g++.dg/cpp2a/srcloc5.C.jj     2019-11-15 10:57:35.421095311 
+0100
+++ gcc/testsuite/g++.dg/cpp2a/srcloc5.C        2019-11-15 11:25:03.541097184 
+0100
@@ -0,0 +1,9 @@
+// { dg-do compile { target c++2a } }
+
+namespace std {
+  typedef int source_location;
+}
+
+auto x = __builtin_source_location (); // { dg-error 
"'std::source_location'\[^\n\r]*is not a class type" }
+// { dg-error "'__impl' is not a member of 'std::source_location'" "" { target 
*-*-* } .-1 }
+// { dg-message "evaluating '__builtin_source_location'" "" { target *-*-* } 
.-2 }
--- gcc/testsuite/g++.dg/cpp2a/srcloc6.C.jj     2019-11-15 11:00:52.896097950 
+0100
+++ gcc/testsuite/g++.dg/cpp2a/srcloc6.C        2019-11-15 11:25:03.541097184 
+0100
@@ -0,0 +1,9 @@
+// { dg-do compile { target c++2a } }
+
+namespace std {
+  struct source_location {
+  };
+}
+
+auto x = __builtin_source_location (); // { dg-error "'__impl' is not a member 
of 'std::source_location'" }
+// { dg-message "evaluating '__builtin_source_location'" "" { target *-*-* } 
.-1 }
--- gcc/testsuite/g++.dg/cpp2a/srcloc7.C.jj     2019-11-15 11:01:26.967580801 
+0100
+++ gcc/testsuite/g++.dg/cpp2a/srcloc7.C        2019-11-15 11:25:03.542097169 
+0100
@@ -0,0 +1,10 @@
+// { dg-do compile { target c++2a } }
+
+namespace std {
+  struct source_location {
+    static void __impl ();
+  };
+}
+
+auto x = __builtin_source_location (); // { dg-error 
"'std::source_location::__impl\\(\\)' is not a type" }
+// { dg-message "evaluating '__builtin_source_location'" "" { target *-*-* } 
.-1 }
--- gcc/testsuite/g++.dg/cpp2a/srcloc8.C.jj     2019-11-15 11:03:04.160105574 
+0100
+++ gcc/testsuite/g++.dg/cpp2a/srcloc8.C        2019-11-15 11:25:03.542097169 
+0100
@@ -0,0 +1,10 @@
+// { dg-do compile { target c++2a } }
+
+namespace std {
+  struct source_location {
+    typedef int __impl;
+  };
+}
+
+auto x = __builtin_source_location (); // { dg-error 
"'std::source_location::__impl()' is not a class type" }
+// { dg-message "evaluating '__builtin_source_location'" "" { target *-*-* } 
.-1 }
--- gcc/testsuite/g++.dg/cpp2a/srcloc9.C.jj     2019-11-15 11:04:03.663202412 
+0100
+++ gcc/testsuite/g++.dg/cpp2a/srcloc9.C        2019-11-15 11:25:03.542097169 
+0100
@@ -0,0 +1,11 @@
+// { dg-do compile { target c++2a } }
+
+namespace std {
+  struct source_location {
+    struct __impl {
+    };
+  };
+}
+
+auto x = __builtin_source_location (); // { dg-error 
"'std::source_location::__impl' does not contain only non-static data members 
'__file_name', '__function_name', '__line' and '__column'" }
+// { dg-message "evaluating '__builtin_source_location'" "" { target *-*-* } 
.-1 }
--- gcc/testsuite/g++.dg/cpp2a/srcloc10.C.jj    2019-11-15 11:05:09.253206861 
+0100
+++ gcc/testsuite/g++.dg/cpp2a/srcloc10.C       2019-11-15 11:25:03.542097169 
+0100
@@ -0,0 +1,13 @@
+// { dg-do compile { target c++2a } }
+
+namespace std {
+  struct source_location {
+    struct __impl {
+      const char *__file_name, *__function_name;
+      int __foo, __line, __column;
+    };
+  };
+}
+
+auto x = __builtin_source_location (); // { dg-error 
"'std::source_location::__impl' does not contain only non-static data members 
'__file_name', '__function_name', '__line' and '__column'" }
+// { dg-message "evaluating '__builtin_source_location'" "" { target *-*-* } 
.-1 }
--- gcc/testsuite/g++.dg/cpp2a/srcloc11.C.jj    2019-11-15 11:06:01.856408428 
+0100
+++ gcc/testsuite/g++.dg/cpp2a/srcloc11.C       2019-11-15 11:25:03.542097169 
+0100
@@ -0,0 +1,13 @@
+// { dg-do compile { target c++2a } }
+
+namespace std {
+  struct source_location {
+    struct __impl {
+      const char *__file_name, *__function_name;
+      int __line;
+    };
+  };
+}
+
+auto x = __builtin_source_location (); // { dg-error 
"'std::source_location::__impl' does not contain only non-static data members 
'__file_name', '__function_name', '__line' and '__column'" }
+// { dg-message "evaluating '__builtin_source_location'" "" { target *-*-* } 
.-1 }
--- gcc/testsuite/g++.dg/cpp2a/srcloc12.C.jj    2019-11-15 11:06:25.999041982 
+0100
+++ gcc/testsuite/g++.dg/cpp2a/srcloc12.C       2019-11-15 11:25:03.543097153 
+0100
@@ -0,0 +1,14 @@
+// { dg-do compile { target c++2a } }
+
+namespace std {
+  struct source_location {
+    struct __impl {
+      const void *__file_name;
+      const char *__function_name;
+      int __line, __column;
+    };
+  };
+}
+
+auto x = __builtin_source_location (); // { dg-error 
"'std::source_location::__impl::__file_name' does not have 'const char \\*' 
type" }
+// { dg-message "evaluating '__builtin_source_location'" "" { target *-*-* } 
.-1 }
--- gcc/testsuite/g++.dg/cpp2a/srcloc13.C.jj    2019-11-15 11:18:34.184999454 
+0100
+++ gcc/testsuite/g++.dg/cpp2a/srcloc13.C       2019-11-15 11:25:03.543097153 
+0100
@@ -0,0 +1,15 @@
+// { dg-do compile { target c++2a } }
+
+namespace std {
+  struct source_location {
+    struct __impl {
+      const char *__file_name;
+      const char *__function_name;
+      float __line;
+      int __column;
+    };
+  };
+}
+
+auto x = __builtin_source_location (); // { dg-error 
"'std::source_location::__impl::__line' does not have integral type" }
+// { dg-message "evaluating '__builtin_source_location'" "" { target *-*-* } 
.-1 }
--- gcc/testsuite/g++.dg/cpp2a/srcloc14.C.jj    2019-11-15 11:19:51.561826493 
+0100
+++ gcc/testsuite/g++.dg/cpp2a/srcloc14.C       2019-11-15 11:25:03.543097153 
+0100
@@ -0,0 +1,15 @@
+// { dg-do compile { target c++2a } }
+
+namespace std {
+  struct source_location {
+    struct __impl {
+      // Test that ordering doesn't matter
+      long long __column;
+      const char *__file_name;
+      int __line;
+      const char *__function_name;
+    };
+  };
+}
+
+auto x = __builtin_source_location ();


        Jakub

Reply via email to