From: DeLesley Hutchins Date: Wed, 6 Nov 2013 18:40:01 +0000 (+0000) Subject: Thread safety analysis: minor bugfix to smart pointer handling, and expanded X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9a2f84b2f03e79fb21f9db9e029045fba09dedef;p=clang Thread safety analysis: minor bugfix to smart pointer handling, and expanded test case. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@194157 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Analysis/ThreadSafety.cpp b/lib/Analysis/ThreadSafety.cpp index 607526db3e..df163aaf6d 100644 --- a/lib/Analysis/ThreadSafety.cpp +++ b/lib/Analysis/ThreadSafety.cpp @@ -2137,14 +2137,15 @@ void BuildLockset::VisitCallExpr(CallExpr *Exp) { case OO_Star: case OO_Arrow: { if (Analyzer->Handler.issueBetaWarnings()) { - const Expr *Target = OE->getArg(0); - checkPtAccess(Target, AK_Read); + const Expr *Obj = OE->getArg(0); + checkAccess(Obj, AK_Read); + checkPtAccess(Obj, AK_Read); } break; } default: { - const Expr *Source = OE->getArg(0); - checkAccess(Source, AK_Read); + const Expr *Obj = OE->getArg(0); + checkAccess(Obj, AK_Read); break; } } diff --git a/test/SemaCXX/warn-thread-safety-analysis.cpp b/test/SemaCXX/warn-thread-safety-analysis.cpp index 8ea411325f..fc99456fdf 100644 --- a/test/SemaCXX/warn-thread-safety-analysis.cpp +++ b/test/SemaCXX/warn-thread-safety-analysis.cpp @@ -4213,14 +4213,44 @@ class PtGuardedBySanityTest { class SmartPtr_PtGuardedBy_Test { + Mutex mu1; Mutex mu2; - SmartPtr sp PT_GUARDED_BY(mu2); - SmartPtr sq PT_GUARDED_BY(mu2); + SmartPtr sp GUARDED_BY(mu1) PT_GUARDED_BY(mu2); + SmartPtr sq GUARDED_BY(mu1) PT_GUARDED_BY(mu2); - void test() { - sp.get(); // OK -- no GUARDED_BY - *sp = 0; // expected-warning {{reading the value pointed to by 'sp' requires locking 'mu2'}} - sq->a = 0; // expected-warning {{reading the value pointed to by 'sq' requires locking 'mu2'}} + void test1() { + mu1.ReaderLock(); + mu2.Lock(); + + sp.get(); + if (*sp == 0) doSomething(); + *sp = 0; + sq->a = 0; + + mu2.Unlock(); + mu1.Unlock(); + } + + void test2() { + mu2.Lock(); + + sp.get(); // expected-warning {{reading variable 'sp' requires locking 'mu1'}} + if (*sp == 0) doSomething(); // expected-warning {{reading variable 'sp' requires locking 'mu1'}} + *sp = 0; // expected-warning {{reading variable 'sp' requires locking 'mu1'}} + sq->a = 0; // expected-warning {{reading variable 'sq' requires locking 'mu1'}} + + mu2.Unlock(); + } + + void test3() { + mu1.Lock(); + + sp.get(); + if (*sp == 0) doSomething(); // expected-warning {{reading the value pointed to by 'sp' requires locking 'mu2'}} + *sp = 0; // expected-warning {{reading the value pointed to by 'sp' requires locking 'mu2'}} + sq->a = 0; // expected-warning {{reading the value pointed to by 'sq' requires locking 'mu2'}} + + mu1.Unlock(); } };