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:
Richard Biener 2019-10-02 10:54:10 +00:00 committed by Richard Biener
parent ba045eb229
commit fc1a202ca6
4 changed files with 122 additions and 0 deletions

View File

@ -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.

View File

@ -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;

View File

@ -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.

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