PR c++/77775 - misoptimization of PMF comparison
authorJason Merrill <jason@redhat.com>
Tue, 4 Oct 2016 21:14:18 +0000 (17:14 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 4 Oct 2016 21:14:18 +0000 (17:14 -0400)
* constexpr.c (cxx_eval_component_reference): Use name matching
for PMFs.

From-SVN: r240757

gcc/cp/ChangeLog
gcc/cp/constexpr.c
gcc/testsuite/g++.dg/cpp0x/constexpr-pmf1.C [new file with mode: 0644]

index 3fc378ae4637cf956b7a104d74e56385ab6403fb..b7a57e072da300a962933f75effed78ec8163c5a 100644 (file)
@@ -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.
index 2db13d2e1877a18535a2d838ed1a93624619b68a..4acbb2600b4b5c293ea11a71450cf291c6529668 100644 (file)
@@ -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 (file)
index 0000000..b6a7935
--- /dev/null
@@ -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();
+}