implement the option2 of P2014R0 This implements the option2 of https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2014r0.pdf. This also fixes https://github.com/llvm/llvm-project/issues/56671. Although wg21 didn't get consensus for the direction of the problem, we're happy to have some implementation and user experience first. And from issue56671, the option2 should be the pursued one. Reviewed By: ychen Differential Revision: https://reviews.llvm.org/D133341
117 lines
3.2 KiB
C++
117 lines
3.2 KiB
C++
// Tests that we'll find aligned allocation funciton properly.
|
|
// RUN: %clang_cc1 %s -std=c++20 %s -fsyntax-only -verify -fcoro-aligned-allocation
|
|
|
|
#include "Inputs/std-coroutine.h"
|
|
|
|
namespace std {
|
|
typedef __SIZE_TYPE__ size_t;
|
|
enum class align_val_t : size_t {};
|
|
}
|
|
|
|
struct task {
|
|
struct promise_type {
|
|
auto initial_suspend() { return std::suspend_always{}; }
|
|
auto final_suspend() noexcept { return std::suspend_always{}; }
|
|
auto get_return_object() { return task{}; }
|
|
void unhandled_exception() {}
|
|
void return_value(int) {}
|
|
void *operator new(std::size_t); // expected-warning 1+{{under -fcoro-aligned-allocation, the non-aligned allocation function for the promise type 'f' has higher precedence than the global aligned allocation function}}
|
|
};
|
|
};
|
|
|
|
task f() {
|
|
co_return 43;
|
|
}
|
|
|
|
struct task2 {
|
|
struct promise_type {
|
|
auto initial_suspend() { return std::suspend_always{}; }
|
|
auto final_suspend() noexcept { return std::suspend_always{}; }
|
|
auto get_return_object() { return task2{}; }
|
|
void unhandled_exception() {}
|
|
void return_value(int) {}
|
|
void *operator new(std::size_t, std::align_val_t);
|
|
};
|
|
};
|
|
|
|
// no diagnostic expected
|
|
task2 f1() {
|
|
co_return 43;
|
|
}
|
|
|
|
struct task3 {
|
|
struct promise_type {
|
|
auto initial_suspend() { return std::suspend_always{}; }
|
|
auto final_suspend() noexcept { return std::suspend_always{}; }
|
|
auto get_return_object() { return task3{}; }
|
|
void unhandled_exception() {}
|
|
void return_value(int) {}
|
|
void *operator new(std::size_t, std::align_val_t) noexcept;
|
|
void *operator new(std::size_t) noexcept;
|
|
static auto get_return_object_on_allocation_failure() { return task3{}; }
|
|
};
|
|
};
|
|
|
|
// no diagnostic expected
|
|
task3 f2() {
|
|
co_return 43;
|
|
}
|
|
|
|
struct task4 {
|
|
struct promise_type {
|
|
auto initial_suspend() { return std::suspend_always{}; }
|
|
auto final_suspend() noexcept { return std::suspend_always{}; }
|
|
auto get_return_object() { return task4{}; }
|
|
void unhandled_exception() {}
|
|
void return_value(int) {}
|
|
void *operator new(std::size_t, std::align_val_t, int, double, int) noexcept;
|
|
};
|
|
};
|
|
|
|
// no diagnostic expected
|
|
task4 f3(int, double, int) {
|
|
co_return 43;
|
|
}
|
|
|
|
struct task5 {
|
|
struct promise_type {
|
|
auto initial_suspend() { return std::suspend_always{}; }
|
|
auto final_suspend() noexcept { return std::suspend_always{}; }
|
|
auto get_return_object() { return task5{}; }
|
|
void unhandled_exception() {}
|
|
void return_value(int) {}
|
|
};
|
|
};
|
|
|
|
// no diagnostic expected.
|
|
// The aligned allocation will be declared by the compiler.
|
|
task5 f4() {
|
|
co_return 43;
|
|
}
|
|
|
|
namespace std {
|
|
struct nothrow_t {};
|
|
constexpr nothrow_t nothrow = {};
|
|
}
|
|
|
|
struct task6 {
|
|
struct promise_type {
|
|
auto initial_suspend() { return std::suspend_always{}; }
|
|
auto final_suspend() noexcept { return std::suspend_always{}; }
|
|
auto get_return_object() { return task6{}; }
|
|
void unhandled_exception() {}
|
|
void return_value(int) {}
|
|
static task6 get_return_object_on_allocation_failure() { return task6{}; }
|
|
};
|
|
};
|
|
|
|
task6 f5() { // expected-error 1+{{unable to find '::operator new(size_t, align_val_t, nothrow_t)' for 'f5'}}
|
|
co_return 43;
|
|
}
|
|
|
|
void *operator new(std::size_t, std::align_val_t, std::nothrow_t) noexcept;
|
|
|
|
task6 f6() {
|
|
co_return 43;
|
|
}
|