From: Richard Biener Date: Wed, 2 Oct 2019 10:54:10 +0000 (+0000) Subject: re PR c++/91606 (Optimization leads to invalid code) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=fc1a202ca60def4894f2deeda8ae184527ee897e;p=gcc.git re PR c++/91606 (Optimization leads to invalid code) 2019-10-02 Richard Biener 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 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index a1e520a5137..bac74fef422 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2019-10-02 Richard Biener + + 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 PR c++/91889 - follow-up fix for DR 2352. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 67c4521e98c..c96294feb2e 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a5a1cf36df2..3fbed65d3c1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-10-02 Richard Biener + + PR c++/91606 + * g++.dg/torture/pr91606.C: New testcase. + 2019-10-02 Tobias Burnus * gfortran.dg/goacc/asyncwait-1.f95: Handle new error message. 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 +#include +#include + +template +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 +constexpr const T1* get_if(const variant* v) +{ + if (v->index != 0) + { + return nullptr; + } + return &v->f1; +} + +template +constexpr const T2* get_if(const variant* v) +{ + if (v->index != 1) + { + return nullptr; + } + return &v->f2; +} + +template +struct my_array +{ + constexpr const T* begin() const + { + return data; + } + + constexpr const T* end() const + { + return data + N; + } + + T data[N]; +}; + +template +constexpr auto get_array_of_variants(Ts ...ptrs) +{ + return std::array...>, sizeof...(Ts)>{ ptrs... }; +} + +template +constexpr auto get_member_functions(); + +template +constexpr int getFuncId(Member (Class::*memFuncPtr)) +{ + int idx = 0u; + for (auto &anyFunc : get_member_functions()) + { + if (auto *specificFunc = get_if(&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() +{ + return get_array_of_variants(&MyStruct::fun1, &MyStruct::fun2); +} + +int main() +{ + return getFuncId(&MyStruct::fun1); +}