[Bug optimization/14511] [tree-ssa] "pure virtual method called" error when calling a method on a static_casted object
dnovillo at redhat dot com
gcc-bugzilla@gcc.gnu.org
Wed Mar 17 19:28:00 GMT 2004
------- Additional Comments From dnovillo at redhat dot com 2004-03-17 19:28 -------
Subject: Re: [tree-ssa] "pure virtual method
called" error when calling a method on a static_casted object
On Wed, 2004-03-10 at 14:01, pinskia at gcc dot gnu dot org wrote:
> ------- Additional Comments From pinskia at gcc dot gnu dot org 2004-03-10 19:01 -------
> The issue I think is that the structs are not marked as they can alias each other.
>
Indeed. The problem occurs when we replace the RHS of (3) with
&_ZTV4IFoo<D1485>[2]
1. this<D1553>_6->_vptr.IFoo<D1483> = &_ZTV4IFoo<D1485>[2];
2. this<D1550>_4->_vptr.IFoo<D1511> = &_ZTV3Bar<D1512>[2];
3. T.3<D1532>_10 = this<D1553>_6->_vptr.IFoo<D1483>;
4. T.4<D1533>_11 = *T.3<D1532>_10;
5. # VUSE <_ZTV4IFoo_1>;
6. # VUSE <_ZTV3Bar_2>;
7. T.4_11 (this<D1553>_6);
The alias pass was not computing type aliases properly for this<D1553>
and this<D1550> for two reasons:
* Variables _ZTV4IFoo<D1485> and _ZTV3Bar<D1512 are read-only, so
they were being ignored. However, ignoring them meant that the
alias sets for this<D1553> and this<D1550> were not being
populated, therefore the two memory tags were not found to
conflict, allowing DOM to propagate (1) into (3).
* The sub-type checking in may_alias_p was not computing the right
pointer-to type for ARRAY_TYPEs.
Bootstrapped and tested on x86, x86-64 and ia64.
Diego.
* tree-ssa-alias.c (compute_flow_insensitive_aliasing): Do not
ignore read-only variables.
(may_alias_p): Fix pointer-to-var calculation when 'var' is an
array.
testsuite/ChangeLog.tree-ssa:
* g++.dg/tree-ssa/20040317-1.C: New test.
Index: tree-ssa-alias.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-alias.c,v
retrieving revision 1.1.2.12
diff -d -c -p -d -u -p -r1.1.2.12 tree-ssa-alias.c
--- tree-ssa-alias.c 16 Mar 2004 22:31:55 -0000 1.1.2.12
+++ tree-ssa-alias.c 17 Mar 2004 19:17:31 -0000
@@ -797,10 +797,6 @@ compute_flow_insensitive_aliasing (struc
if (!tag_stored_p && !var_stored_p)
continue;
- /* Skip memory tags which are written if the variable is readonly. */
- if (tag_stored_p && TREE_READONLY (var))
- continue;
-
if (may_alias_p (p_map->var, p_map->set, var, v_map->set))
{
size_t num_tag_refs = ai->num_references[tag_ann->uid];
@@ -1337,7 +1333,12 @@ may_alias_p (tree ptr, HOST_WIDE_INT mem
if (AGGREGATE_TYPE_P (TREE_TYPE (mem))
|| AGGREGATE_TYPE_P (TREE_TYPE (var)))
{
- tree ptr_to_var = TYPE_POINTER_TO (TREE_TYPE (var));
+ tree ptr_to_var;
+
+ if (TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE)
+ ptr_to_var = TYPE_POINTER_TO (TREE_TYPE (TREE_TYPE (var)));
+ else
+ ptr_to_var = TYPE_POINTER_TO (TREE_TYPE (var));
/* If no pointer-to VAR exists, then MEM can't alias VAR. */
if (ptr_to_var == NULL_TREE)
Index: testsuite/g++.dg/tree-ssa/20040317-1.C
===================================================================
RCS file: testsuite/g++.dg/tree-ssa/20040317-1.C
diff -N testsuite/g++.dg/tree-ssa/20040317-1.C
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ testsuite/g++.dg/tree-ssa/20040317-1.C 17 Mar 2004 19:17:31 -0000
@@ -0,0 +1,38 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+/* Test provided by Brian Ryner in PR 14511. The alias analyzer was
+ not handling structures containing arrays properly. In this case,
+ the static cast was introducing two assignments of the form
+
+ this_6->_vptr.IFoo = &_ZTV4IFoo[2];
+ this_4->_vptr.IFoo = &_ZTV3Bar[2];
+
+ which were not considered to alias each other because the alias
+ analyzer was not computing a proper pointer to array elements.
+ Another related bug was the type based alias analyzer not computing
+ alias relations to _ZTV4IFoo and _ZTV3Bar. Since those variables
+ are read-only, it was disregarding alias information for them.
+ So, the memory tags for the two 'this' variables were not being
+ marked as aliased with these variables. Resulting in the two
+ assignments not aliasing each other.
+
+ This was causing the optimizers to generate a call to the virtual
+ method Foo() instead of the overloaded version. */
+
+struct IFoo
+{
+ virtual void Foo() = 0;
+};
+
+struct Bar : IFoo
+{
+ void Foo() { }
+};
+
+int main(int argc, char **argv)
+{
+ Bar* b = new Bar();
+ static_cast<IFoo*>(b)->Foo();
+ return 0;
+}
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14511
More information about the Gcc-bugs
mailing list