This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[C++ PATCH] diagnose address and decltype of unsatisfied function


While looking at one of the issues under discussion at the meeting, I noticed we weren't diagnosing a couple of cases of unsatisfied un-overloaded functions.

It also seems to me that -fconcepts-ts ought to imply -fconcepts for pre-C++20 modes.

Tested x86_64-pc-linux-gnu, applying to trunk.
commit 88d071f8e0a1637bc95e78c5a52ff44423946bfc
Author: Jason Merrill <jason@redhat.com>
Date:   Tue Nov 5 10:44:34 2019 +0000

    Catch missed uses of function with unsatisfied constraints.
    
    While looking at CA378 I noticed that we weren't properly diagnosing two of
    the three erroneous lines in the example.
    
            * decl2.c (mark_used): Diagnose use of a function with unsatisfied
            constraints here.
            * typeck.c (cp_build_function_call_vec): Not here.

diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index b9f3b87b60b..4dc54811122 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -5524,6 +5524,21 @@ mark_used (tree decl, tsubst_flags_t complain)
      directly.  */
   maybe_instantiate_decl (decl);
 
+  if (flag_concepts && TREE_CODE (decl) == FUNCTION_DECL
+      && !constraints_satisfied_p (decl))
+    {
+      if (complain & tf_error)
+	{
+	  auto_diagnostic_group d;
+	  error ("use of function %qD with unsatisfied constraints",
+		 decl);
+	  location_t loc = DECL_SOURCE_LOCATION (decl);
+	  inform (loc, "declared here");
+	  diagnose_constraints (loc, decl, NULL_TREE);
+	}
+      return false;
+    }
+
   if (processing_template_decl || in_template_function ())
     return true;
 
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 27d97859cb3..eefb83d3207 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -3871,26 +3871,6 @@ cp_build_function_call_vec (tree function, vec<tree, va_gc> **params,
 
   if (TREE_CODE (function) == FUNCTION_DECL)
     {
-      /* If the function is a non-template member function
-         or a non-template friend, then we need to check the
-         constraints.
-
-        Note that if overload resolution failed with a single
-        candidate this function will be used to explicitly diagnose
-        the failure for the single call expression. The check is
-        technically redundant since we also would have failed in
-        add_function_candidate. */
-      if (flag_concepts
-          && (complain & tf_error)
-          && !constraints_satisfied_p (function))
-        {
-          auto_diagnostic_group d;
-          error ("cannot call function %qD", function);
-          location_t loc = DECL_SOURCE_LOCATION (function);
-          diagnose_constraints (loc, function, NULL_TREE);
-          return error_mark_node;
-        }
-
       if (!mark_used (function, complain))
 	return error_mark_node;
       fndecl = function;
diff --git a/gcc/testsuite/g++.dg/concepts/dr1430.C b/gcc/testsuite/g++.dg/concepts/dr1430.C
index 6f5bab1e106..05c91526c20 100644
--- a/gcc/testsuite/g++.dg/concepts/dr1430.C
+++ b/gcc/testsuite/g++.dg/concepts/dr1430.C
@@ -41,6 +41,6 @@ requires Similar<Args...> // { dg-error "pack expansion" }
 
 int main()
 {
-  foo(1, 2, 3); // { dg-error "cannot call" }
-  bar(1, 2, 3); // { dg-error "cannot call" }
+  foo(1, 2, 3); // { dg-error "" }
+  bar(1, 2, 3); // { dg-error "" }
 }
diff --git a/gcc/testsuite/g++.dg/concepts/expression2.C b/gcc/testsuite/g++.dg/concepts/expression2.C
index 1cff60542f5..60dd5414461 100644
--- a/gcc/testsuite/g++.dg/concepts/expression2.C
+++ b/gcc/testsuite/g++.dg/concepts/expression2.C
@@ -31,7 +31,7 @@ class S
 
 int main()
 {
-  f1(s); // { dg-error "cannot call|private" }
+  f1(s); // { dg-error "unsatisfied|private" }
   f2(s); // { dg-error "" }
 
   // When used in non-SFINAE contexts, make sure that we fail
diff --git a/gcc/testsuite/g++.dg/concepts/fn2.C b/gcc/testsuite/g++.dg/concepts/fn2.C
index debb3238a6e..1c1280c9d15 100644
--- a/gcc/testsuite/g++.dg/concepts/fn2.C
+++ b/gcc/testsuite/g++.dg/concepts/fn2.C
@@ -11,9 +11,9 @@ template<typename T>
 // Non-dependent args are checked even in dependent scope.
 template<typename T>
   void h(T x) {
-    f(0); // { dg-error "cannot call" }
+    f(0); // { dg-error "" }
   }
 
 int main() {
-  f(0); // { dg-error "cannot call" }
+  f(0); // { dg-error "" }
 }
diff --git a/gcc/testsuite/g++.dg/concepts/fn5.C b/gcc/testsuite/g++.dg/concepts/fn5.C
index 7714788c3c0..6d86ac5d0af 100644
--- a/gcc/testsuite/g++.dg/concepts/fn5.C
+++ b/gcc/testsuite/g++.dg/concepts/fn5.C
@@ -19,6 +19,6 @@ int main() {
   S1<char> s1;      // { dg-error "constraint|invalid" }
   S2<int, char> s2; // { dg-error "constraint|invalid" }
 
-  f('a');    // { dg-error "cannot" }
-  g(0, 'a'); // { dg-error "cannot" }
+  f('a');    // { dg-error "unsatisfied" }
+  g(0, 'a'); // { dg-error "unsatisfied" }
 }
diff --git a/gcc/testsuite/g++.dg/concepts/fn8.C b/gcc/testsuite/g++.dg/concepts/fn8.C
index ffcce4f0220..ed900809908 100644
--- a/gcc/testsuite/g++.dg/concepts/fn8.C
+++ b/gcc/testsuite/g++.dg/concepts/fn8.C
@@ -8,7 +8,7 @@ template<Class T> void f(T) { }
 
 template<typename T> void fn(T) { }
 
-auto p1 = &f<int>; // { dg-error "no matches" }
+auto p1 = &f<int>; // { dg-error "" }
 void (*p2)(int) = &f<int>; // { dg-error "no matches" }
 void (*p3)(int) = &f; // { dg-error "no matches" }
 
@@ -16,7 +16,7 @@ struct S {
   template<Class T> int f(T) { return 0; }
 };
 
-auto p4 = &S::template f<int>; // { dg-error "no matches" }
+auto p4 = &S::template f<int>; // { dg-error "" }
 int (S::*p6)(int) = &S::template f<int>; // { dg-error "no matches" }
 int (S::*p7)(int) = &S::f; // { dg-error "no matches" }
 
diff --git a/gcc/testsuite/g++.dg/concepts/placeholder5.C b/gcc/testsuite/g++.dg/concepts/placeholder5.C
index 7881a40a22a..eccad65a301 100644
--- a/gcc/testsuite/g++.dg/concepts/placeholder5.C
+++ b/gcc/testsuite/g++.dg/concepts/placeholder5.C
@@ -14,5 +14,5 @@ concept bool C =
 template <C c>
 constexpr bool f() { return true; }
 
-static_assert(f<double>(), "");	// { dg-error "cannot call|as type" }
-static_assert(f<int>(), ""); // { dg-error "cannot call|as type" }
+static_assert(f<double>(), "");	// { dg-error "unsatisfied|as type" }
+static_assert(f<int>(), ""); // { dg-error "unsatisfied|as type" }
diff --git a/gcc/testsuite/g++.dg/concepts/template-parm11.C b/gcc/testsuite/g++.dg/concepts/template-parm11.C
index 07ad6e284e9..257e7c691db 100644
--- a/gcc/testsuite/g++.dg/concepts/template-parm11.C
+++ b/gcc/testsuite/g++.dg/concepts/template-parm11.C
@@ -15,5 +15,5 @@ void getTable(const ColSpec&...)
 
 void f()
 {
-  getTable(7, 'a'); // { dg-error "cannot call" }
+  getTable(7, 'a'); // { dg-error "" }
 };
diff --git a/gcc/testsuite/g++.dg/concepts/var-concept2.C b/gcc/testsuite/g++.dg/concepts/var-concept2.C
index 4ff00a008b9..5e1faec213f 100644
--- a/gcc/testsuite/g++.dg/concepts/var-concept2.C
+++ b/gcc/testsuite/g++.dg/concepts/var-concept2.C
@@ -12,7 +12,7 @@ void f2(C1) {}
 
 int main ()
 {
-  f1(0, 0); // { dg-error "cannot call" }
-  f2(1); // { dg-error "cannot call" }
+  f1(0, 0); // { dg-error "" }
+  f2(1); // { dg-error "" }
   return 0;
 }
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-dr1430.C b/gcc/testsuite/g++.dg/cpp2a/concepts-dr1430.C
index f39921fcec7..91eefee602a 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts-dr1430.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-dr1430.C
@@ -10,5 +10,5 @@ void foo( Args... args ) {}
 
 int main()
 {
-  foo(1, 2, 3); // { dg-error "cannot call" }
+  foo(1, 2, 3); // { dg-error "" }
 }
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-fn1.C b/gcc/testsuite/g++.dg/cpp2a/concepts-fn1.C
index 33f3a7490bb..9287ab8e5d7 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts-fn1.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-fn1.C
@@ -35,7 +35,7 @@ int fn2(T t) { return 0; }
 void driver()
 {
   fn1(0); // OK
-  fn2(0); // { dg-error "cannot call function" }
+  fn2(0); // { dg-error "" }
 }
 
 // Ordering
@@ -126,7 +126,7 @@ void caller_1(T x)
 { 
   f1(x); // Unchecked dependent arg.
   f1(empty{}); // Checked non-dependent arg, but OK
-  f1(0); // { dg-error "cannot call function" }
+  f1(0); // { dg-error "" }
 }
 
 // fn3.c -- Ordering
@@ -159,7 +159,7 @@ template<typename T> requires Type<T> void ok(T) { }
 template<typename T> requires Class<T> void err(T) { }
 
 auto p1 = &ok<int>;
-auto p2 = &err<int>; // { dg-error "no matches" }
+auto p2 = &err<int>; // { dg-error "" }
 void (*p3)(int) = &ok<int>;
 void (*p4)(int) = &err<int>; // { dg-error "no matches" }
 void (*p5)(int) = &ok;
@@ -180,7 +180,7 @@ struct S2 {
 };
 
 auto p7 = &S2::ok<int>;
-auto p8 = &S2::err<int>; // { dg-error "no matches" }
+auto p8 = &S2::err<int>; // { dg-error "" }
 int (S2::*p9)(int) = &S2::ok<int>;
 int (S2::*p10)(int) = &S2::err<int>; // { dg-error "no matches" }
 int (S2::*p11)(int) = &S2::ok;
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-fn3.C b/gcc/testsuite/g++.dg/cpp2a/concepts-fn3.C
index e73ae23881a..b25adcc17c0 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts-fn3.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-fn3.C
@@ -31,11 +31,11 @@ struct S
 int main()
 {
   f1(1, 2, 3);
-  f1(1, 2, 3u); // { dg-error "cannot call" }
+  f1(1, 2, 3u); // { dg-error "" }
   f2(1, 2, 3);
-  f2(1, 2, 3u); // { dg-error "cannot call" }
+  f2(1, 2, 3u); // { dg-error "" }
   f3(1, 2, 3);
-  f3(1, 2, 3u); // { dg-error "cannot call" }
+  f3(1, 2, 3u); // { dg-error "" }
   f3(1u, 2, 3);
 
   S<void> s;
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-fn4.C b/gcc/testsuite/g++.dg/cpp2a/concepts-fn4.C
new file mode 100644
index 00000000000..8a29ca9360c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-fn4.C
@@ -0,0 +1,11 @@
+// Testcase from [expr.prim.id]/5
+// { dg-do compile { target c++2a } }
+
+template<typename T> struct A {
+  static void f(int) requires false;
+};
+void g() {
+  A<int>::f(0);			// { dg-error "" "cannot call f" }
+  void (*p1)(int) = A<int>::f;  // { dg-error "" "cannot take the address of f" }
+  decltype(A<int>::f)* p2 = nullptr; // { dg-error "" "the type decltype(A<int>::f) is invalid" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-friend1.C b/gcc/testsuite/g++.dg/cpp2a/concepts-friend1.C
index da97575687f..e3740d5170e 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts-friend1.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-friend1.C
@@ -23,7 +23,7 @@ struct X { } x;
 
 int main() {
   // f(0); // OK
-  f(nt); // { dg-error "cannot call" }
+  f(nt); // { dg-error "" }
   f(x);  // { dg-error "3:'f' was not declared" }
 
   S<int> si;
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-noexcept1.C b/gcc/testsuite/g++.dg/cpp2a/concepts-noexcept1.C
index e5a9b72b4fd..418040aa56e 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts-noexcept1.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-noexcept1.C
@@ -20,6 +20,6 @@ template<C2 T>
 void g2(T t);
 
 void test() {
-  g1(0); // { dg-error "cannot call" }
+  g1(0); // { dg-error "" }
   g2(0);
 }
\ No newline at end of file
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-p1141.C b/gcc/testsuite/g++.dg/cpp2a/concepts-p1141.C
index deb409aa12c..ac240a5b2d5 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts-p1141.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-p1141.C
@@ -79,9 +79,9 @@ void f20(Class auto x, Class auto y) { }
 
 void driver_1()
 {
-  f19(0); // { dg-error "cannot call function" }
+  f19(0); // { dg-error "" }
   f19(empty{});
-  f20(0, empty{}); // { dg-error "cannot call function" }
+  f20(0, empty{}); // { dg-error "" }
   f20(empty{}, empty{});
 }
 
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr65575.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr65575.C
index 3bfde5e2c75..3ab7c9b6082 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr65575.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr65575.C
@@ -19,5 +19,5 @@ int g(int (*)() requires true); // { dg-error "" }
 int
 main()
 {
-  f1(); // { dg-error "cannot call" }
+  f1(); // { dg-error "" }
 }
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr65854.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr65854.C
index a21073c4d67..53bb9a355f1 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr65854.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr65854.C
@@ -19,4 +19,4 @@ template<typename T1, typename T2>
   requires C<T1, T2>
 int f();
 
-auto i = f<char, int>(); // { dg-error "cannot call function" }
+auto i = f<char, int>(); // { dg-error "" }
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr66844.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr66844.C
index 64baab1dca0..c32f4d1184b 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr66844.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr66844.C
@@ -13,4 +13,4 @@ template <typename T>
   requires C<T>
 constexpr bool is_c() { return true; }
 
-static_assert(is_c<void>(), ""); // { dg-error "cannot call" }
+static_assert(is_c<void>(), ""); // { dg-error "" }
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67070.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67070.C
index 548cb402fac..88017dc723f 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67070.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67070.C
@@ -46,6 +46,6 @@ struct X {
 };
 
 void test2() {
-  g1<X, X>(); // { dg-error "cannot call" }
-  g2<X, X>(); // { dg-error "cannot call" }
+  g1<X, X>(); // { dg-error "" }
+  g2<X, X>(); // { dg-error "" }
 }
\ No newline at end of file
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67178.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67178.C
index 264b873c7f4..ff84711a7af 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67178.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67178.C
@@ -20,7 +20,7 @@ template<typename T>
 void f(T) {}
 
 int main() {
-  f(1); // { dg-error "cannot call" }
+  f(1); // { dg-error "" }
 }
 
 
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67225-1.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67225-1.C
index 1c5d73a33d0..500e6314119 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67225-1.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67225-1.C
@@ -28,5 +28,5 @@ struct Y {private: ~Y();};
 
 int main()
 {
-    f<Y>(); // { dg-error "cannot call" }
+    f<Y>(); // { dg-error "" }
 }
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr68093-1.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr68093-1.C
index bc4ddee5770..bf952103841 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr68093-1.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr68093-1.C
@@ -9,5 +9,5 @@ struct S
 
 int main()
 {
-  foobar(S<double>{}, int{}); // { dg-error "cannot call" }
+  foobar(S<double>{}, int{}); // { dg-error "" }
 }
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-requires1.C b/gcc/testsuite/g++.dg/cpp2a/concepts-requires1.C
index f1603af8015..0c2651620ba 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts-requires1.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-requires1.C
@@ -26,7 +26,7 @@ void driver_1() {
   struct S { } s;
   f4(s);
   f5(0);
-  f5((void*)0); // { dg-error "cannot call" }
+  f5((void*)0); // { dg-error "" }
   test.f(s);
 }
 
@@ -67,5 +67,5 @@ void print2(const T& x) { }
 
 void driver_3()
 {
-  print2("hello"); // { dg-error "cannot call" }
+  print2("hello"); // { dg-error "" }
 }
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-requires15.C b/gcc/testsuite/g++.dg/cpp2a/concepts-requires15.C
index 81d919682dc..9b82061af11 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts-requires15.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-requires15.C
@@ -9,7 +9,7 @@ template<C T>
 void fun(T s) { }
 
 int main(int, char **) {
-  fun((int *)0); // { dg-error "cannot call function" }
+  fun((int *)0); // { dg-error "" }
   return 0;
 }
 
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-requires16.C b/gcc/testsuite/g++.dg/cpp2a/concepts-requires16.C
index 209c91657aa..b9532a36eb5 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts-requires16.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-requires16.C
@@ -37,11 +37,11 @@ void f7() { }
 
 void driver()
 {
-  f1<int, int>(); // { dg-error "cannot call function" }
+  f1<int, int>(); // { dg-error "" }
   f3<int, int>();
-  f3<int, void>(); // { dg-error "cannot call function" }
+  f3<int, void>(); // { dg-error "" }
   f4<int, int>();
-  f4<int, void>(); // { dg-error "cannot call function" }
+  f4<int, void>(); // { dg-error "" }
   f7<int>();
   f7<int, int>();
 }
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-requires2.C b/gcc/testsuite/g++.dg/cpp2a/concepts-requires2.C
index 45bb423af65..73cee220567 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts-requires2.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-requires2.C
@@ -18,7 +18,7 @@ template<typename T> requires Bad<T> void bad(T x) { }
 
 void driver_2()
 {
-  bad(0); // { dg-error "cannot call" }
+  bad(0); // { dg-error "" }
 }
 
 // req6.C
@@ -41,8 +41,8 @@ void h2(T);
 
 void driver_3()
 {
-  h1(0); // { dg-error "cannot call" }
-  h2(0); // { dg-error "cannot call" } 
+  h1(0); // { dg-error "" }
+  h2(0); // { dg-error "" } 
 }
 
 // req7.C
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-requires6.C b/gcc/testsuite/g++.dg/cpp2a/concepts-requires6.C
index 065876e94e4..d9899250342 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts-requires6.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-requires6.C
@@ -17,9 +17,9 @@ template <typename T>
   requires C1<T>
 constexpr bool f1() { return true; }
 
-static_assert(f1<char>()); // { dg-error "cannot call" }
-static_assert(f1<int>()); // { dg-error "cannot call" }
-static_assert(f1<double>()); // { dg-error "cannot call" }
+static_assert(f1<char>()); // { dg-error "" }
+static_assert(f1<int>()); // { dg-error "" }
+static_assert(f1<double>()); // { dg-error "" }
 
 
 template <typename T>
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-requires8.C b/gcc/testsuite/g++.dg/cpp2a/concepts-requires8.C
index f10e4bcdb9a..0d61a0ab313 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts-requires8.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-requires8.C
@@ -13,5 +13,5 @@ int main()
 {
   // FIXME: This diagnostic is being emitted twice, when it should
   // be emitted just once.
-  using U = decltype(f(42, non_addable{})); // { dg-error "cannot call function" }
+  using U = decltype(f(42, non_addable{})); // { dg-error "" }
 }
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-traits1.C b/gcc/testsuite/g++.dg/cpp2a/concepts-traits1.C
index 0ea529ef4a6..710ded45fdd 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts-traits1.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-traits1.C
@@ -77,21 +77,21 @@ template<Union T> void f17() { }
 template<Enum T> void f18() { }
 
 int main() {
-  f1<void>(); // { dg-error "cannot call" }
-  f2<void>(); // { dg-error "cannot call" }
-  f3<void>(); // { dg-error "cannot call" }
-  f4<void>(); // { dg-error "cannot call" }
-  f5<void>(); // { dg-error "cannot call" }
-  f6<void>(); // { dg-error "cannot call" }
-  f7<void>(); // { dg-error "cannot call" }
-  f8<void>(); // { dg-error "cannot call" }
-  f9<void>(); // { dg-error "cannot call" }
-  f10<void>(); // { dg-error "cannot call" }
-  f11<void>(); // { dg-error "cannot call" }
-  f12<void>(); // { dg-error "cannot call" }
-  f13<void>(); // { dg-error "cannot call" }
-  f14<void>(); // { dg-error "cannot call" }
-  f15<void>(); // { dg-error "cannot call" }
-  f16<void>(); // { dg-error "cannot call" }
-  f17<void>(); // { dg-error "cannot call" }
+  f1<void>(); // { dg-error "" }
+  f2<void>(); // { dg-error "" }
+  f3<void>(); // { dg-error "" }
+  f4<void>(); // { dg-error "" }
+  f5<void>(); // { dg-error "" }
+  f6<void>(); // { dg-error "" }
+  f7<void>(); // { dg-error "" }
+  f8<void>(); // { dg-error "" }
+  f9<void>(); // { dg-error "" }
+  f10<void>(); // { dg-error "" }
+  f11<void>(); // { dg-error "" }
+  f12<void>(); // { dg-error "" }
+  f13<void>(); // { dg-error "" }
+  f14<void>(); // { dg-error "" }
+  f15<void>(); // { dg-error "" }
+  f16<void>(); // { dg-error "" }
+  f17<void>(); // { dg-error "" }
 }
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-traits2.C b/gcc/testsuite/g++.dg/cpp2a/concepts-traits2.C
index 1dc5ffe9c00..2bdd3d370c2 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts-traits2.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-traits2.C
@@ -78,21 +78,21 @@ template<Enum T> void f18();
 
 
 int main() {
-  f1<void>(); // { dg-error "cannot call" }
-  f2<void>(); // { dg-error "cannot call" }
-  f3<void>(); // { dg-error "cannot call" }
-  f4<void>(); // { dg-error "cannot call" }
-  f5<void>(); // { dg-error "cannot call" }
-  f6<void>(); // { dg-error "cannot call" }
-  f7<void>(); // { dg-error "cannot call" }
-  f8<void>(); // { dg-error "cannot call" }
-  f9<void>(); // { dg-error "cannot call" }
-  f10<void>(); // { dg-error "cannot call" }
-  f11<void>(); // { dg-error "cannot call" }
-  f12<void>(); // { dg-error "cannot call" }
-  f13<void>(); // { dg-error "cannot call" }
-  f14<void>(); // { dg-error "cannot call" }
-  f15<void>(); // { dg-error "cannot call" }
-  f16<void>(); // { dg-error "cannot call" }
-  f17<void>(); // { dg-error "cannot call" }
+  f1<void>(); // { dg-error "" }
+  f2<void>(); // { dg-error "" }
+  f3<void>(); // { dg-error "" }
+  f4<void>(); // { dg-error "" }
+  f5<void>(); // { dg-error "" }
+  f6<void>(); // { dg-error "" }
+  f7<void>(); // { dg-error "" }
+  f8<void>(); // { dg-error "" }
+  f9<void>(); // { dg-error "" }
+  f10<void>(); // { dg-error "" }
+  f11<void>(); // { dg-error "" }
+  f12<void>(); // { dg-error "" }
+  f13<void>(); // { dg-error "" }
+  f14<void>(); // { dg-error "" }
+  f15<void>(); // { dg-error "" }
+  f16<void>(); // { dg-error "" }
+  f17<void>(); // { dg-error "" }
 }
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-ts1.C b/gcc/testsuite/g++.dg/cpp2a/concepts-ts1.C
index b819ad4a1a2..b3acec15986 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts-ts1.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-ts1.C
@@ -35,11 +35,11 @@ auto f15(auto x) -> SameAs<decltype(x)> { return 0; } // { dg-error "deduced ret
 void driver()
 {
   f1(0);
-  f2(0); // { dg-error "cannot call" }
+  f2(0); // { dg-error "" }
   f3(0);
-  f3('a'); // { dg-error "cannot call" }
+  f3('a'); // { dg-error "" }
   f4(0, 0);
-  f4(0, 'a'); // { dg-error "cannot call" }
+  f4(0, 'a'); // { dg-error "" }
   f15(0);
   f15('a'); // { dg-message "" }
 }
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-ts2.C b/gcc/testsuite/g++.dg/cpp2a/concepts-ts2.C
index 9d2dbeee7f3..f731bac8c2a 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts-ts2.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-ts2.C
@@ -38,7 +38,7 @@ int fn2(T t) { return 0; }
 void driver()
 {
   fn1(0); // OK
-  fn2(0); // { dg-error "cannot call function" }
+  fn2(0); // { dg-error "" }
 }
 
 // Ordering
@@ -129,7 +129,7 @@ void caller_1(T x)
 { 
   f1(x); // Unchecked dependent arg.
   f1(empty{}); // Checked non-dependent arg, but OK
-  f1(0); // { dg-error "cannot call function" }
+  f1(0); // { dg-error "" }
 }
 
 // fn3.c -- Ordering
@@ -162,7 +162,7 @@ template<typename T> requires (Type<T>()) void ok(T) { }
 template<typename T> requires (Class<T>()) void err(T) { }
 
 auto p1 = &ok<int>;
-auto p2 = &err<int>; // { dg-error "no matches" }
+auto p2 = &err<int>; // { dg-error "" }
 void (*p3)(int) = &ok<int>;
 void (*p4)(int) = &err<int>; // { dg-error "no matches" }
 void (*p5)(int) = &ok;
@@ -183,7 +183,7 @@ struct S2 {
 };
 
 auto p7 = &S2::ok<int>;
-auto p8 = &S2::err<int>; // { dg-error "no matches" }
+auto p8 = &S2::err<int>; // { dg-error "" }
 int (S2::*p9)(int) = &S2::ok<int>;
 int (S2::*p10)(int) = &S2::err<int>; // { dg-error "no matches" }
 int (S2::*p11)(int) = &S2::ok;
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-ts3.C b/gcc/testsuite/g++.dg/cpp2a/concepts-ts3.C
index c1f4ba9c700..434a5e2651b 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts-ts3.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-ts3.C
@@ -38,7 +38,7 @@ int fn2(T t) { return 0; }
 void driver()
 {
   fn1(0); // OK
-  fn2(0); // { dg-error "cannot call function" }
+  fn2(0); // { dg-error "" }
 }
 
 // Ordering
@@ -129,7 +129,7 @@ void caller_1(T x)
 { 
   f1(x); // Unchecked dependent arg.
   f1(empty{}); // Checked non-dependent arg, but OK
-  f1(0); // { dg-error "cannot call function" }
+  f1(0); // { dg-error "" }
 }
 
 // fn3.c -- Ordering
@@ -162,7 +162,7 @@ template<typename T> requires Type<T> void ok(T) { }
 template<typename T> requires Class<T> void err(T) { }
 
 auto p1 = &ok<int>;
-auto p2 = &err<int>; // { dg-error "no matches" }
+auto p2 = &err<int>; // { dg-error "" }
 void (*p3)(int) = &ok<int>;
 void (*p4)(int) = &err<int>; // { dg-error "no matches" }
 void (*p5)(int) = &ok;
@@ -183,7 +183,7 @@ struct S2 {
 };
 
 auto p7 = &S2::ok<int>;
-auto p8 = &S2::err<int>; // { dg-error "no matches" }
+auto p8 = &S2::err<int>; // { dg-error "" }
 int (S2::*p9)(int) = &S2::ok<int>;
 int (S2::*p10)(int) = &S2::err<int>; // { dg-error "no matches" }
 int (S2::*p11)(int) = &S2::ok;
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-ts4.C b/gcc/testsuite/g++.dg/cpp2a/concepts-ts4.C
index 3d720e86f3b..aa96621d9cf 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts-ts4.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-ts4.C
@@ -23,12 +23,12 @@ Pos{N} void fn();
 void driver()
 {
   f1(0);
-  f2(0); // { dg-error "cannot call function" }
+  f2(0); // { dg-error "" }
 
   same<int, int>();
-  same<int, char>(); // { dg-error "cannot call function" }
+  same<int, char>(); // { dg-error "" }
 
   fn<0>(); // OK
-  fn<-1>(); // { dg-error "cannot call function" }
+  fn<-1>(); // { dg-error "" }
   fn<int>(); // { dg-error "no matching function" }
 }
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts1.C b/gcc/testsuite/g++.dg/cpp2a/concepts1.C
index f22464a9c54..a99343fc04d 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts1.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts1.C
@@ -19,7 +19,7 @@ void decl1(T);
 
 void driver_1()
 {
-  f1(0); // { dg-error "cannot call function" }
+  f1(0); // { dg-error "" }
   f1(empty{});
 
   decl1(empty{}); // { dg-error "call of overload | ambiguous" }
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts3.C b/gcc/testsuite/g++.dg/cpp2a/concepts3.C
index d9624268082..34dacade330 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts3.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts3.C
@@ -42,7 +42,7 @@ template<typename T>
 void f3() { }
 
 void driver2() {
-  f1<S1>(); // { dg-error "cannot call|is private" }
-  f2<S1>(); // { dg-error "cannot call|is private" }
-  f3<S1>(); // { dg-error "cannot call|is private" }
+  f1<S1>(); // { dg-error "unsatisfied|is private" }
+  f2<S1>(); // { dg-error "unsatisfied|is private" }
+  f3<S1>(); // { dg-error "unsatisfied|is private" }
 }
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 4d9d56755f3..00f5218799e 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2019-11-05  Jason Merrill  <jason@redhat.com>
+
+	* decl2.c (mark_used): Diagnose use of a function with unsatisfied
+	constraints here.
+	* typeck.c (cp_build_function_call_vec): Not here.
+
 2019-11-05  Nathan Sidwell  <nathan@acm.org>
 
 	PR c++/92370
commit 6b776fd14bf1acc6e7064e44c7ad1602081492f3
Author: Jason Merrill <jason@redhat.com>
Date:   Tue Nov 5 16:09:21 2019 +0000

    Make -fconcepts-ts imply -fconcepts.
    
            * c-opts.c (c_common_post_options): -fconcepts-ts implies
            -fconcepts.

diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c
index d4c77be5cd5..b84f05c64c7 100644
--- a/gcc/c-family/c-opts.c
+++ b/gcc/c-family/c-opts.c
@@ -1038,7 +1038,7 @@ c_common_post_options (const char **pfilename)
      to know when concepts are enabled. Note that -fconcepts-ts can
      be used to include additional features, although modified to
      work with the standard.  */
-  if (cxx_dialect >= cxx2a)
+  if (cxx_dialect >= cxx2a || flag_concepts_ts)
     flag_concepts = 1;
   else if (flag_concepts)
     /* For -std=c++17 -fconcepts, imply -fconcepts-ts.  */
diff --git a/gcc/testsuite/g++.dg/concepts/fn7.C b/gcc/testsuite/g++.dg/concepts/fn7.C
index 869cb9c9391..1994feca84b 100644
--- a/gcc/testsuite/g++.dg/concepts/fn7.C
+++ b/gcc/testsuite/g++.dg/concepts/fn7.C
@@ -1,5 +1,5 @@
 // { dg-do link { target c++14 } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
 
 void f() requires true { }
 
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index d95424537a9..7f402960fc3 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,8 @@
+2019-11-05  Jason Merrill  <jason@redhat.com>
+
+	* c-opts.c (c_common_post_options): -fconcepts-ts implies
+	-fconcepts.
+
 2019-11-04  Kamlesh Kumar  <kamleshbhalui@gmail.com>
 
 	* c-opts.c (c_common_post_options): Update

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]