Mercurial > hg > CbC > CbC_gcc
diff gcc/testsuite/g++.dg/torture/pr91606.C @ 145:1830386684a0
gcc-9.2.0
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 11:34:05 +0900 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gcc/testsuite/g++.dg/torture/pr91606.C Thu Feb 13 11:34:05 2020 +0900 @@ -0,0 +1,109 @@ +/* { dg-do run } */ +/* { dg-additional-options "-fstrict-aliasing" } */ + +#include <cstdlib> +#include <array> +#include <type_traits> + +template <typename T1, typename T2> +struct variant +{ + constexpr variant(T1 arg) + : f1(arg), + index(0) + {} + + constexpr variant(T2 arg) + : f2(arg), + index(1) + {} + + union + { + T1 f1; + T2 f2; + }; + std::size_t index = 0; +}; + +template <typename T1, typename T2> +constexpr const T1* get_if(const variant<T1, T2>* v) +{ + if (v->index != 0) + { + return nullptr; + } + return &v->f1; +} + +template <typename T2, typename T1> +constexpr const T2* get_if(const variant<T1, T2>* v) +{ + if (v->index != 1) + { + return nullptr; + } + return &v->f2; +} + +template <typename T, size_t N> +struct my_array +{ + constexpr const T* begin() const + { + return data; + } + + constexpr const T* end() const + { + return data + N; + } + + T data[N]; +}; + +template <typename ...Ts> +constexpr auto get_array_of_variants(Ts ...ptrs) +{ + return std::array<variant<std::decay_t<Ts>...>, sizeof...(Ts)>{ ptrs... }; +} + +template <typename T> +constexpr auto get_member_functions(); + +template <typename Member, typename Class> +constexpr int getFuncId(Member (Class::*memFuncPtr)) +{ + int idx = 0u; + for (auto &anyFunc : get_member_functions<Class>()) + { + if (auto *specificFunc = get_if<Member (Class::*)>(&anyFunc)) + { + if (*specificFunc == memFuncPtr) + { + return idx; + } + } + ++idx; + } + std::abort(); +} + +struct MyStruct +{ + void fun1(int /*a*/) {} + + int fun2(char /*b*/, short /*c*/, bool /*d*/) { return 0; } + +}; + +template <> +constexpr auto get_member_functions<MyStruct>() +{ + return get_array_of_variants(&MyStruct::fun1, &MyStruct::fun2); +} + +int main() +{ + return getFuncId(&MyStruct::fun1); +}