@@ -1492,7 +1492,7 @@ cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun,
temp_override<tree> ovr (current_function_decl);
if (ctx->call && ctx->call->fundef)
current_function_decl = ctx->call->fundef->decl;
- return fold_builtin_source_location (EXPR_LOCATION (t));
+ return fold_builtin_source_location (t);
}
int strops = 0;
@@ -722,7 +722,7 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
break;
case CP_BUILT_IN_SOURCE_LOCATION:
*expr_p
- = fold_builtin_source_location (EXPR_LOCATION (*expr_p));
+ = fold_builtin_source_location (*expr_p);
break;
case CP_BUILT_IN_IS_CORRESPONDING_MEMBER:
*expr_p
@@ -2850,7 +2850,7 @@ cp_fold (tree x)
case CP_BUILT_IN_IS_CONSTANT_EVALUATED:
break;
case CP_BUILT_IN_SOURCE_LOCATION:
- x = fold_builtin_source_location (EXPR_LOCATION (x));
+ x = fold_builtin_source_location (x);
break;
case CP_BUILT_IN_IS_CORRESPONDING_MEMBER:
x = fold_builtin_is_corresponding_member
@@ -2872,7 +2872,7 @@ cp_fold (tree x)
&& fndecl_built_in_p (callee, CP_BUILT_IN_SOURCE_LOCATION,
BUILT_IN_FRONTEND))
{
- x = fold_builtin_source_location (EXPR_LOCATION (x));
+ x = fold_builtin_source_location (x);
break;
}
@@ -3171,12 +3171,11 @@ process_stmt_assume_attribute (tree std_attrs, tree statement,
return remove_attribute ("gnu", "assume", std_attrs);
}
-/* Helper of fold_builtin_source_location, return the
- std::source_location::__impl type after performing verification
- on it. LOC is used for reporting any errors. */
+/* Return the type std::source_location::__impl after performing verification
+ on it. */
-static tree
-get_source_location_impl_type (location_t loc)
+tree
+get_source_location_impl_type ()
{
tree name = get_identifier ("source_location");
tree decl = lookup_qualified_name (std_node, name);
@@ -3184,9 +3183,9 @@ get_source_location_impl_type (location_t loc)
{
auto_diagnostic_group d;
if (decl == error_mark_node || TREE_CODE (decl) == TREE_LIST)
- qualified_name_lookup_error (std_node, name, decl, loc);
+ qualified_name_lookup_error (std_node, name, decl, input_location);
else
- error_at (loc, "%qD is not a type", decl);
+ error ("%qD is not a type", decl);
return error_mark_node;
}
name = get_identifier ("__impl");
@@ -3196,15 +3195,15 @@ get_source_location_impl_type (location_t loc)
{
auto_diagnostic_group d;
if (decl == error_mark_node || TREE_CODE (decl) == TREE_LIST)
- qualified_name_lookup_error (type, name, decl, loc);
+ qualified_name_lookup_error (type, name, decl, input_location);
else
- error_at (loc, "%qD is not a type", decl);
+ error ("%qD is not a type", decl);
return error_mark_node;
}
type = TREE_TYPE (decl);
if (TREE_CODE (type) != RECORD_TYPE)
{
- error_at (loc, "%qD is not a class type", decl);
+ error ("%qD is not a class type", decl);
return error_mark_node;
}
@@ -3221,8 +3220,7 @@ get_source_location_impl_type (location_t loc)
{
if (TREE_TYPE (field) != const_string_type_node)
{
- error_at (loc, "%qD does not have %<const char *%> type",
- field);
+ error ("%qD does not have %<const char *%> type", field);
return error_mark_node;
}
cnt++;
@@ -3232,7 +3230,7 @@ get_source_location_impl_type (location_t loc)
{
if (TREE_CODE (TREE_TYPE (field)) != INTEGER_TYPE)
{
- error_at (loc, "%qD does not have integral type", field);
+ error ("%qD does not have integral type", field);
return error_mark_node;
}
cnt++;
@@ -3244,9 +3242,9 @@ get_source_location_impl_type (location_t loc)
}
if (cnt != 4)
{
- error_at (loc, "%<std::source_location::__impl%> does not contain only "
- "non-static data members %<_M_file_name%>, "
- "%<_M_function_name%>, %<_M_line%> and %<_M_column%>");
+ error ("%<std::source_location::__impl%> does not contain only "
+ "non-static data members %<_M_file_name%>, "
+ "%<_M_function_name%>, %<_M_line%> and %<_M_column%>");
return error_mark_node;
}
return build_qualified_type (type, TYPE_QUAL_CONST);
@@ -3337,21 +3335,21 @@ 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. */
+/* Fold the __builtin_source_location () call T. */
tree
-fold_builtin_source_location (location_t loc)
+fold_builtin_source_location (const_tree t)
{
- if (source_location_impl == NULL_TREE)
- {
- auto_diagnostic_group d;
- source_location_impl = get_source_location_impl_type (loc);
- if (source_location_impl == error_mark_node)
- inform (loc, "evaluating %qs", "__builtin_source_location");
- }
+ gcc_assert (TREE_CODE (t) == CALL_EXPR);
+ /* TREE_TYPE (t) is const std::source_location::__impl* */
+ tree source_location_impl = TREE_TYPE (TREE_TYPE (t));
if (source_location_impl == error_mark_node)
return build_zero_cst (const_ptr_type_node);
+ gcc_assert (CLASS_TYPE_P (source_location_impl)
+ && id_equal (DECL_NAME (TYPE_NAME (source_location_impl)),
+ "__impl"));
+
+ location_t loc = EXPR_LOCATION (t);
if (source_location_table == NULL)
source_location_table
= hash_table <source_location_table_entry_hash>::create_ggc (64);
@@ -3427,7 +3425,7 @@ fold_builtin_source_location (location_t loc)
entryp->var = var;
}
- return build_fold_addr_expr_with_type_loc (loc, var, const_ptr_type_node);
+ return build_fold_addr_expr_with_type_loc (loc, var, TREE_TYPE (t));
}
#include "gt-cp-cp-gimplify.h"
@@ -235,8 +235,6 @@ enum cp_tree_index
CPTI_PSEUDO_CONTRACT_VIOLATION,
- CPTI_SOURCE_LOCATION_IMPL,
-
CPTI_FALLBACK_DFLOAT32_TYPE,
CPTI_FALLBACK_DFLOAT64_TYPE,
CPTI_FALLBACK_DFLOAT128_TYPE,
@@ -395,9 +393,6 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX];
/* 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. */
@@ -8295,7 +8290,8 @@ extern tree process_stmt_hotness_attribute (tree, location_t);
extern tree build_assume_call (location_t, tree);
extern tree process_stmt_assume_attribute (tree, tree, location_t);
extern bool simple_empty_class_p (tree, tree, tree_code);
-extern tree fold_builtin_source_location (location_t);
+extern tree fold_builtin_source_location (const_tree);
+extern tree get_source_location_impl_type ();
/* in name-lookup.cc */
extern tree strip_using_decl (tree);
@@ -4669,9 +4669,13 @@ 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);
+ /* The concrete return type of __builtin_source_location is
+ const std::source_location::__impl*, but we can't form the type
+ at this point. So we initially use a deduced return type and
+ update it from require_deduced_type upon first use. */
+ tree auto_ftype = build_function_type_list (make_auto (), NULL_TREE);
decl = add_builtin_function ("__builtin_source_location",
- cptr_ftype, CP_BUILT_IN_SOURCE_LOCATION,
+ auto_ftype, CP_BUILT_IN_SOURCE_LOCATION,
BUILT_IN_FRONTEND, NULL, NULL_TREE);
set_call_expr_flags (decl, ECF_CONST | ECF_NOTHROW | ECF_LEAF);
@@ -18751,6 +18755,23 @@ require_deduced_type (tree decl, tsubst_flags_t complain)
{
if (undeduced_auto_decl (decl))
{
+ if (TREE_CODE (decl) == FUNCTION_DECL
+ && fndecl_built_in_p (decl, BUILT_IN_FRONTEND)
+ && DECL_FE_FUNCTION_CODE (decl) == CP_BUILT_IN_SOURCE_LOCATION)
+ {
+ /* Determine the return type of __builtin_source_location. */
+ tree type = get_source_location_impl_type ();
+ if (type == error_mark_node)
+ {
+ inform (input_location, "using %qs", "__builtin_source_location");
+ return false;
+ }
+ type = cp_build_qualified_type (type, TYPE_QUAL_CONST);
+ type = build_pointer_type (type);
+ apply_deduced_return_type (decl, type);
+ return true;
+ }
+
if (warning_suppressed_p (decl) && seen_error ())
/* We probably already complained about deduction failure. */;
else if (complain & tf_error)
@@ -10,4 +10,4 @@ namespace std {
}
auto x = __builtin_source_location (); // { dg-error "'std::source_location::__impl' does not contain only non-static data members '_M_file_name', '_M_function_name', '_M_line' and '_M_column'" }
-// { dg-message "evaluating '__builtin_source_location'" "" { target *-*-* } .-1 }
+// { dg-message "using '__builtin_source_location'" "" { target *-*-* } .-1 }
@@ -10,4 +10,4 @@ namespace std {
}
auto x = __builtin_source_location (); // { dg-error "'std::source_location::__impl' does not contain only non-static data members '_M_file_name', '_M_function_name', '_M_line' and '_M_column'" }
-// { dg-message "evaluating '__builtin_source_location'" "" { target *-*-* } .-1 }
+// { dg-message "using '__builtin_source_location'" "" { target *-*-* } .-1 }
@@ -11,4 +11,4 @@ namespace std {
}
auto x = __builtin_source_location (); // { dg-error "'std::source_location::__impl::_M_file_name' does not have 'const char \\*' type" }
-// { dg-message "evaluating '__builtin_source_location'" "" { target *-*-* } .-1 }
+// { dg-message "using '__builtin_source_location'" "" { target *-*-* } .-1 }
@@ -12,4 +12,4 @@ namespace std {
}
auto x = __builtin_source_location (); // { dg-error "'std::source_location::__impl::_M_line' does not have integral type" }
-// { dg-message "evaluating '__builtin_source_location'" "" { target *-*-* } .-1 }
+// { dg-message "using '__builtin_source_location'" "" { target *-*-* } .-1 }
@@ -2,4 +2,4 @@
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 }
+// { dg-message "using '__builtin_source_location'" "" { target *-*-* } .-2 }
@@ -5,4 +5,4 @@ namespace std {
}
auto x = __builtin_source_location (); // { dg-error "'void std::source_location\\(\\)' is not a type" }
-// { dg-message "evaluating '__builtin_source_location'" "" { target *-*-* } .-1 }
+// { dg-message "using '__builtin_source_location'" "" { target *-*-* } .-1 }
@@ -6,4 +6,4 @@ namespace std {
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 }
+// { dg-message "using '__builtin_source_location'" "" { target *-*-* } .-2 }
@@ -6,4 +6,4 @@ namespace std {
}
auto x = __builtin_source_location (); // { dg-error "'__impl' is not a member of 'std::source_location'" }
-// { dg-message "evaluating '__builtin_source_location'" "" { target *-*-* } .-1 }
+// { dg-message "using '__builtin_source_location'" "" { target *-*-* } .-1 }
@@ -7,4 +7,4 @@ namespace std {
}
auto x = __builtin_source_location (); // { dg-error "'std::source_location::__impl\\(\\)' is not a type" }
-// { dg-message "evaluating '__builtin_source_location'" "" { target *-*-* } .-1 }
+// { dg-message "using '__builtin_source_location'" "" { target *-*-* } .-1 }
@@ -7,4 +7,4 @@ namespace std {
}
auto x = __builtin_source_location (); // { dg-error "'std::source_location::__impl()' is not a class type" }
-// { dg-message "evaluating '__builtin_source_location'" "" { target *-*-* } .-1 }
+// { dg-message "using '__builtin_source_location'" "" { target *-*-* } .-1 }
@@ -8,4 +8,4 @@ namespace std {
}
auto x = __builtin_source_location (); // { dg-error "'std::source_location::__impl' does not contain only non-static data members '_M_file_name', '_M_function_name', '_M_line' and '_M_column'" }
-// { dg-message "evaluating '__builtin_source_location'" "" { target *-*-* } .-1 }
+// { dg-message "using '__builtin_source_location'" "" { target *-*-* } .-1 }
new file mode 100644
@@ -0,0 +1,28 @@
+// PR c++/100881
+// { dg-additional-options "-std=c++20 -fmodules-ts" }
+// { dg-module-cmi pr100881 }
+module;
+#include <source_location>
+export module pr100881;
+
+export consteval int
+current_line_fn(const std::source_location& loc = std::source_location::current())
+{
+ return loc.line();
+}
+
+export struct current_line_cls
+{
+ int line = std::source_location::current().line();
+};
+
+export template<class T> consteval int
+current_line_fn_tmpl(const std::source_location& loc = std::source_location::current())
+{
+ return loc.line();
+}
+
+export template<class T> struct current_line_cls_tmpl
+{
+ int line = std::source_location::current().line();
+};
new file mode 100644
@@ -0,0 +1,8 @@
+// PR c++/100881
+// { dg-additional-options "-std=c++20 -fmodules-ts" }
+import pr100881;
+
+static_assert(current_line_fn() == 5);
+static_assert(current_line_cls{}.line == 6);
+static_assert(current_line_fn_tmpl<int>() == 7);
+static_assert(current_line_cls_tmpl<int>{}.line == 8);