|
1 | 1 | // RUN: %clang_cc1 -fsyntax-only -verify %s
|
2 | 2 | // RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
|
3 | 3 | // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
|
| 4 | +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 %s |
| 5 | +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s |
4 | 6 |
|
5 | 7 | // Tests that dependent expressions are always allowed, whereas non-dependent
|
6 | 8 | // are checked as usual.
|
@@ -32,7 +34,7 @@ T f1(T t1, U u1, int i1, T** tpp)
|
32 | 34 | i1 = t1[u1];
|
33 | 35 | i1 *= t1;
|
34 | 36 |
|
35 |
| - i1(u1, t1); // error |
| 37 | + i1(u1, t1); |
36 | 38 | u1(i1, t1);
|
37 | 39 |
|
38 | 40 | U u2 = (T)i1;
|
@@ -60,3 +62,99 @@ void f3() {
|
60 | 62 | f2<int*>(0);
|
61 | 63 | f2<int>(0); // expected-error {{no matching function for call to 'f2'}}
|
62 | 64 | }
|
| 65 | + |
| 66 | +#if __cplusplus >= 202002L |
| 67 | +namespace GH138657 { |
| 68 | +template <auto V> // #gh138657-template-head |
| 69 | +class meta {}; |
| 70 | +template<int N> |
| 71 | +class meta<N()> {}; // expected-error {{called object type 'int' is not a function or function point}} |
| 72 | + |
| 73 | +template<int N[1]> |
| 74 | +class meta<N()> {}; // expected-error {{called object type 'int *' is not a function or function point}} |
| 75 | + |
| 76 | +template<char* N> |
| 77 | +class meta<N()> {}; // expected-error {{called object type 'char *' is not a function or function point}} |
| 78 | + |
| 79 | +struct S {}; |
| 80 | +template<S> |
| 81 | +class meta<S()> {}; // expected-error {{template argument for non-type template parameter is treated as function type 'S ()'}} |
| 82 | + // expected-note@#gh138657-template-head {{template parameter is declared here}} |
| 83 | + |
| 84 | +} |
| 85 | + |
| 86 | +namespace GH115725 { |
| 87 | +template<auto ...> struct X {}; |
| 88 | +template<typename T, typename ...Ts> struct A { |
| 89 | + template<Ts ...Ns, T *...Ps> |
| 90 | + A(X<0(Ps)...>, Ts (*...qs)[Ns]); |
| 91 | + // expected-error@-1{{called object type 'int' is not a function or function pointer}} |
| 92 | + |
| 93 | +}; |
| 94 | +} |
| 95 | + |
| 96 | +namespace GH68852 { |
| 97 | +template <auto v> |
| 98 | +struct constexpr_value { |
| 99 | + template <class... Ts> |
| 100 | + constexpr constexpr_value<v(Ts::value...)> call(Ts...) { |
| 101 | + //expected-error@-1 {{called object type 'int' is not a function or function pointer}} |
| 102 | + return {}; |
| 103 | + } |
| 104 | +}; |
| 105 | + |
| 106 | +template <auto v> constexpr static inline auto c_ = constexpr_value<v>{}; |
| 107 | +// expected-note@-1 {{in instantiation of template}} |
| 108 | +auto k = c_<1>; // expected-note {{in instantiation of variable}} |
| 109 | + |
| 110 | +} |
| 111 | + |
| 112 | +#endif |
| 113 | +#if __cplusplus >= 201702L |
| 114 | + |
| 115 | +namespace GH138731 { |
| 116 | +template <class...> |
| 117 | +using void_t = void; |
| 118 | + |
| 119 | +template <class T> |
| 120 | +T&& declval(); |
| 121 | + |
| 122 | +struct S { |
| 123 | + S(); |
| 124 | + static int f(); |
| 125 | + static int var; |
| 126 | +}; |
| 127 | + |
| 128 | +namespace invoke_detail { |
| 129 | + |
| 130 | +template <typename F> |
| 131 | +struct traits { |
| 132 | + template <typename... A> |
| 133 | + using result = decltype(declval<F>()(declval<A>()...)); |
| 134 | +}; |
| 135 | + |
| 136 | +template <typename F, typename... A> |
| 137 | +using invoke_result_t = typename traits<F>::template result<A...>; |
| 138 | + |
| 139 | +template <typename Void, typename F, typename... A> |
| 140 | +inline constexpr bool is_invocable_v = false; |
| 141 | + |
| 142 | +template <typename F, typename... A> |
| 143 | +inline constexpr bool |
| 144 | + is_invocable_v<void_t<invoke_result_t<F, A...>>, F, A...> = true; |
| 145 | + |
| 146 | +} |
| 147 | + |
| 148 | +template <typename F, typename... A> |
| 149 | +inline constexpr bool is_invocable_v = |
| 150 | + invoke_detail::is_invocable_v<void, F, A...>; |
| 151 | + |
| 152 | +static_assert(!is_invocable_v<int>); |
| 153 | +static_assert(!is_invocable_v<int, int>); |
| 154 | +static_assert(!is_invocable_v<S>); |
| 155 | +static_assert(is_invocable_v<decltype(&S::f)>); |
| 156 | +static_assert(!is_invocable_v<decltype(&S::var)>); |
| 157 | + |
| 158 | +} |
| 159 | + |
| 160 | +#endif |
0 commit comments