This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] [Annotalysis] Add support for arrays in lock expressions


This patch adds support for array indexing (i.e. operator []) in lock
expressions.  The current version of gcc seems to emit these as
expressions involving pointer arithmetic, so we  update
get_canonical_lock_expr() to handle such expressions.

Bootstrapped and passed gcc regression testsuite on
x86_64-unknown-linux-gnu.  Okay for google/gcc-4_6?

 -DeLesley

Changelog.google-4_6:
2011-11-03  DeLesley Hutchins  <delesley@google.com>
   * tree-threadsafe-analyze.c (get_canonical_lock_expr):
     Add support for pointer arithmetic operations

testsuite/Changelog.google-4_6:
2011-11-02  DeLesley Hutchins <delesley@google.com>
   * g++.dg/thread-ann/thread_annot_lock-84.C:
    New regression test.

-- 
DeLesley Hutchins | Software Engineer | delesley@google.com | 505-206-0315
Index: testsuite/g++.dg/thread-ann/thread_annot_lock-84.C
===================================================================
--- testsuite/g++.dg/thread-ann/thread_annot_lock-84.C	(revision 0)
+++ testsuite/g++.dg/thread-ann/thread_annot_lock-84.C	(revision 0)
@@ -0,0 +1,29 @@
+// Test lock expressions involving array elements.  
+// { dg-do compile }
+// { dg-options "-Wthread-safety" }
+
+#include "thread_annot_common.h"
+
+struct Foo {
+  Mutex mu_;
+  int a GUARDED_BY(mu_);
+  
+  static void foo1(Foo* foos, int n);
+  static void foo2(Foo* foos, int n);
+};
+
+void Foo::foo1(Foo* foos, int n) {
+  for (int i = 0; i < n; ++i) {
+    foos[i].mu_.Lock();
+    foos[i].a = 0;
+    foos[i].mu_.Unlock();
+  }
+}
+
+void Foo::foo2(Foo* foos, int n) {
+  for (int i = 0; i < n-1; ++i) {
+    foos[i].mu_.Lock();
+    foos[i+1].a = 0;    // { dg-warning "Writing to variable" }
+    foos[i].mu_.Unlock();
+  }
+}
Index: tree-threadsafe-analyze.c
===================================================================
--- tree-threadsafe-analyze.c	(revision 180716)
+++ tree-threadsafe-analyze.c	(working copy)
@@ -79,6 +79,7 @@ along with GCC; see the file COPYING3.  
 #include "coretypes.h"
 #include "tm.h"
 #include "tree.h"
+#include "gimple.h"
 #include "c-family/c-common.h"
 #include "toplev.h"
 #include "input.h"
@@ -804,12 +805,27 @@ get_canonical_lock_expr (tree lock, tree
               && !gimple_nop_p (SSA_NAME_DEF_STMT (lock)))
             {
               gimple def_stmt = SSA_NAME_DEF_STMT (lock);
-              if (is_gimple_assign (def_stmt)
-                  && (get_gimple_rhs_class (gimple_assign_rhs_code (def_stmt))
-                      == GIMPLE_SINGLE_RHS))
-                return get_canonical_lock_expr (gimple_assign_rhs1 (def_stmt),
-                                                base_obj, is_temp_expr,
-                                                NULL_TREE);
+              if (is_gimple_assign (def_stmt))
+                {
+                  enum gimple_rhs_class gcls =
+                    get_gimple_rhs_class (gimple_assign_rhs_code (def_stmt));
+                  tree rhs = 0;
+
+                  if (gcls == GIMPLE_SINGLE_RHS)
+                    rhs = gimple_assign_rhs1 (def_stmt);
+                  else if (gcls == GIMPLE_UNARY_RHS)
+                    rhs = build1 (gimple_assign_rhs_code (def_stmt),
+                                  TREE_TYPE (gimple_assign_lhs (def_stmt)),
+                                  gimple_assign_rhs1 (def_stmt));
+                  else if (gcls == GIMPLE_BINARY_RHS)
+                    rhs = build2 (gimple_assign_rhs_code (def_stmt),
+                                  TREE_TYPE (gimple_assign_lhs (def_stmt)),
+                                  gimple_assign_rhs1 (def_stmt),
+                                  gimple_assign_rhs2 (def_stmt));
+                  if (rhs)
+                    return get_canonical_lock_expr (rhs, base_obj,
+                                                    is_temp_expr, NULL_TREE);
+                }
               else if (is_gimple_call (def_stmt))
                 {
                   tree fdecl = gimple_call_fndecl (def_stmt);
@@ -981,6 +997,24 @@ get_canonical_lock_expr (tree lock, tree
                            TREE_TYPE (TREE_TYPE (canon_base)), canon_base);
           break;
         }
+      case PLUS_EXPR:
+      case POINTER_PLUS_EXPR:
+      case MULT_EXPR:
+        {
+          tree left = TREE_OPERAND (lock, 0);
+          tree canon_left = get_canonical_lock_expr (left, base_obj,
+                                                     true /* is_temp_expr */,
+                                                     NULL_TREE);
+
+          tree right = TREE_OPERAND (lock, 1);
+          tree canon_right = get_canonical_lock_expr (right, base_obj,
+                                                      true /* is_temp_expr */,
+                                                      NULL_TREE);
+          if (left != canon_left || right != canon_right)
+            lock = build2 (TREE_CODE(lock), TREE_TYPE(lock),
+                           canon_left, canon_right);
+          break;
+        }
       default:
         break;
     }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]