Files
TheRock/compiler/amd-llvm/clang/test/SemaCXX/builtin-invoke.cpp
T
derek.holloway 7502bf64a4
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
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

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;
}());