diff options
Diffstat (limited to 'gcc/cp/constraint.cc')
-rw-r--r-- | gcc/cp/constraint.cc | 74 |
1 files changed, 68 insertions, 6 deletions
diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc index 2f1678c..c8eef24 100644 --- a/gcc/cp/constraint.cc +++ b/gcc/cp/constraint.cc @@ -1836,7 +1836,7 @@ tsubst_parameter_mapping (tree map, tree args, tsubst_flags_t complain, tree in_ static bool satisfying_constraint; /* A vector of incomplete types (and of declarations with undeduced return type), - appended to by note_failed_type_completion_for_satisfaction. The + appended to by note_failed_type_completion. The satisfaction caches use this in order to keep track of "potentially unstable" satisfaction results. @@ -1845,21 +1845,69 @@ static bool satisfying_constraint; static GTY((deletable)) vec<tree, va_gc> *failed_type_completions; +/* A map of where types were found to be incomplete in SFINAE context, for + warning if they are later completed. */ + +static GTY((cache)) hash_map<tree, location_t, decl_location_traits> *failed_completions_map; + /* Called whenever a type completion (or return type deduction) failure occurs that definitely affects the meaning of the program, by e.g. inducing substitution failure. */ void -note_failed_type_completion_for_satisfaction (tree t) +note_failed_type_completion (tree t, tsubst_flags_t complain) { + if (dependent_template_arg_p (t)) + return; + + gcc_checking_assert ((TYPE_P (t) && !COMPLETE_TYPE_P (t)) + || (DECL_P (t) && undeduced_auto_decl (t))); + if (satisfying_constraint) + vec_safe_push (failed_type_completions, t); + + if (TYPE_P (t)) { - gcc_checking_assert ((TYPE_P (t) && !COMPLETE_TYPE_P (t)) - || (DECL_P (t) && undeduced_auto_decl (t))); - vec_safe_push (failed_type_completions, t); + if (!CLASS_TYPE_P (t)) + return; + t = TYPE_MAIN_DECL (t); + } + if (!(complain & tf_error) + && warning_enabled_at (DECL_SOURCE_LOCATION (t), + OPT_Wsfinae_incomplete_)) + { + if (warn_sfinae_incomplete > 1) + { + if (TREE_CODE (t) == TYPE_DECL) + warning (OPT_Wsfinae_incomplete_, + "failed to complete %qT in SFINAE context", TREE_TYPE (t)); + else + warning (OPT_Wsfinae_incomplete_, + "failed to deduce %qD in SFINAE context", t); + } + if (!failed_completions_map) + failed_completions_map + = hash_map<tree, location_t, decl_location_traits>::create_ggc (); + failed_completions_map->put (t, input_location); } } +/* If T was previously found to be incomplete in SFINAE context, return the + location where that happened, otherwise UNKNOWN_LOCATION. */ + +location_t +failed_completion_location (tree t) +{ + if (failed_completions_map) + { + if (TYPE_P (t)) + t = TYPE_MAIN_DECL (t); + if (location_t *p = failed_completions_map->get (t)) + return *p; + } + return UNKNOWN_LOCATION; +} + /* Returns true if the range [BEGIN, END) of elements within the failed_type_completions vector contains a complete type (or a declaration with a non-placeholder return type). */ @@ -2704,6 +2752,8 @@ satisfy_declaration_constraints (tree t, sat_info info) static tree satisfy_declaration_constraints (tree t, tree args, sat_info info) { + tree orig_args = args; + /* Update the declaration for diagnostics. */ info.in_decl = t; @@ -2732,7 +2782,7 @@ satisfy_declaration_constraints (tree t, tree args, sat_info info) tree result = boolean_true_node; if (tree norm = get_normalized_constraints_from_decl (t, info.noisy ())) { - if (!push_tinst_level (t, args)) + if (!push_tinst_level (t, orig_args)) return result; tree pattern = DECL_TEMPLATE_RESULT (t); push_to_top_level (); @@ -3098,6 +3148,9 @@ diagnose_trait_expr (tree expr, tree args) case CPTK_IS_CONVERTIBLE: inform (loc, " %qT is not convertible from %qE", t2, t1); break; + case CPTK_IS_DESTRUCTIBLE: + inform (loc, " %qT is not destructible", t1); + break; case CPTK_IS_EMPTY: inform (loc, " %qT is not an empty class", t1); break; @@ -3143,6 +3196,9 @@ diagnose_trait_expr (tree expr, tree args) case CPTK_IS_NOTHROW_CONVERTIBLE: inform (loc, " %qT is not nothrow convertible from %qE", t2, t1); break; + case CPTK_IS_NOTHROW_DESTRUCTIBLE: + inform (loc, " %qT is not nothrow destructible", t1); + break; case CPTK_IS_NOTHROW_INVOCABLE: if (!t2) inform (loc, " %qT is not nothrow invocable", t1); @@ -3192,6 +3248,9 @@ diagnose_trait_expr (tree expr, tree args) case CPTK_IS_TRIVIALLY_COPYABLE: inform (loc, " %qT is not trivially copyable", t1); break; + case CPTK_IS_TRIVIALLY_DESTRUCTIBLE: + inform (loc, " %qT is not trivially destructible", t1); + break; case CPTK_IS_UNBOUNDED_ARRAY: inform (loc, " %qT is not an unbounded array", t1); break; @@ -3207,6 +3266,9 @@ diagnose_trait_expr (tree expr, tree args) case CPTK_RANK: inform (loc, " %qT cannot yield a rank", t1); break; + case CPTK_TYPE_ORDER: + inform (loc, " %qT and %qT cannot be ordered", t1, t2); + break; case CPTK_REF_CONSTRUCTS_FROM_TEMPORARY: inform (loc, " %qT is not a reference that binds to a temporary " "object of type %qT (direct-initialization)", t1, t2); |