diff options
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/constexpr.cc | 2 | ||||
-rw-r--r-- | gcc/cp/cp-gimplify.cc | 57 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 8 | ||||
-rw-r--r-- | gcc/cp/decl.cc | 25 |
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) |