aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2019-06-25 12:15:40 -0400
committerJason Merrill <jason@gcc.gnu.org>2019-06-25 12:15:40 -0400
commita4cc28287993320b4550a8a1d3842172d41b8d1c (patch)
tree5cab53c6ed870a1e647482ffeca76676911c19e1
parent27bb6f7c4775b6dc554811eec9597511e2d38973 (diff)
downloadgcc-a4cc28287993320b4550a8a1d3842172d41b8d1c.zip
gcc-a4cc28287993320b4550a8a1d3842172d41b8d1c.tar.gz
gcc-a4cc28287993320b4550a8a1d3842172d41b8d1c.tar.bz2
class.c (resolves_to_fixed_type_p): Check CLASSTYPE_FINAL.
* 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
-rw-r--r--gcc/cp/ChangeLog4
-rw-r--r--gcc/cp/class.c6
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/final1.C8
3 files changed, 16 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index a0f6166..dee69b8 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index e0df9ef..a679e65 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -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
index 0000000..43407f0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/final1.C
@@ -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; }