public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] [Annotalysis] Support trylock attributes on virtual methods.
@ 2011-11-08 18:26 Delesley Hutchins
  2011-11-09  3:08 ` Ollie Wild
  2011-11-10 17:28 ` Diego Novillo
  0 siblings, 2 replies; 5+ messages in thread
From: Delesley Hutchins @ 2011-11-08 18:26 UTC (permalink / raw)
  To: gcc-patches, Diego Novillo, Ollie Wild

[-- Attachment #1: Type: text/plain, Size: 613 bytes --]

This patch fixes a bug wherein the trylock attribute would not work if
it was attached to a virtual method.

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-08  DeLesley Hutchins  <delesley@google.com>
   * tree-threadsafe-analyze.c:
     factors out code to get function decl.

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

-- 
DeLesley Hutchins | Software Engineer | delesley@google.com | 505-206-0315

[-- Attachment #2: gcc-virtual-trylock.patch --]
[-- Type: text/x-patch, Size: 2941 bytes --]

Index: testsuite/g++.dg/thread-ann/thread_annot_lock-85.C
===================================================================
--- testsuite/g++.dg/thread-ann/thread_annot_lock-85.C	(revision 0)
+++ testsuite/g++.dg/thread-ann/thread_annot_lock-85.C	(revision 0)
@@ -0,0 +1,22 @@
+// Regression test, handle trylock on virtual method. 
+// { dg-do compile }
+// { dg-options "-Wthread-safety" }
+
+#include "thread_annot_common.h"
+
+class LOCKABLE Lock {
+ public:
+ virtual ~Lock() {}
+ virtual bool TryLock() EXCLUSIVE_TRYLOCK_FUNCTION(true) { return true; }
+ void Unlock() UNLOCK_FUNCTION() {}
+};
+
+
+void foo() {
+  Lock x;
+  Lock *p = &x;
+  if (p->TryLock()) {
+    p->Unlock();
+  }
+}
+
Index: tree-threadsafe-analyze.c
===================================================================
--- tree-threadsafe-analyze.c	(revision 180984)
+++ tree-threadsafe-analyze.c	(working copy)
@@ -2508,26 +2508,14 @@
   return;
 }
 
-/* The main routine that handles gimple call statements.  */
 
-static void
-handle_call_gs (gimple call, struct bb_threadsafe_info *current_bb_info)
-{
+/* Get the function declaration from a gimple call stmt.  This handles both
+   ordinary function calls and virtual methods. */
+static tree
+get_fdecl_from_gimple_stmt (gimple call) {
   tree fdecl = gimple_call_fndecl (call);
-  int num_args = gimple_call_num_args (call);
-  int arg_index = 0;
-  tree arg_type = NULL_TREE;
-  tree arg;
-  tree lhs;
-  location_t locus;
-
-  if (!gimple_has_location (call))
-    locus = input_location;
-  else
-    locus = gimple_location (call);
-
   /* If the callee fndecl is NULL, check if it is a virtual function,
-     and if so, try to get its decl through the reference object.  */
+       and if so, try to get its decl through the reference object.  */
   if (!fdecl)
     {
       tree callee = gimple_call_fn (call);
@@ -2546,7 +2534,28 @@
               fdecl = lang_hooks.get_virtual_function_decl (callee, objtype);                    
         }
     }
+  return fdecl;
+}
 
+
+/* The main routine that handles gimple call statements.  */
+
+static void
+handle_call_gs (gimple call, struct bb_threadsafe_info *current_bb_info)
+{
+  tree fdecl = get_fdecl_from_gimple_stmt (call);
+  int num_args = gimple_call_num_args (call);
+  int arg_index = 0;
+  tree arg_type = NULL_TREE;
+  tree arg;
+  tree lhs;
+  location_t locus;
+
+  if (!gimple_has_location (call))
+    locus = input_location;
+  else
+    locus = gimple_location (call);
+
   /* The callee fndecl could be NULL, e.g., when the function is passed in
      as an argument.  */
   if (fdecl)
@@ -2839,7 +2848,8 @@
         }
       else if (is_gimple_call (gs))
         {
-          tree fdecl = gimple_call_fndecl (gs);
+          tree fdecl = get_fdecl_from_gimple_stmt (gs);
+
           /* The function decl could be null in some cases, e.g.
              a function pointer passed in as a parameter.  */
           if (fdecl

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] [Annotalysis] Support trylock attributes on virtual methods.
  2011-11-08 18:26 [PATCH] [Annotalysis] Support trylock attributes on virtual methods Delesley Hutchins
@ 2011-11-09  3:08 ` Ollie Wild
  2011-11-10 17:28 ` Diego Novillo
  1 sibling, 0 replies; 5+ messages in thread
From: Ollie Wild @ 2011-11-09  3:08 UTC (permalink / raw)
  To: Delesley Hutchins, Diego Novillo; +Cc: gcc-patches

On Tue, Nov 8, 2011 at 12:11 PM, Delesley Hutchins <delesley@google.com> wrote:
> This patch fixes a bug wherein the trylock attribute would not work if
> it was attached to a virtual method.

Diego, can you please review this?

Thanks,
Ollie

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] [Annotalysis] Support trylock attributes on virtual methods.
  2011-11-08 18:26 [PATCH] [Annotalysis] Support trylock attributes on virtual methods Delesley Hutchins
  2011-11-09  3:08 ` Ollie Wild
@ 2011-11-10 17:28 ` Diego Novillo
  2011-11-10 22:55   ` Delesley Hutchins
  1 sibling, 1 reply; 5+ messages in thread
From: Diego Novillo @ 2011-11-10 17:28 UTC (permalink / raw)
  To: Delesley Hutchins; +Cc: gcc-patches, Ollie Wild

On 11-11-08 13:11 , Delesley Hutchins wrote:
> This patch fixes a bug wherein the trylock attribute would not work if
> it was attached to a virtual method.
>
> 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-08  DeLesley Hutchins<delesley@google.com>
>     * tree-threadsafe-analyze.c:
>       factors out code to get function decl.

Fix formatting.  Blank line after date.  Specify the name of the 
modified function in '()'.

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

Blank line after date.


> Index: testsuite/g++.dg/thread-ann/thread_annot_lock-85.C
> ===================================================================
> --- testsuite/g++.dg/thread-ann/thread_annot_lock-85.C	(revision 0)
> +++ testsuite/g++.dg/thread-ann/thread_annot_lock-85.C	(revision 0)
> @@ -0,0 +1,22 @@
> +// Regression test, handle trylock on virtual method.
> +// { dg-do compile }
> +// { dg-options "-Wthread-safety" }
> +
> +#include "thread_annot_common.h"
> +
> +class LOCKABLE Lock {
> + public:
> + virtual ~Lock() {}
> + virtual bool TryLock() EXCLUSIVE_TRYLOCK_FUNCTION(true) { return true; }
> + void Unlock() UNLOCK_FUNCTION() {}
> +};
> +
> +
> +void foo() {
> +  Lock x;
> +  Lock *p = &x;
> +  if (p->TryLock()) {
> +    p->Unlock();
> +  }
> +}
> +
> Index: tree-threadsafe-analyze.c
> ===================================================================
> --- tree-threadsafe-analyze.c	(revision 180984)
> +++ tree-threadsafe-analyze.c	(working copy)
> @@ -2508,26 +2508,14 @@
>    return;
>  }
>
> -/* The main routine that handles gimple call statements.  */
>
> -static void
> -handle_call_gs (gimple call, struct bb_threadsafe_info *current_bb_info)
> -{
> +/* Get the function declaration from a gimple call stmt.  This handles both
> +   ordinary function calls and virtual methods. */
> +static tree
> +get_fdecl_from_gimple_stmt (gimple call) {

Opening brace on line below.
Reference 'call' argument in capitals.

>    tree fdecl = gimple_call_fndecl (call);
> -  int num_args = gimple_call_num_args (call);
> -  int arg_index = 0;
> -  tree arg_type = NULL_TREE;
> -  tree arg;
> -  tree lhs;
> -  location_t locus;
> -
> -  if (!gimple_has_location (call))
> -    locus = input_location;
> -  else
> -    locus = gimple_location (call);
> -
>    /* If the callee fndecl is NULL, check if it is a virtual function,
> -     and if so, try to get its decl through the reference object.  */
> +       and if so, try to get its decl through the reference object.  */
>    if (!fdecl)
>      {
>        tree callee = gimple_call_fn (call);
> @@ -2546,7 +2534,28 @@
>                fdecl = lang_hooks.get_virtual_function_decl (callee, objtype);
>          }
>      }
> +  return fdecl;
> +}
>
> +
> +/* The main routine that handles gimple call statements.  */
> +
> +static void
> +handle_call_gs (gimple call, struct bb_threadsafe_info *current_bb_info)

Since you are modifying this code, could you add documentation for CALL 
and CURRENT_BB_INFO?

> +{
> +  tree fdecl = get_fdecl_from_gimple_stmt (call);
> +  int num_args = gimple_call_num_args (call);
> +  int arg_index = 0;
> +  tree arg_type = NULL_TREE;
> +  tree arg;
> +  tree lhs;
> +  location_t locus;
> +
> +  if (!gimple_has_location (call))
> +    locus = input_location;
> +  else
> +    locus = gimple_location (call);
> +
>    /* The callee fndecl could be NULL, e.g., when the function is passed in
>       as an argument.  */
>    if (fdecl)
> @@ -2839,7 +2848,8 @@
>          }
>        else if (is_gimple_call (gs))
>          {
> -          tree fdecl = gimple_call_fndecl (gs);
> +          tree fdecl = get_fdecl_from_gimple_stmt (gs);
> +

What about the other spots where we call gimple_call_fndecl, shouldn't 
we call get_fdecl_from_gimple_stmt instead?


Diego.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] [Annotalysis] Support trylock attributes on virtual methods.
  2011-11-10 17:28 ` Diego Novillo
@ 2011-11-10 22:55   ` Delesley Hutchins
  2011-11-10 23:24     ` Diego Novillo
  0 siblings, 1 reply; 5+ messages in thread
From: Delesley Hutchins @ 2011-11-10 22:55 UTC (permalink / raw)
  To: Diego Novillo; +Cc: gcc-patches, Ollie Wild

[-- Attachment #1: Type: text/plain, Size: 318 bytes --]

> What about the other spots where we call gimple_call_fndecl, shouldn't we
> call get_fdecl_from_gimple_stmt instead?

Good point.  I've gone through and updated the necessary spots.

New patch with all fixes is attached.

  -DeLesley



-- 
DeLesley Hutchins | Software Engineer | delesley@google.com | 505-206-0315

[-- Attachment #2: gcc-virtual-trylock2.patch --]
[-- Type: text/x-patch, Size: 6154 bytes --]

Index: testsuite/g++.dg/thread-ann/thread_annot_lock-85.C
===================================================================
--- testsuite/g++.dg/thread-ann/thread_annot_lock-85.C	(revision 0)
+++ testsuite/g++.dg/thread-ann/thread_annot_lock-85.C	(revision 0)
@@ -0,0 +1,22 @@
+// Regression test, handle trylock on virtual method. 
+// { dg-do compile }
+// { dg-options "-Wthread-safety" }
+
+#include "thread_annot_common.h"
+
+class LOCKABLE Lock {
+ public:
+ virtual ~Lock() {}
+ virtual bool TryLock() EXCLUSIVE_TRYLOCK_FUNCTION(true) { return true; }
+ void Unlock() UNLOCK_FUNCTION() {}
+};
+
+
+void foo() {
+  Lock x;
+  Lock *p = &x;
+  if (p->TryLock()) {
+    p->Unlock();
+  }
+}
+
Index: tree-threadsafe-analyze.c
===================================================================
--- tree-threadsafe-analyze.c	(revision 181268)
+++ tree-threadsafe-analyze.c	(working copy)
@@ -564,6 +564,38 @@
     return false;
 }
 
+
+/* Get the function declaration from a gimple call stmt (CALL).  This handles
+   both ordinary function calls and virtual methods. */
+
+static tree
+get_fdecl_from_gimple_stmt (gimple call)
+{
+  tree fdecl = gimple_call_fndecl (call);
+  /* If the callee fndecl is NULL, check if it is a virtual function,
+       and if so, try to get its decl through the reference object.  */
+  if (!fdecl)
+    {
+      tree callee = gimple_call_fn (call);
+      if (TREE_CODE (callee) == OBJ_TYPE_REF)
+        {
+          tree objtype = TREE_TYPE (TREE_TYPE (OBJ_TYPE_REF_OBJECT (callee)));
+          /* 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)
+              fdecl = lang_hooks.get_virtual_function_decl (callee, objtype);
+        }
+    }
+  return fdecl;
+}
+
+
 /* Given a CALL gimple statment, check if its function decl is annotated
    with "lock_returned" attribute. If so, return the lock specified in
    the attribute. Otherise, return NULL_TREE.  */
@@ -571,7 +603,7 @@
 static tree
 get_lock_returned_by_call (gimple call)
 {
-  tree fdecl = gimple_call_fndecl (call);
+  tree fdecl = get_fdecl_from_gimple_stmt (call);
   tree attr = (fdecl
                ? lookup_attribute ("lock_returned", DECL_ATTRIBUTES (fdecl))
                : NULL_TREE);
@@ -828,7 +860,7 @@
                 }
               else if (is_gimple_call (def_stmt))
                 {
-                  tree fdecl = gimple_call_fndecl (def_stmt);
+                  tree fdecl = get_fdecl_from_gimple_stmt (def_stmt);
                   tree real_lock = get_lock_returned_by_call (def_stmt);
                   if (real_lock)
                     {
@@ -1661,6 +1693,7 @@
   gcc_unreachable ();
 }
 
+
 /* A helper function that adds the LOCKABLE, acquired by CALL, to the
    corresponding lock sets (LIVE_EXCL_LOCKS or LIVE_SHARED_LOCKS) depending
    on the boolean parameter IS_EXCLUSIVE_LOCK. If the CALL is a trylock call,
@@ -1967,7 +2000,6 @@
         }
       else if (TREE_CODE (get_leftmost_base_var (arg)) == PARM_DECL)
         {
-          tree fdecl = gimple_call_fndecl (call);
           tree new_base = get_actual_argument_from_parameter (
               call, fdecl, get_leftmost_base_var (arg));
           lockable = get_canonical_lock_expr (arg, NULL_TREE, false, new_base);
@@ -2542,12 +2574,17 @@
   return;
 }
 
-/* The main routine that handles gimple call statements.  */
 
+/* The main routine that handles gimple call statements.  This will update
+   the set of held locks.
+   CALL            -- the gimple call statement.
+   CURRENT_BB_INFO -- a pointer to the lockset structures for the current
+                      basic block.
+*/
 static void
 handle_call_gs (gimple call, struct bb_threadsafe_info *current_bb_info)
 {
-  tree fdecl = gimple_call_fndecl (call);
+  tree fdecl = get_fdecl_from_gimple_stmt (call);
   int num_args = gimple_call_num_args (call);
   int arg_index = 0;
   tree arg_type = NULL_TREE;
@@ -2560,27 +2597,6 @@
   else
     locus = gimple_location (call);
 
-  /* If the callee fndecl is NULL, check if it is a virtual function,
-     and if so, try to get its decl through the reference object.  */
-  if (!fdecl)
-    {
-      tree callee = gimple_call_fn (call);
-      if (TREE_CODE (callee) == OBJ_TYPE_REF)
-        {
-          tree objtype = TREE_TYPE (TREE_TYPE (OBJ_TYPE_REF_OBJECT (callee)));
-          /* 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)
-              fdecl = lang_hooks.get_virtual_function_decl (callee, objtype);                    
-        }
-    }
-
   /* The callee fndecl could be NULL, e.g., when the function is passed in
      as an argument.  */
   if (fdecl)
@@ -2873,7 +2889,8 @@
         }
       else if (is_gimple_call (gs))
         {
-          tree fdecl = gimple_call_fndecl (gs);
+          tree fdecl = get_fdecl_from_gimple_stmt (gs);
+
           /* The function decl could be null in some cases, e.g.
              a function pointer passed in as a parameter.  */
           if (fdecl

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] [Annotalysis] Support trylock attributes on virtual methods.
  2011-11-10 22:55   ` Delesley Hutchins
@ 2011-11-10 23:24     ` Diego Novillo
  0 siblings, 0 replies; 5+ messages in thread
From: Diego Novillo @ 2011-11-10 23:24 UTC (permalink / raw)
  To: Delesley Hutchins; +Cc: gcc-patches, Ollie Wild

On 11-11-10 17:23 , Delesley Hutchins wrote:

> +    {
> +      tree callee = gimple_call_fn (call);
> +      if (TREE_CODE (callee) == OBJ_TYPE_REF)
> +        {
> +          tree objtype = TREE_TYPE (TREE_TYPE (OBJ_TYPE_REF_OBJECT (callee)));
> +          /* 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.

Re-format for 80 cols.

OK with that change.


Diego.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2011-11-10 22:32 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-11-08 18:26 [PATCH] [Annotalysis] Support trylock attributes on virtual methods Delesley Hutchins
2011-11-09  3:08 ` Ollie Wild
2011-11-10 17:28 ` Diego Novillo
2011-11-10 22:55   ` Delesley Hutchins
2011-11-10 23:24     ` Diego Novillo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).