diff options
author | Jason Merrill <jason@redhat.com> | 2016-10-04 17:14:18 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2016-10-04 17:14:18 -0400 |
commit | 2db613e5d3a2698fcd32460ad23b0c1b8ae31c7a (patch) | |
tree | 1a5e32cc80f2acb985b965737519edc6c20b1820 /gcc | |
parent | 76b294d48d6c375b76f1695ea56c960d5473439b (diff) | |
download | gcc-2db613e5d3a2698fcd32460ad23b0c1b8ae31c7a.zip gcc-2db613e5d3a2698fcd32460ad23b0c1b8ae31c7a.tar.gz gcc-2db613e5d3a2698fcd32460ad23b0c1b8ae31c7a.tar.bz2 |
PR c++/77775 - misoptimization of PMF comparison
* constexpr.c (cxx_eval_component_reference): Use name matching
for PMFs.
From-SVN: r240757
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/constexpr.c | 8 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/constexpr-pmf1.C | 17 |
3 files changed, 30 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 3fc378a..b7a57e0 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2016-09-30 Jason Merrill <jason@redhat.com> + + PR c++/77775 + * constexpr.c (cxx_eval_component_reference): Use name matching + for PMFs. + 2016-10-04 Jason Merrill <jason@redhat.com> Implement P0091R2, Template argument deduction for class templates. diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 2db13d2..4acbb26 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -2315,9 +2315,13 @@ cxx_eval_component_reference (const constexpr_ctx *ctx, tree t, } if (*non_constant_p) return t; + bool pmf = TYPE_PTRMEMFUNC_P (TREE_TYPE (whole)); FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (whole), i, field, value) { - if (field == part) + /* Use name match for PMF fields, as a variant will have a + different FIELD_DECL with a different type. */ + if (pmf ? DECL_NAME (field) == DECL_NAME (part) + : field == part) { if (value) return value; @@ -2342,6 +2346,8 @@ cxx_eval_component_reference (const constexpr_ctx *ctx, tree t, if (is_really_empty_class (TREE_TYPE (t))) return build_constructor (TREE_TYPE (t), NULL); + gcc_assert (DECL_CONTEXT (part) == TYPE_MAIN_VARIANT (TREE_TYPE (whole))); + if (CONSTRUCTOR_NO_IMPLICIT_ZERO (whole)) { /* 'whole' is part of the aggregate initializer we're currently diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-pmf1.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-pmf1.C new file mode 100644 index 0000000..b6a7935 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-pmf1.C @@ -0,0 +1,17 @@ +// PR c++/77775 +// { dg-options -fdump-tree-gimple } +// { dg-final { scan-tree-dump "== viewAdded" "gimple" { target c++11 } } } + +namespace Sublime { +struct View; +struct AreaIndex; +struct Area { + void qt_static_metacall(); + void viewAdded(AreaIndex *, View *); +}; +} +void Sublime::Area::qt_static_metacall() { + typedef void (Area::*_t)(AreaIndex *, View *); + if (*reinterpret_cast<_t *>(1) == _t(&Area::viewAdded)) + __builtin_abort(); +} |