re PR c++/91606 (Optimization leads to invalid code)
2019-10-02 Richard Biener <rguenther@suse.de> PR c++/91606 * decl.c (build_ptrmemfunc_type): Mark pointer-to-member fat pointer structure members as DECL_NONADDRESSABLE_P. * g++.dg/torture/pr91606.C: New testcase. From-SVN: r276448
This commit is contained in:
parent
ba045eb229
commit
fc1a202ca6
@ -1,3 +1,9 @@
|
||||
2019-10-02 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR c++/91606
|
||||
* decl.c (build_ptrmemfunc_type): Mark pointer-to-member
|
||||
fat pointer structure members as DECL_NONADDRESSABLE_P.
|
||||
|
||||
2019-09-28 Marek Polacek <polacek@redhat.com>
|
||||
|
||||
PR c++/91889 - follow-up fix for DR 2352.
|
||||
|
@ -9665,10 +9665,12 @@ build_ptrmemfunc_type (tree type)
|
||||
TYPE_PTRMEMFUNC_FLAG (t) = 1;
|
||||
|
||||
field = build_decl (input_location, FIELD_DECL, pfn_identifier, type);
|
||||
DECL_NONADDRESSABLE_P (field) = 1;
|
||||
fields = field;
|
||||
|
||||
field = build_decl (input_location, FIELD_DECL, delta_identifier,
|
||||
delta_type_node);
|
||||
DECL_NONADDRESSABLE_P (field) = 1;
|
||||
DECL_CHAIN (field) = fields;
|
||||
fields = field;
|
||||
|
||||
|
@ -1,3 +1,8 @@
|
||||
2019-10-02 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR c++/91606
|
||||
* g++.dg/torture/pr91606.C: New testcase.
|
||||
|
||||
2019-10-02 Tobias Burnus <tobias@codesourcery.com>
|
||||
|
||||
* gfortran.dg/goacc/asyncwait-1.f95: Handle new error message.
|
||||
|
109
gcc/testsuite/g++.dg/torture/pr91606.C
Normal file
109
gcc/testsuite/g++.dg/torture/pr91606.C
Normal file
@ -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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user