aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/g++.dg/torture/pr91606.C
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/testsuite/g++.dg/torture/pr91606.C')
-rw-r--r--gcc/testsuite/g++.dg/torture/pr91606.C109
1 files changed, 109 insertions, 0 deletions
diff --git a/gcc/testsuite/g++.dg/torture/pr91606.C b/gcc/testsuite/g++.dg/torture/pr91606.C
new file mode 100644
index 00000000000..37a05a5e3a5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr91606.C
@@ -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);
+}