From patchwork Thu Jun 30 17:01:58 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Delesley Hutchins X-Patchwork-Id: 102785 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 9314DB6F5A for ; Fri, 1 Jul 2011 03:02:34 +1000 (EST) Received: (qmail 18951 invoked by alias); 30 Jun 2011 17:02:27 -0000 Received: (qmail 18942 invoked by uid 22791); 30 Jun 2011 17:02:25 -0000 X-SWARE-Spam-Status: No, hits=0.6 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, SPF_HELO_PASS, TW_BJ, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from smtp-out.google.com (HELO smtp-out.google.com) (74.125.121.67) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 30 Jun 2011 17:02:05 +0000 Received: from hpaq7.eem.corp.google.com (hpaq7.eem.corp.google.com [172.25.149.7]) by smtp-out.google.com with ESMTP id p5UH20Ul015985 for ; Thu, 30 Jun 2011 10:02:04 -0700 Received: from gwb20 (gwb20.prod.google.com [10.200.2.20]) by hpaq7.eem.corp.google.com with ESMTP id p5UH0ECk014079 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for ; Thu, 30 Jun 2011 10:01:59 -0700 Received: by gwb20 with SMTP id 20so1019949gwb.3 for ; Thu, 30 Jun 2011 10:01:59 -0700 (PDT) MIME-Version: 1.0 Received: by 10.150.60.6 with SMTP id i6mr2098646yba.229.1309453318884; Thu, 30 Jun 2011 10:01:58 -0700 (PDT) Received: by 10.150.53.1 with HTTP; Thu, 30 Jun 2011 10:01:58 -0700 (PDT) Date: Thu, 30 Jun 2011 10:01:58 -0700 Message-ID: Subject: [PATCH] [Annotalysis] Fixes virtual method calls when type is unknown From: Delesley Hutchins To: gcc-patches@gcc.gnu.org, Diego Novillo , Le-Chun Wu X-System-Of-Record: true X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org 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 * tree-threadsafe-analyze.c (handle_call_gs): Fixes case where the virtual method callee has unknown type. + { + fdecl = lang_hooks.get_virtual_function_decl (callee, objtype); + } } } 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(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... */