CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
241 lines
7.8 KiB
C++
241 lines
7.8 KiB
C++
// RUN: %clang_cc1 -verify -fsyntax-only %s -std=c++23
|
|
|
|
void func() { // expected-note {{'func' declared here}}
|
|
__builtin_invoke(); // expected-error {{too few arguments to function call, expected at least 1, have 0}}
|
|
}
|
|
|
|
void nfunc() noexcept {}
|
|
|
|
struct S {};
|
|
void argfunc(int, S) {} // expected-note {{'argfunc' declared here}}
|
|
|
|
struct Callable {
|
|
void operator()() {}
|
|
|
|
void func() {}
|
|
|
|
int var;
|
|
};
|
|
|
|
void* malloc(decltype(sizeof(int)));
|
|
|
|
template <class T>
|
|
struct pointer_wrapper {
|
|
T* v;
|
|
|
|
T& operator*() {
|
|
return *v;
|
|
}
|
|
};
|
|
|
|
namespace std {
|
|
template <class T>
|
|
class reference_wrapper {
|
|
T* ptr;
|
|
|
|
public:
|
|
constexpr reference_wrapper(T& ref) : ptr(&ref) {}
|
|
|
|
constexpr T& get() { return *ptr; }
|
|
};
|
|
|
|
template <class T>
|
|
constexpr reference_wrapper<T> ref(T& v) {
|
|
return reference_wrapper<T>(v);
|
|
}
|
|
} // namespace std
|
|
|
|
struct InvalidSpecialization1 {
|
|
void func() {}
|
|
|
|
int var;
|
|
};
|
|
|
|
template <>
|
|
class std::reference_wrapper<InvalidSpecialization1> {
|
|
public:
|
|
reference_wrapper(InvalidSpecialization1&) {}
|
|
};
|
|
|
|
struct InvalidSpecialization2 {
|
|
void func() {}
|
|
|
|
int var;
|
|
};
|
|
|
|
template <>
|
|
class std::reference_wrapper<InvalidSpecialization2> {
|
|
public:
|
|
reference_wrapper(InvalidSpecialization2&) {}
|
|
|
|
private:
|
|
InvalidSpecialization2& get(); // expected-note 2 {{declared private here}}
|
|
};
|
|
|
|
struct ExplicitObjectParam {
|
|
void func(this const ExplicitObjectParam& self) {}
|
|
};
|
|
|
|
struct Incomplete; // expected-note 2 {{forward declaration}}
|
|
struct Incomplete2;
|
|
|
|
void incomplete_by_val_test(Incomplete);
|
|
|
|
void incomplete_test(Incomplete& incomplete) {
|
|
__builtin_invoke((int (Incomplete2::*)){}, incomplete); // expected-error {{incomplete type 'Incomplete' used in type trait expression}} \
|
|
expected-error {{indirection requires pointer operand ('Incomplete' invalid)}}
|
|
__builtin_invoke(incomplete_test, incomplete);
|
|
__builtin_invoke(incomplete_by_val_test, incomplete); // expected-error {{argument type 'Incomplete' is incomplete}}
|
|
}
|
|
|
|
void call() {
|
|
__builtin_invoke(func);
|
|
__builtin_invoke(nfunc);
|
|
static_assert(!noexcept(__builtin_invoke(func)));
|
|
static_assert(noexcept(__builtin_invoke(nfunc)));
|
|
__builtin_invoke(func, 1); // expected-error {{too many arguments to function call, expected 0, have 1}}
|
|
__builtin_invoke(argfunc, 1); // expected-error {{too few arguments to function call, expected 2, have 1}}
|
|
__builtin_invoke(Callable{});
|
|
__builtin_invoke(malloc, 0);
|
|
__builtin_invoke(__builtin_malloc, 0); // expected-error {{builtin functions must be directly called}}
|
|
|
|
// Variadic function
|
|
void variadic_func(int, ...); // expected-note {{declared here}}
|
|
|
|
__builtin_invoke(variadic_func); // expected-error {{too few arguments to function call, expected at least 1, have 0}}
|
|
__builtin_invoke(variadic_func, 1);
|
|
__builtin_invoke(variadic_func, 1, 2, 3);
|
|
|
|
// static member function
|
|
struct StaticMember {
|
|
static void func(int);
|
|
};
|
|
|
|
__builtin_invoke(StaticMember::func, 1);
|
|
StaticMember sm;
|
|
__builtin_invoke(sm.func, 1);
|
|
|
|
// lambda
|
|
__builtin_invoke([] {});
|
|
__builtin_invoke([](int) {}, 1);
|
|
|
|
// Member function pointer
|
|
__builtin_invoke(&Callable::func); // expected-error {{too few arguments to function call, expected at least 2, have 1}}
|
|
__builtin_invoke(&Callable::func, 1); // expected-error {{indirection requires pointer operand ('int' invalid)}}
|
|
__builtin_invoke(&Callable::func, Callable{});
|
|
__builtin_invoke(&Callable::func, Callable{}, 1); // expected-error {{too many arguments to function call, expected 0, have 1}}
|
|
__builtin_invoke(&ExplicitObjectParam::func, ExplicitObjectParam{});
|
|
|
|
Callable c;
|
|
__builtin_invoke(&Callable::func, &c);
|
|
__builtin_invoke(&Callable::func, std::ref(c));
|
|
__builtin_invoke(&Callable::func, &c);
|
|
__builtin_invoke(&Callable::func, &c, 2); // expected-error {{too many arguments to function call, expected 0, have 1}}
|
|
__builtin_invoke(&Callable::func, pointer_wrapper<Callable>{&c});
|
|
__builtin_invoke(&Callable::func, pointer_wrapper<Callable>{&c}, 2); // expected-error {{too many arguments to function call, expected 0, have 1}}
|
|
|
|
InvalidSpecialization1 is1;
|
|
InvalidSpecialization2 is2;
|
|
__builtin_invoke(&InvalidSpecialization1::func, std::ref(is1)); // expected-error {{no member named 'get' in 'std::reference_wrapper<InvalidSpecialization1>'}}
|
|
__builtin_invoke(&InvalidSpecialization2::func, std::ref(is2)); // expected-error {{'get' is a private member of 'std::reference_wrapper<InvalidSpecialization2>'}}
|
|
|
|
// Member data pointer
|
|
__builtin_invoke(&Callable::var); // expected-error {{too few arguments to function call, expected at least 2, have 1}}
|
|
__builtin_invoke(&Callable::var, 1); // expected-error {{indirection requires pointer operand ('int' invalid)}}
|
|
(void)__builtin_invoke(&Callable::var, Callable{});
|
|
__builtin_invoke(&Callable::var, Callable{}, 1); // expected-error {{too many arguments to function call, expected 2, have 3}}
|
|
|
|
(void)__builtin_invoke(&Callable::var, &c);
|
|
(void)__builtin_invoke(&Callable::var, std::ref(c));
|
|
(void)__builtin_invoke(&Callable::var, &c);
|
|
__builtin_invoke(&Callable::var, &c, 2); // expected-error {{too many arguments to function call, expected 2, have 3}}
|
|
(void)__builtin_invoke(&Callable::var, pointer_wrapper<Callable>{&c});
|
|
__builtin_invoke(&Callable::var, pointer_wrapper<Callable>{&c}, 2); // expected-error {{too many arguments to function call, expected 2, have 3}}
|
|
|
|
__builtin_invoke(&InvalidSpecialization1::var, std::ref(is1)); // expected-error {{no member named 'get' in 'std::reference_wrapper<InvalidSpecialization1>'}}
|
|
(void)__builtin_invoke(&InvalidSpecialization2::var, std::ref(is2)); // expected-error {{'get' is a private member of 'std::reference_wrapper<InvalidSpecialization2>'}}
|
|
}
|
|
|
|
[[nodiscard]] int diagnose_discard();
|
|
int no_diagnose_discard();
|
|
|
|
namespace std {
|
|
template <class... Args>
|
|
auto invoke(Args&&... args) -> decltype(__builtin_invoke(args...));
|
|
} // namespace std
|
|
|
|
template <class... Args>
|
|
concept invocable = requires(Args... args) { __builtin_invoke(args...); };
|
|
|
|
static_assert(!invocable<std::reference_wrapper<InvalidSpecialization1>>);
|
|
static_assert(!invocable<std::reference_wrapper<InvalidSpecialization2>>);
|
|
|
|
void test3() {
|
|
__builtin_invoke(diagnose_discard); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
|
|
__builtin_invoke(no_diagnose_discard);
|
|
}
|
|
|
|
template <class T>
|
|
auto test(T v) {
|
|
return __builtin_invoke(v);
|
|
}
|
|
|
|
auto call2() {
|
|
test(call);
|
|
}
|
|
|
|
template <class ClassT, class FuncT>
|
|
void func(ClassT& c, FuncT&& func) {
|
|
__builtin_invoke(func, c, 1, 2, 3); // expected-error {{too many arguments to function call, expected 0, have 3}}
|
|
}
|
|
|
|
struct DependentTest {
|
|
void func(int, int, int);
|
|
void bad_func();
|
|
};
|
|
|
|
void call3() {
|
|
DependentTest d;
|
|
func(d, &DependentTest::func);
|
|
func(d, &DependentTest::bad_func); // expected-note {{requested here}}
|
|
}
|
|
|
|
constexpr int constexpr_func() {
|
|
return 42;
|
|
}
|
|
|
|
struct ConstexprTestStruct {
|
|
int i;
|
|
constexpr int func() {
|
|
return 55;
|
|
}
|
|
};
|
|
|
|
// Make sure that constant evaluation works
|
|
static_assert([]() {
|
|
|
|
ConstexprTestStruct s;
|
|
if (__builtin_invoke(&ConstexprTestStruct::func, s) != 55) // [func.requires]/p1.1
|
|
return false;
|
|
if (__builtin_invoke(&ConstexprTestStruct::func, std::ref(s)) != 55) // [func.requires]/p1.2
|
|
return false;
|
|
if (__builtin_invoke(&ConstexprTestStruct::func, &s) != 55) // [func.requires]/p1.3
|
|
return false;
|
|
|
|
s.i = 22;
|
|
if (__builtin_invoke(&ConstexprTestStruct::i, s) != 22) // [func.requires]/p1.4
|
|
return false;
|
|
if (__builtin_invoke(&ConstexprTestStruct::i, std::ref(s)) != 22) // [func.requires]/p1.5
|
|
return false;
|
|
if (__builtin_invoke(&ConstexprTestStruct::i, &s) != 22) // [func.requires]/p1.6
|
|
return false;
|
|
|
|
// [func.requires]/p1.7
|
|
if (__builtin_invoke(constexpr_func) != 42)
|
|
return false;
|
|
if (__builtin_invoke([] { return 34; }) != 34)
|
|
return false;
|
|
|
|
return true;
|
|
}());
|