diff options
author | Jordan Rose <jordan_rose@apple.com> | 2012-09-28 22:21:35 +0000 |
---|---|---|
committer | Jordan Rose <jordan_rose@apple.com> | 2012-09-28 22:21:35 +0000 |
commit | 7a2704800943fbb69207e125d28186278712af36 (patch) | |
tree | 0caa71289707359adc8219048e0e384ec227e9a2 /lib/Sema/AnalysisBasedWarnings.cpp | |
parent | 58b6bdcdeb683a3504f2248a409e1f4e85876cee (diff) |
-Warc-repeated-use-of-weak: check ivars and variables as well.
Like properties, loading from a weak ivar twice in the same function can
give you inconsistent results if the object is deallocated between the
two loads. It is safer to assign to a strong local variable and use that.
Second half of <rdar://problem/12280249>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@164855 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/AnalysisBasedWarnings.cpp')
-rw-r--r-- | lib/Sema/AnalysisBasedWarnings.cpp | 33 |
1 files changed, 28 insertions, 5 deletions
diff --git a/lib/Sema/AnalysisBasedWarnings.cpp b/lib/Sema/AnalysisBasedWarnings.cpp index 86e9dc2d64..bc25c0a554 100644 --- a/lib/Sema/AnalysisBasedWarnings.cpp +++ b/lib/Sema/AnalysisBasedWarnings.cpp @@ -957,19 +957,42 @@ static void diagnoseRepeatedUseOfWeak(Sema &S, const WeakObjectProfileTy &Key = I->second->first; const WeakUseVector &Uses = I->second->second; - // For complicated expressions like self.foo.bar, it's hard to keep track - // of whether 'self.foo' is the same between two cases. We can only be - // 100% sure of a repeated use if the "base" part of the key is a variable, - // rather than, say, another property. + // For complicated expressions like 'a.b.c' and 'x.b.c', WeakObjectProfileTy + // may not contain enough information to determine that these are different + // properties. We can only be 100% sure of a repeated use in certain cases, + // and we adjust the diagnostic kind accordingly so that the less certain + // case can be turned off if it is too noisy. unsigned DiagKind; if (Key.isExactProfile()) DiagKind = diag::warn_arc_repeated_use_of_weak; else DiagKind = diag::warn_arc_possible_repeated_use_of_weak; + // Classify the weak object being accessed for better warning text. + // This enum should stay in sync with the cases in + // warn_arc_repeated_use_of_weak and warn_arc_possible_repeated_use_of_weak. + enum { + Variable, + Property, + ImplicitProperty, + Ivar + } ObjectKind; + + const NamedDecl *D = Key.getProperty(); + if (isa<VarDecl>(D)) + ObjectKind = Variable; + else if (isa<ObjCPropertyDecl>(D)) + ObjectKind = Property; + else if (isa<ObjCMethodDecl>(D)) + ObjectKind = ImplicitProperty; + else if (isa<ObjCIvarDecl>(D)) + ObjectKind = Ivar; + else + llvm_unreachable("Unexpected weak object kind!"); + // Show the first time the object was read. S.Diag(FirstRead->getLocStart(), DiagKind) - << FunctionKind + << ObjectKind << D << FunctionKind << FirstRead->getSourceRange(); // Print all the other accesses as notes. |