This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] [Annotalysis] Fix internal compiler errors in thread safety analysis.
- From: Delesley Hutchins <delesley at google dot com>
- To: gcc-patches at gcc dot gnu dot org, Diego Novillo <dnovillo at google dot com>, Ollie Wild <aaw at google dot com>
- Date: Tue, 13 Sep 2011 15:27:26 -0700
- Subject: [PATCH] [Annotalysis] Fix internal compiler errors in thread safety analysis.
This patch fixes two bugs which cause an internal compiler error in
annotalysis. The first change fixes a failure when a variable is
typecast from an unknown (forward-defined) type. The second change
fixes a case in which an assert was triggered, because subexpressions
were not canonicalized correctly.
Bootstrapped and passed gcc regression testsuite on
x86_64-unknown-linux-gnu. Tested on google core components.
Okay for google/gcc-4_6?
-DeLesley
gcc/Changelog.annotalysis:
2011-9-13 DeLesley Hutchins <delesley@google.com>
* gcc/cp/class.c (cp_get_virtual_function_decl) bugfix where
type is uknown
* gcc/tree-threadsafe-analyze.c (get_canonical_lock_expr)
don't remove & on recursive call
Index: gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-79.C
===================================================================
--- gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-79.C (revision 178784)
+++ gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-79.C (working copy)
@@ -75,3 +75,27 @@ void foo3()
(new FooDerived)->doSomething();
}
+class FooNodef;
+
+// test case for cast from undefined type
+void foo4(FooNodef *f) {
+ ((Foo*) f)->doSomething();
+}
+
+
+// Regression test for canonicalization of subexpressions that refer to
+// lockable objects.
+class LOCKABLE Base {
+public:
+ Mutex mu_;
+ virtual void baseMethod() SHARED_LOCKS_REQUIRED(mu_) = 0;
+};
+
+class Derived : public Base {
+public:
+ void foo() SHARED_LOCKS_REQUIRED(mu_);
+};
+
+void Derived::foo() {
+ baseMethod();
+}
Index: gcc/cp/class.c
===================================================================
--- gcc/cp/class.c (revision 178784)
+++ gcc/cp/class.c (working copy)
@@ -8384,9 +8384,15 @@ cp_get_virtual_function_decl (tree ref, tree known
{
HOST_WIDE_INT index = tree_low_cst (OBJ_TYPE_REF_TOKEN (ref), 1);
HOST_WIDE_INT i = 0;
- tree v = BINFO_VIRTUALS (TYPE_BINFO (known_type));
+ tree binfo = TYPE_BINFO(known_type);
+ tree v;
tree fndecl;
-
+
+ if (!binfo)
+ return NULL_TREE;
+
+ v = BINFO_VIRTUALS (TYPE_BINFO (known_type));
+
while (v && i != index)
{
i += (TARGET_VTABLE_USES_DESCRIPTORS
Index: gcc/tree-threadsafe-analyze.c
===================================================================
--- gcc/tree-threadsafe-analyze.c (revision 178784)
+++ gcc/tree-threadsafe-analyze.c (working copy)
@@ -884,10 +884,12 @@ get_canonical_lock_expr (tree lock, tree base_obj,
{
tree base = TREE_OPERAND (lock, 0);
tree canon_base;
- /* When the expr is a pointer to a lockable type (i.e. mu.Lock()
+ /* For expressions that denote locks,
+ When the expr is a pointer to a lockable type (i.e. mu.Lock()
or Lock(&mu) internally), we don't need the address-taken
operator (&). */
- if (lookup_attribute("lockable", TYPE_ATTRIBUTES (TREE_TYPE (base))))
+ if (!is_temp_expr &&
+ lookup_attribute("lockable", TYPE_ATTRIBUTES (TREE_TYPE (base))))
return get_canonical_lock_expr (base, base_obj,
false /* is_temp_expr */,
new_leftmost_base_var);
--
DeLesley Hutchins | Software Engineer | delesley@google.com | 505-206-0315