aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/constexpr.cc2
-rw-r--r--gcc/cp/cp-gimplify.cc57
-rw-r--r--gcc/cp/cp-tree.h8
-rw-r--r--gcc/cp/decl.cc25
4 files changed, 53 insertions, 39 deletions
diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index e43d928..d99c49b 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -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;
diff --git a/gcc/cp/cp-gimplify.cc b/gcc/cp/cp-gimplify.cc
index 983f2a5..1e0b4f8 100644
--- a/gcc/cp/cp-gimplify.cc
+++ b/gcc/cp/cp-gimplify.cc
@@ -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,20 @@ 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 (TYPE_IDENTIFIER (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 +3424,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"
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 0d6c234..541d760 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.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. */
@@ -8296,7 +8291,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);
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 5081563..df74d88 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -4670,9 +4670,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 declare it with an auto return
+ type which we then "deduce" 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);
@@ -18752,6 +18756,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)
+ {
+ /* Set 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)