This bug fixes a failure in annotalysis that is caused when gcc does
not return the correct static type for the callee of a virtual method.

Bootstrapped and passed GCC regression testsuite on x86_64-unknown-linux-gnu.

Okay for branches/annotalysis and google/main?

  -DeLesley


2011-06-30   DeLesley Hutchins  <deles...@google.com>
        * tree-threadsafe-analyze.c (handle_call_gs): Fixes case where
the virtual
        method callee has unknown type.


Index: gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-79.C
===================================================================
--- gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-79.C      (revision 0)
+++ gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-79.C      (revision 0)
@@ -0,0 +1,54 @@
+// Test virtual method calls in cases where the static type is unknown
+// This is a "good" test case that should not incur any thread safety warning.
+// { dg-do compile }
+// { dg-options "-Wthread-safety -O" }
+
+#include "thread_annot_common.h"
+
+class Foo {
+public:
+  Mutex m;
+
+  Foo();
+  virtual ~Foo();
+  virtual void doSomething() EXCLUSIVE_LOCKS_REQUIRED(m) = 0;
+};
+
+
+class FooDerived : public Foo {
+public:
+  FooDerived();
+  virtual ~FooDerived();
+  virtual void doSomething();
+};
+
+
+/**
+ * This is a test case for a bug wherein annotalysis would crash when
analyzing
+ * a virtual method call.
+ *
+ * The following three functions represent cases where gcc loses the static
+ * type of foo in the expression foo->doSomething() when it drops down to
+ * gimple.  Annotalysis should technically issue a thread-safe
warning in these
+ * cases, but because the type is missing, it should silently accept them
+ * instead.  See tree-threadsafe-analyze.c::handle_call_gs.
+ */
+
+// reinterpret_cast
+void foo1(void* ptr)
+{
+  reinterpret_cast<Foo*>(ptr)->doSomething();
+}
+
+// C-style cast
+void foo2(int* buf)
+{
+  ((Foo*) buf)->doSomething();
+}
+
+// new expression, with no local variable
+void foo3()
+{
+  (new FooDerived)->doSomething();
+}
+
Index: gcc/tree-threadsafe-analyze.c
===================================================================
--- gcc/tree-threadsafe-analyze.c       (revision 175385)
+++ gcc/tree-threadsafe-analyze.c       (working copy)
@@ -2446,7 +2446,18 @@
       if (TREE_CODE (callee) == OBJ_TYPE_REF)
         {
           tree objtype = TREE_TYPE (TREE_TYPE (OBJ_TYPE_REF_OBJECT (callee)));
-          fdecl = lang_hooks.get_virtual_function_decl (callee, objtype);
+          /* Check to make sure objtype is a valid type.
+           * OBJ_TYPE_REF_OBJECT does not always return the correct
static type of the callee.
+           * For example:  Given  foo(void* ptr) { ((Foo*)
ptr)->doSomething(); }
+           * objtype will be void, not Foo.  Whether or not this
happens depends on the details
+           * of how a particular call is lowered to GIMPLE, and there
is no easy fix that works
+           * in all cases.  For now, we simply rely on gcc's type
information; if that information
+           * is not accurate, then the analysis will be less precise.
+           */
+          if (TREE_CODE(objtype) == RECORD_TYPE)  /* if objtype is an
object type... */
+            {
+              fdecl = lang_hooks.get_virtual_function_decl (callee, objtype);
+            }
         }
     }

Reply via email to