class.c (resolves_to_fixed_type_p): Check CLASSTYPE_FINAL.
authorJason Merrill <jason@redhat.com>
Tue, 25 Jun 2019 16:15:40 +0000 (12:15 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 25 Jun 2019 16:15:40 +0000 (12:15 -0400)
* class.c (resolves_to_fixed_type_p): Check CLASSTYPE_FINAL.

If we have a pointer to final class, we know the dynamic type of the object
must be that class, because it can't have any derived classes.

From-SVN: r272656

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/testsuite/g++.dg/tree-ssa/final1.C [new file with mode: 0644]

index a0f61668559d9b042d761041fb9254060cc16ac7..dee69b87eba7556c9181c20da9e1a7a08b868024 100644 (file)
@@ -1,3 +1,7 @@
+2019-06-25  Jason Merrill  <jason@redhat.com>
+
+       * class.c (resolves_to_fixed_type_p): Check CLASSTYPE_FINAL.
+
 2019-06-25  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/90969
index e0df9ef2b20a436870dbe8d232d1a6f1608d68e1..a679e651bbe3a49f44d8625b45995cd6ba27ad80 100644 (file)
@@ -7477,10 +7477,12 @@ resolves_to_fixed_type_p (tree instance, int* nonnull)
     }
 
   fixed = fixed_type_or_null (instance, nonnull, &cdtorp);
-  if (fixed == NULL_TREE)
-    return 0;
   if (INDIRECT_TYPE_P (t))
     t = TREE_TYPE (t);
+  if (CLASS_TYPE_P (t) && CLASSTYPE_FINAL (t))
+    return 1;
+  if (fixed == NULL_TREE)
+    return 0;
   if (!same_type_ignoring_top_level_qualifiers_p (t, fixed))
     return 0;
   return cdtorp ? -1 : 1;
diff --git a/gcc/testsuite/g++.dg/tree-ssa/final1.C b/gcc/testsuite/g++.dg/tree-ssa/final1.C
new file mode 100644 (file)
index 0000000..43407f0
--- /dev/null
@@ -0,0 +1,8 @@
+// { dg-do compile { target c++11 } }
+// { dg-additional-options -fdump-tree-gimple }
+// { dg-final { scan-tree-dump-not "vptr" gimple } }
+
+struct A { int i; };
+struct B final: public virtual A { int j; };
+
+int f(B* b) { return b->i; }