aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/constraint.cc15
-rw-r--r--gcc/cp/pt.c2
-rw-r--r--gcc/testsuite/g++.dg/concepts/diagnostic1.C4
-rw-r--r--gcc/testsuite/g++.dg/concepts/placeholder3.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/placeholder4.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/concepts-pr67178.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/concepts-requires6.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/concepts-return-req1.C19
9 files changed, 43 insertions, 13 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index efb135e..585420a 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,11 @@
+2019-10-30 Jason Merrill <jason@redhat.com>
+
+ PR c++/92268 - hard error satisfying return-type-requirement
+ * constraint.cc (type_deducible_p): Check for substitution failure.
+ (diagnose_compound_requirement): Adjust diagnostic.
+ * pt.c (do_auto_deduction): Don't pass cargs to
+ constraints_satisfied_p.
+
2019-10-30 Jakub Jelinek <jakub@redhat.com>
PR c++/91369 - Implement P0784R7: constexpr new
diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index b8a2645..db2a30c 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -1822,10 +1822,7 @@ tsubst_type_requirement (tree t, tree args, subst_info info)
return finish_type_requirement (EXPR_LOCATION (t), type);
}
-/* True if TYPE can be deduced from EXPR.
-
- FIXME: C++20 compound requirement constraints should be normalized and then
- satisfied rather than substituted. */
+/* True if TYPE can be deduced from EXPR. */
static bool
type_deducible_p (tree expr, tree type, tree placeholder, tree args,
@@ -1839,12 +1836,17 @@ type_deducible_p (tree expr, tree type, tree placeholder, tree args,
substitutes args into any template parameters in the trailing
result type. */
tree saved_constr = PLACEHOLDER_TYPE_CONSTRAINTS (placeholder);
- PLACEHOLDER_TYPE_CONSTRAINTS (placeholder)
+ tree subst_constr
= tsubst_constraint (saved_constr,
args,
info.complain | tf_partial,
info.in_decl);
+ if (subst_constr == error_mark_node)
+ return false;
+
+ PLACEHOLDER_TYPE_CONSTRAINTS (placeholder) = subst_constr;
+
/* Temporarily unlink the canonical type. */
tree saved_type = TYPE_CANONICAL (placeholder);
TYPE_CANONICAL (placeholder) = NULL_TREE;
@@ -3139,7 +3141,8 @@ diagnose_compound_requirement (tree req, tree args, tree in_decl)
if (!type_deducible_p (expr, type, placeholder, args, quiet))
{
tree orig_expr = TREE_OPERAND (req, 0);
- inform (loc, "type deduction from %qE failed", orig_expr);
+ inform (loc, "%qE does not satisfy return-type-requirement",
+ orig_expr);
/* Further explain the reason for the error. */
type_deducible_p (expr, type, placeholder, args, noisy);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index c5675dd..414140a 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -28138,7 +28138,7 @@ do_auto_deduction (tree type, tree init, tree auto_node,
/* Rebuild the check using the deduced arguments. */
check = build_concept_check (cdecl, cargs, tf_none);
- if (!constraints_satisfied_p (check, cargs))
+ if (!constraints_satisfied_p (check))
{
if (complain & tf_warning_or_error)
{
diff --git a/gcc/testsuite/g++.dg/concepts/diagnostic1.C b/gcc/testsuite/g++.dg/concepts/diagnostic1.C
index ced56d4..7da08db 100644
--- a/gcc/testsuite/g++.dg/concepts/diagnostic1.C
+++ b/gcc/testsuite/g++.dg/concepts/diagnostic1.C
@@ -8,12 +8,12 @@ concept bool SameAs = __is_same_as(T, U);
template <class T>
concept bool R1 = requires (T& t) { // { dg-message "in requirements" }
{ t.begin() } -> T; // { dg-error "no match" }
- { t.end() } -> SameAs<T*>; // { dg-error "does not satisfy" }
+ { t.end() } -> SameAs<T*>; // { dg-message "does not satisfy" }
};
template <class T>
concept bool R2 = requires (T& t) { // { dg-message "in requirements" }
- { t.end() } -> SameAs<T*>; // { dg-error "does not satisfy" }
+ { t.end() } -> SameAs<T*>; // { dg-message "does not satisfy" }
};
struct foo {
diff --git a/gcc/testsuite/g++.dg/concepts/placeholder3.C b/gcc/testsuite/g++.dg/concepts/placeholder3.C
index 4f8600b..d90e5cf 100644
--- a/gcc/testsuite/g++.dg/concepts/placeholder3.C
+++ b/gcc/testsuite/g++.dg/concepts/placeholder3.C
@@ -8,7 +8,7 @@ concept bool Same = __is_same_as(T, U);
template <class T>
concept bool C =
requires { // { dg-message "in requirements" }
- { 0 } -> Same<T>; // { dg-error "does not satisfy" }
+ { 0 } -> Same<T>; // { dg-message "does not satisfy" }
};
template <C c>
diff --git a/gcc/testsuite/g++.dg/concepts/placeholder4.C b/gcc/testsuite/g++.dg/concepts/placeholder4.C
index 2b5afbb..ab9d8e6 100644
--- a/gcc/testsuite/g++.dg/concepts/placeholder4.C
+++ b/gcc/testsuite/g++.dg/concepts/placeholder4.C
@@ -8,7 +8,7 @@ concept bool Same = __is_same_as(T, U);
template <class T>
concept bool C =
requires { // { dg-message "in requirements" }
- { 0 } -> Same<T>; // { dg-error "does not satisfy" }
+ { 0 } -> Same<T>; // { dg-message "does not satisfy" }
};
template <class T>
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67178.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67178.C
index f76f2e3..264b873 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67178.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67178.C
@@ -12,7 +12,7 @@ concept C0 = requires (auto x) { // { dg-error "placeholder type" }
template<typename T>
concept C1 = requires (C1 auto x) { // { dg-error "not been declared|placeholder|two or more|in requirements" }
x; // { dg-error "not declared" }
- { x } -> c; // { dg-error "not declared|does not satisfy" }
+ { x } -> c; // { dg-message "not declared|does not satisfy" }
};
template<typename T>
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-requires6.C b/gcc/testsuite/g++.dg/cpp2a/concepts-requires6.C
index 20df78b..065876e 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts-requires6.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-requires6.C
@@ -10,7 +10,7 @@ concept SameAs = __is_same_as(T, U);
template <typename T>
concept C1 = requires(T t) { // { dg-message "in requirements" }
{ t } -> SameAs<T>; // NOTE: t deduced as decltype((t))
- // { dg-error "does not satisfy placeholder constraints" "" { target *-*-* } .-1 }
+ // { dg-message "does not satisfy" "" { target *-*-* } .-1 }
};
template <typename T>
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-return-req1.C b/gcc/testsuite/g++.dg/cpp2a/concepts-return-req1.C
new file mode 100644
index 0000000..1d005f0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-return-req1.C
@@ -0,0 +1,19 @@
+// PR c++/92268
+// { dg-do compile { target c++2a } }
+
+template <class T> concept Two = true;
+template <class T> concept One = Two<typename T::type>;
+template <class T> concept Zero = requires
+ {
+ { T() } -> One;
+ };
+
+template <class T>
+void f() requires Zero<T>;
+template <class T>
+int f(...);
+
+int main()
+{
+ f<int>();
+}