aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2016-10-04 17:14:18 -0400
committerJason Merrill <jason@gcc.gnu.org>2016-10-04 17:14:18 -0400
commit2db613e5d3a2698fcd32460ad23b0c1b8ae31c7a (patch)
tree1a5e32cc80f2acb985b965737519edc6c20b1820 /gcc
parent76b294d48d6c375b76f1695ea56c960d5473439b (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/cp/constexpr.c8
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-pmf1.C17
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();
+}