Commit 8aa76bb7 by Jason Merrill Committed by Jason Merrill

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.

From-SVN: r277860
parent 0df65305
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> 2019-11-05 Nathan Sidwell <nathan@acm.org>
PR c++/92370 PR c++/92370
......
...@@ -5524,6 +5524,21 @@ mark_used (tree decl, tsubst_flags_t complain) ...@@ -5524,6 +5524,21 @@ mark_used (tree decl, tsubst_flags_t complain)
directly. */ directly. */
maybe_instantiate_decl (decl); 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 ()) if (processing_template_decl || in_template_function ())
return true; return true;
......
...@@ -3871,26 +3871,6 @@ cp_build_function_call_vec (tree function, vec<tree, va_gc> **params, ...@@ -3871,26 +3871,6 @@ cp_build_function_call_vec (tree function, vec<tree, va_gc> **params,
if (TREE_CODE (function) == FUNCTION_DECL) 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)) if (!mark_used (function, complain))
return error_mark_node; return error_mark_node;
fndecl = function; fndecl = function;
......
...@@ -41,6 +41,6 @@ requires Similar<Args...> // { dg-error "pack expansion" } ...@@ -41,6 +41,6 @@ requires Similar<Args...> // { dg-error "pack expansion" }
int main() int main()
{ {
foo(1, 2, 3); // { dg-error "cannot call" } foo(1, 2, 3); // { dg-error "" }
bar(1, 2, 3); // { dg-error "cannot call" } bar(1, 2, 3); // { dg-error "" }
} }
...@@ -31,7 +31,7 @@ class S ...@@ -31,7 +31,7 @@ class S
int main() int main()
{ {
f1(s); // { dg-error "cannot call|private" } f1(s); // { dg-error "unsatisfied|private" }
f2(s); // { dg-error "" } f2(s); // { dg-error "" }
// When used in non-SFINAE contexts, make sure that we fail // When used in non-SFINAE contexts, make sure that we fail
......
...@@ -11,9 +11,9 @@ template<typename T> ...@@ -11,9 +11,9 @@ template<typename T>
// Non-dependent args are checked even in dependent scope. // Non-dependent args are checked even in dependent scope.
template<typename T> template<typename T>
void h(T x) { void h(T x) {
f(0); // { dg-error "cannot call" } f(0); // { dg-error "" }
} }
int main() { int main() {
f(0); // { dg-error "cannot call" } f(0); // { dg-error "" }
} }
...@@ -19,6 +19,6 @@ int main() { ...@@ -19,6 +19,6 @@ int main() {
S1<char> s1; // { dg-error "constraint|invalid" } S1<char> s1; // { dg-error "constraint|invalid" }
S2<int, char> s2; // { dg-error "constraint|invalid" } S2<int, char> s2; // { dg-error "constraint|invalid" }
f('a'); // { dg-error "cannot" } f('a'); // { dg-error "unsatisfied" }
g(0, 'a'); // { dg-error "cannot" } g(0, 'a'); // { dg-error "unsatisfied" }
} }
...@@ -8,7 +8,7 @@ template<Class T> void f(T) { } ...@@ -8,7 +8,7 @@ template<Class T> void f(T) { }
template<typename T> void fn(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 (*p2)(int) = &f<int>; // { dg-error "no matches" }
void (*p3)(int) = &f; // { dg-error "no matches" } void (*p3)(int) = &f; // { dg-error "no matches" }
...@@ -16,7 +16,7 @@ struct S { ...@@ -16,7 +16,7 @@ struct S {
template<Class T> int f(T) { return 0; } 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::*p6)(int) = &S::template f<int>; // { dg-error "no matches" }
int (S::*p7)(int) = &S::f; // { dg-error "no matches" } int (S::*p7)(int) = &S::f; // { dg-error "no matches" }
......
...@@ -14,5 +14,5 @@ concept bool C = ...@@ -14,5 +14,5 @@ concept bool C =
template <C c> template <C c>
constexpr bool f() { return true; } constexpr bool f() { return true; }
static_assert(f<double>(), ""); // { dg-error "cannot call|as type" } static_assert(f<double>(), ""); // { dg-error "unsatisfied|as type" }
static_assert(f<int>(), ""); // { dg-error "cannot call|as type" } static_assert(f<int>(), ""); // { dg-error "unsatisfied|as type" }
...@@ -15,5 +15,5 @@ void getTable(const ColSpec&...) ...@@ -15,5 +15,5 @@ void getTable(const ColSpec&...)
void f() void f()
{ {
getTable(7, 'a'); // { dg-error "cannot call" } getTable(7, 'a'); // { dg-error "" }
}; };
...@@ -12,7 +12,7 @@ void f2(C1) {} ...@@ -12,7 +12,7 @@ void f2(C1) {}
int main () int main ()
{ {
f1(0, 0); // { dg-error "cannot call" } f1(0, 0); // { dg-error "" }
f2(1); // { dg-error "cannot call" } f2(1); // { dg-error "" }
return 0; return 0;
} }
...@@ -10,5 +10,5 @@ void foo( Args... args ) {} ...@@ -10,5 +10,5 @@ void foo( Args... args ) {}
int main() int main()
{ {
foo(1, 2, 3); // { dg-error "cannot call" } foo(1, 2, 3); // { dg-error "" }
} }
...@@ -35,7 +35,7 @@ int fn2(T t) { return 0; } ...@@ -35,7 +35,7 @@ int fn2(T t) { return 0; }
void driver() void driver()
{ {
fn1(0); // OK fn1(0); // OK
fn2(0); // { dg-error "cannot call function" } fn2(0); // { dg-error "" }
} }
// Ordering // Ordering
...@@ -126,7 +126,7 @@ void caller_1(T x) ...@@ -126,7 +126,7 @@ void caller_1(T x)
{ {
f1(x); // Unchecked dependent arg. f1(x); // Unchecked dependent arg.
f1(empty{}); // Checked non-dependent arg, but OK f1(empty{}); // Checked non-dependent arg, but OK
f1(0); // { dg-error "cannot call function" } f1(0); // { dg-error "" }
} }
// fn3.c -- Ordering // fn3.c -- Ordering
...@@ -159,7 +159,7 @@ template<typename T> requires Type<T> void ok(T) { } ...@@ -159,7 +159,7 @@ template<typename T> requires Type<T> void ok(T) { }
template<typename T> requires Class<T> void err(T) { } template<typename T> requires Class<T> void err(T) { }
auto p1 = &ok<int>; auto p1 = &ok<int>;
auto p2 = &err<int>; // { dg-error "no matches" } auto p2 = &err<int>; // { dg-error "" }
void (*p3)(int) = &ok<int>; void (*p3)(int) = &ok<int>;
void (*p4)(int) = &err<int>; // { dg-error "no matches" } void (*p4)(int) = &err<int>; // { dg-error "no matches" }
void (*p5)(int) = &ok; void (*p5)(int) = &ok;
...@@ -180,7 +180,7 @@ struct S2 { ...@@ -180,7 +180,7 @@ struct S2 {
}; };
auto p7 = &S2::ok<int>; 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::*p9)(int) = &S2::ok<int>;
int (S2::*p10)(int) = &S2::err<int>; // { dg-error "no matches" } int (S2::*p10)(int) = &S2::err<int>; // { dg-error "no matches" }
int (S2::*p11)(int) = &S2::ok; int (S2::*p11)(int) = &S2::ok;
......
...@@ -31,11 +31,11 @@ struct S ...@@ -31,11 +31,11 @@ struct S
int main() int main()
{ {
f1(1, 2, 3); 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, 3);
f2(1, 2, 3u); // { dg-error "cannot call" } f2(1, 2, 3u); // { dg-error "" }
f3(1, 2, 3); f3(1, 2, 3);
f3(1, 2, 3u); // { dg-error "cannot call" } f3(1, 2, 3u); // { dg-error "" }
f3(1u, 2, 3); f3(1u, 2, 3);
S<void> s; S<void> s;
......
// 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" }
}
...@@ -23,7 +23,7 @@ struct X { } x; ...@@ -23,7 +23,7 @@ struct X { } x;
int main() { int main() {
// f(0); // OK // f(0); // OK
f(nt); // { dg-error "cannot call" } f(nt); // { dg-error "" }
f(x); // { dg-error "3:'f' was not declared" } f(x); // { dg-error "3:'f' was not declared" }
S<int> si; S<int> si;
......
...@@ -20,6 +20,6 @@ template<C2 T> ...@@ -20,6 +20,6 @@ template<C2 T>
void g2(T t); void g2(T t);
void test() { void test() {
g1(0); // { dg-error "cannot call" } g1(0); // { dg-error "" }
g2(0); g2(0);
} }
\ No newline at end of file
...@@ -79,9 +79,9 @@ void f20(Class auto x, Class auto y) { } ...@@ -79,9 +79,9 @@ void f20(Class auto x, Class auto y) { }
void driver_1() void driver_1()
{ {
f19(0); // { dg-error "cannot call function" } f19(0); // { dg-error "" }
f19(empty{}); f19(empty{});
f20(0, empty{}); // { dg-error "cannot call function" } f20(0, empty{}); // { dg-error "" }
f20(empty{}, empty{}); f20(empty{}, empty{});
} }
......
...@@ -19,5 +19,5 @@ int g(int (*)() requires true); // { dg-error "" } ...@@ -19,5 +19,5 @@ int g(int (*)() requires true); // { dg-error "" }
int int
main() main()
{ {
f1(); // { dg-error "cannot call" } f1(); // { dg-error "" }
} }
...@@ -19,4 +19,4 @@ template<typename T1, typename T2> ...@@ -19,4 +19,4 @@ template<typename T1, typename T2>
requires C<T1, T2> requires C<T1, T2>
int f(); int f();
auto i = f<char, int>(); // { dg-error "cannot call function" } auto i = f<char, int>(); // { dg-error "" }
...@@ -13,4 +13,4 @@ template <typename T> ...@@ -13,4 +13,4 @@ template <typename T>
requires C<T> requires C<T>
constexpr bool is_c() { return true; } constexpr bool is_c() { return true; }
static_assert(is_c<void>(), ""); // { dg-error "cannot call" } static_assert(is_c<void>(), ""); // { dg-error "" }
...@@ -46,6 +46,6 @@ struct X { ...@@ -46,6 +46,6 @@ struct X {
}; };
void test2() { void test2() {
g1<X, X>(); // { dg-error "cannot call" } g1<X, X>(); // { dg-error "" }
g2<X, X>(); // { dg-error "cannot call" } g2<X, X>(); // { dg-error "" }
} }
\ No newline at end of file
...@@ -20,7 +20,7 @@ template<typename T> ...@@ -20,7 +20,7 @@ template<typename T>
void f(T) {} void f(T) {}
int main() { int main() {
f(1); // { dg-error "cannot call" } f(1); // { dg-error "" }
} }
...@@ -28,5 +28,5 @@ struct Y {private: ~Y();}; ...@@ -28,5 +28,5 @@ struct Y {private: ~Y();};
int main() int main()
{ {
f<Y>(); // { dg-error "cannot call" } f<Y>(); // { dg-error "" }
} }
...@@ -9,5 +9,5 @@ struct S ...@@ -9,5 +9,5 @@ struct S
int main() int main()
{ {
foobar(S<double>{}, int{}); // { dg-error "cannot call" } foobar(S<double>{}, int{}); // { dg-error "" }
} }
...@@ -26,7 +26,7 @@ void driver_1() { ...@@ -26,7 +26,7 @@ void driver_1() {
struct S { } s; struct S { } s;
f4(s); f4(s);
f5(0); f5(0);
f5((void*)0); // { dg-error "cannot call" } f5((void*)0); // { dg-error "" }
test.f(s); test.f(s);
} }
...@@ -67,5 +67,5 @@ void print2(const T& x) { } ...@@ -67,5 +67,5 @@ void print2(const T& x) { }
void driver_3() void driver_3()
{ {
print2("hello"); // { dg-error "cannot call" } print2("hello"); // { dg-error "" }
} }
...@@ -9,7 +9,7 @@ template<C T> ...@@ -9,7 +9,7 @@ template<C T>
void fun(T s) { } void fun(T s) { }
int main(int, char **) { int main(int, char **) {
fun((int *)0); // { dg-error "cannot call function" } fun((int *)0); // { dg-error "" }
return 0; return 0;
} }
...@@ -37,11 +37,11 @@ void f7() { } ...@@ -37,11 +37,11 @@ void f7() { }
void driver() void driver()
{ {
f1<int, int>(); // { dg-error "cannot call function" } f1<int, int>(); // { dg-error "" }
f3<int, int>(); f3<int, int>();
f3<int, void>(); // { dg-error "cannot call function" } f3<int, void>(); // { dg-error "" }
f4<int, int>(); f4<int, int>();
f4<int, void>(); // { dg-error "cannot call function" } f4<int, void>(); // { dg-error "" }
f7<int>(); f7<int>();
f7<int, int>(); f7<int, int>();
} }
...@@ -18,7 +18,7 @@ template<typename T> requires Bad<T> void bad(T x) { } ...@@ -18,7 +18,7 @@ template<typename T> requires Bad<T> void bad(T x) { }
void driver_2() void driver_2()
{ {
bad(0); // { dg-error "cannot call" } bad(0); // { dg-error "" }
} }
// req6.C // req6.C
...@@ -41,8 +41,8 @@ void h2(T); ...@@ -41,8 +41,8 @@ void h2(T);
void driver_3() void driver_3()
{ {
h1(0); // { dg-error "cannot call" } h1(0); // { dg-error "" }
h2(0); // { dg-error "cannot call" } h2(0); // { dg-error "" }
} }
// req7.C // req7.C
......
...@@ -17,9 +17,9 @@ template <typename T> ...@@ -17,9 +17,9 @@ template <typename T>
requires C1<T> requires C1<T>
constexpr bool f1() { return true; } constexpr bool f1() { return true; }
static_assert(f1<char>()); // { dg-error "cannot call" } static_assert(f1<char>()); // { dg-error "" }
static_assert(f1<int>()); // { dg-error "cannot call" } static_assert(f1<int>()); // { dg-error "" }
static_assert(f1<double>()); // { dg-error "cannot call" } static_assert(f1<double>()); // { dg-error "" }
template <typename T> template <typename T>
......
...@@ -13,5 +13,5 @@ int main() ...@@ -13,5 +13,5 @@ int main()
{ {
// FIXME: This diagnostic is being emitted twice, when it should // FIXME: This diagnostic is being emitted twice, when it should
// be emitted just once. // 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 "" }
} }
...@@ -77,21 +77,21 @@ template<Union T> void f17() { } ...@@ -77,21 +77,21 @@ template<Union T> void f17() { }
template<Enum T> void f18() { } template<Enum T> void f18() { }
int main() { int main() {
f1<void>(); // { dg-error "cannot call" } f1<void>(); // { dg-error "" }
f2<void>(); // { dg-error "cannot call" } f2<void>(); // { dg-error "" }
f3<void>(); // { dg-error "cannot call" } f3<void>(); // { dg-error "" }
f4<void>(); // { dg-error "cannot call" } f4<void>(); // { dg-error "" }
f5<void>(); // { dg-error "cannot call" } f5<void>(); // { dg-error "" }
f6<void>(); // { dg-error "cannot call" } f6<void>(); // { dg-error "" }
f7<void>(); // { dg-error "cannot call" } f7<void>(); // { dg-error "" }
f8<void>(); // { dg-error "cannot call" } f8<void>(); // { dg-error "" }
f9<void>(); // { dg-error "cannot call" } f9<void>(); // { dg-error "" }
f10<void>(); // { dg-error "cannot call" } f10<void>(); // { dg-error "" }
f11<void>(); // { dg-error "cannot call" } f11<void>(); // { dg-error "" }
f12<void>(); // { dg-error "cannot call" } f12<void>(); // { dg-error "" }
f13<void>(); // { dg-error "cannot call" } f13<void>(); // { dg-error "" }
f14<void>(); // { dg-error "cannot call" } f14<void>(); // { dg-error "" }
f15<void>(); // { dg-error "cannot call" } f15<void>(); // { dg-error "" }
f16<void>(); // { dg-error "cannot call" } f16<void>(); // { dg-error "" }
f17<void>(); // { dg-error "cannot call" } f17<void>(); // { dg-error "" }
} }
...@@ -78,21 +78,21 @@ template<Enum T> void f18(); ...@@ -78,21 +78,21 @@ template<Enum T> void f18();
int main() { int main() {
f1<void>(); // { dg-error "cannot call" } f1<void>(); // { dg-error "" }
f2<void>(); // { dg-error "cannot call" } f2<void>(); // { dg-error "" }
f3<void>(); // { dg-error "cannot call" } f3<void>(); // { dg-error "" }
f4<void>(); // { dg-error "cannot call" } f4<void>(); // { dg-error "" }
f5<void>(); // { dg-error "cannot call" } f5<void>(); // { dg-error "" }
f6<void>(); // { dg-error "cannot call" } f6<void>(); // { dg-error "" }
f7<void>(); // { dg-error "cannot call" } f7<void>(); // { dg-error "" }
f8<void>(); // { dg-error "cannot call" } f8<void>(); // { dg-error "" }
f9<void>(); // { dg-error "cannot call" } f9<void>(); // { dg-error "" }
f10<void>(); // { dg-error "cannot call" } f10<void>(); // { dg-error "" }
f11<void>(); // { dg-error "cannot call" } f11<void>(); // { dg-error "" }
f12<void>(); // { dg-error "cannot call" } f12<void>(); // { dg-error "" }
f13<void>(); // { dg-error "cannot call" } f13<void>(); // { dg-error "" }
f14<void>(); // { dg-error "cannot call" } f14<void>(); // { dg-error "" }
f15<void>(); // { dg-error "cannot call" } f15<void>(); // { dg-error "" }
f16<void>(); // { dg-error "cannot call" } f16<void>(); // { dg-error "" }
f17<void>(); // { dg-error "cannot call" } f17<void>(); // { dg-error "" }
} }
...@@ -35,11 +35,11 @@ auto f15(auto x) -> SameAs<decltype(x)> { return 0; } // { dg-error "deduced ret ...@@ -35,11 +35,11 @@ auto f15(auto x) -> SameAs<decltype(x)> { return 0; } // { dg-error "deduced ret
void driver() void driver()
{ {
f1(0); f1(0);
f2(0); // { dg-error "cannot call" } f2(0); // { dg-error "" }
f3(0); f3(0);
f3('a'); // { dg-error "cannot call" } f3('a'); // { dg-error "" }
f4(0, 0); f4(0, 0);
f4(0, 'a'); // { dg-error "cannot call" } f4(0, 'a'); // { dg-error "" }
f15(0); f15(0);
f15('a'); // { dg-message "" } f15('a'); // { dg-message "" }
} }
......
...@@ -38,7 +38,7 @@ int fn2(T t) { return 0; } ...@@ -38,7 +38,7 @@ int fn2(T t) { return 0; }
void driver() void driver()
{ {
fn1(0); // OK fn1(0); // OK
fn2(0); // { dg-error "cannot call function" } fn2(0); // { dg-error "" }
} }
// Ordering // Ordering
...@@ -129,7 +129,7 @@ void caller_1(T x) ...@@ -129,7 +129,7 @@ void caller_1(T x)
{ {
f1(x); // Unchecked dependent arg. f1(x); // Unchecked dependent arg.
f1(empty{}); // Checked non-dependent arg, but OK f1(empty{}); // Checked non-dependent arg, but OK
f1(0); // { dg-error "cannot call function" } f1(0); // { dg-error "" }
} }
// fn3.c -- Ordering // fn3.c -- Ordering
...@@ -162,7 +162,7 @@ template<typename T> requires (Type<T>()) void ok(T) { } ...@@ -162,7 +162,7 @@ template<typename T> requires (Type<T>()) void ok(T) { }
template<typename T> requires (Class<T>()) void err(T) { } template<typename T> requires (Class<T>()) void err(T) { }
auto p1 = &ok<int>; auto p1 = &ok<int>;
auto p2 = &err<int>; // { dg-error "no matches" } auto p2 = &err<int>; // { dg-error "" }
void (*p3)(int) = &ok<int>; void (*p3)(int) = &ok<int>;
void (*p4)(int) = &err<int>; // { dg-error "no matches" } void (*p4)(int) = &err<int>; // { dg-error "no matches" }
void (*p5)(int) = &ok; void (*p5)(int) = &ok;
...@@ -183,7 +183,7 @@ struct S2 { ...@@ -183,7 +183,7 @@ struct S2 {
}; };
auto p7 = &S2::ok<int>; 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::*p9)(int) = &S2::ok<int>;
int (S2::*p10)(int) = &S2::err<int>; // { dg-error "no matches" } int (S2::*p10)(int) = &S2::err<int>; // { dg-error "no matches" }
int (S2::*p11)(int) = &S2::ok; int (S2::*p11)(int) = &S2::ok;
......
...@@ -38,7 +38,7 @@ int fn2(T t) { return 0; } ...@@ -38,7 +38,7 @@ int fn2(T t) { return 0; }
void driver() void driver()
{ {
fn1(0); // OK fn1(0); // OK
fn2(0); // { dg-error "cannot call function" } fn2(0); // { dg-error "" }
} }
// Ordering // Ordering
...@@ -129,7 +129,7 @@ void caller_1(T x) ...@@ -129,7 +129,7 @@ void caller_1(T x)
{ {
f1(x); // Unchecked dependent arg. f1(x); // Unchecked dependent arg.
f1(empty{}); // Checked non-dependent arg, but OK f1(empty{}); // Checked non-dependent arg, but OK
f1(0); // { dg-error "cannot call function" } f1(0); // { dg-error "" }
} }
// fn3.c -- Ordering // fn3.c -- Ordering
...@@ -162,7 +162,7 @@ template<typename T> requires Type<T> void ok(T) { } ...@@ -162,7 +162,7 @@ template<typename T> requires Type<T> void ok(T) { }
template<typename T> requires Class<T> void err(T) { } template<typename T> requires Class<T> void err(T) { }
auto p1 = &ok<int>; auto p1 = &ok<int>;
auto p2 = &err<int>; // { dg-error "no matches" } auto p2 = &err<int>; // { dg-error "" }
void (*p3)(int) = &ok<int>; void (*p3)(int) = &ok<int>;
void (*p4)(int) = &err<int>; // { dg-error "no matches" } void (*p4)(int) = &err<int>; // { dg-error "no matches" }
void (*p5)(int) = &ok; void (*p5)(int) = &ok;
...@@ -183,7 +183,7 @@ struct S2 { ...@@ -183,7 +183,7 @@ struct S2 {
}; };
auto p7 = &S2::ok<int>; 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::*p9)(int) = &S2::ok<int>;
int (S2::*p10)(int) = &S2::err<int>; // { dg-error "no matches" } int (S2::*p10)(int) = &S2::err<int>; // { dg-error "no matches" }
int (S2::*p11)(int) = &S2::ok; int (S2::*p11)(int) = &S2::ok;
......
...@@ -23,12 +23,12 @@ Pos{N} void fn(); ...@@ -23,12 +23,12 @@ Pos{N} void fn();
void driver() void driver()
{ {
f1(0); f1(0);
f2(0); // { dg-error "cannot call function" } f2(0); // { dg-error "" }
same<int, int>(); same<int, int>();
same<int, char>(); // { dg-error "cannot call function" } same<int, char>(); // { dg-error "" }
fn<0>(); // OK fn<0>(); // OK
fn<-1>(); // { dg-error "cannot call function" } fn<-1>(); // { dg-error "" }
fn<int>(); // { dg-error "no matching function" } fn<int>(); // { dg-error "no matching function" }
} }
...@@ -19,7 +19,7 @@ void decl1(T); ...@@ -19,7 +19,7 @@ void decl1(T);
void driver_1() void driver_1()
{ {
f1(0); // { dg-error "cannot call function" } f1(0); // { dg-error "" }
f1(empty{}); f1(empty{});
decl1(empty{}); // { dg-error "call of overload | ambiguous" } decl1(empty{}); // { dg-error "call of overload | ambiguous" }
......
...@@ -42,7 +42,7 @@ template<typename T> ...@@ -42,7 +42,7 @@ template<typename T>
void f3() { } void f3() { }
void driver2() { void driver2() {
f1<S1>(); // { dg-error "cannot call|is private" } f1<S1>(); // { dg-error "unsatisfied|is private" }
f2<S1>(); // { dg-error "cannot call|is private" } f2<S1>(); // { dg-error "unsatisfied|is private" }
f3<S1>(); // { dg-error "cannot call|is private" } f3<S1>(); // { dg-error "unsatisfied|is private" }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment