aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/constraint.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/constraint.cc')
-rw-r--r--gcc/cp/constraint.cc70
1 files changed, 65 insertions, 5 deletions
diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 44fb086..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,19 +1845,67 @@ 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))
+ {
+ 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)
{
- 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 (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
@@ -3100,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;
@@ -3145,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);
@@ -3194,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;
@@ -3209,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);