summaryrefslogtreecommitdiffstats
path: root/clang/lib/Analysis/ThreadSafety.cpp
diff options
context:
space:
mode:
authorDeLesley Hutchins <delesley@google.com>2014-08-14 19:17:06 +0000
committerDeLesley Hutchins <delesley@google.com>2014-08-14 19:17:06 +0000
commit4133b13bd228f04fb93071a6b176ad4c148388ec (patch)
treef8ddb56bcd4309fcd2b8332956fce0fe852efb37 /clang/lib/Analysis/ThreadSafety.cpp
parentb704534233564158bf78d4c4af22d8a5253af993 (diff)
downloadbcm5719-llvm-4133b13bd228f04fb93071a6b176ad4c148388ec.tar.gz
bcm5719-llvm-4133b13bd228f04fb93071a6b176ad4c148388ec.zip
Thread Safety Analysis: fix to improve handling of references to guarded
data members and range based for loops. llvm-svn: 215671
Diffstat (limited to 'clang/lib/Analysis/ThreadSafety.cpp')
-rw-r--r--clang/lib/Analysis/ThreadSafety.cpp54
1 files changed, 34 insertions, 20 deletions
diff --git a/clang/lib/Analysis/ThreadSafety.cpp b/clang/lib/Analysis/ThreadSafety.cpp
index 2108bbb3c54..c49e6e7049b 100644
--- a/clang/lib/Analysis/ThreadSafety.cpp
+++ b/clang/lib/Analysis/ThreadSafety.cpp
@@ -1215,7 +1215,7 @@ class BuildLockset : public StmtVisitor<BuildLockset> {
// helper functions
void warnIfMutexNotHeld(const NamedDecl *D, const Expr *Exp, AccessKind AK,
Expr *MutexExp, ProtectedOperationKind POK,
- StringRef DiagKind);
+ StringRef DiagKind, SourceLocation Loc);
void warnIfMutexHeld(const NamedDecl *D, const Expr *Exp, Expr *MutexExp,
StringRef DiagKind);
@@ -1247,7 +1247,7 @@ public:
void BuildLockset::warnIfMutexNotHeld(const NamedDecl *D, const Expr *Exp,
AccessKind AK, Expr *MutexExp,
ProtectedOperationKind POK,
- StringRef DiagKind) {
+ StringRef DiagKind, SourceLocation Loc) {
LockKind LK = getLockKindFromAccessKind(AK);
CapabilityExpr Cp = Analyzer->SxBuilder.translateAttrExpr(MutexExp, D, Exp);
@@ -1263,7 +1263,7 @@ void BuildLockset::warnIfMutexNotHeld(const NamedDecl *D, const Expr *Exp,
FactEntry *LDat = FSet.findLock(Analyzer->FactMan, !Cp);
if (LDat) {
Analyzer->Handler.handleFunExcludesLock(
- DiagKind, D->getNameAsString(), (!Cp).toString(), Exp->getExprLoc());
+ DiagKind, D->getNameAsString(), (!Cp).toString(), Loc);
return;
}
@@ -1276,7 +1276,7 @@ void BuildLockset::warnIfMutexNotHeld(const NamedDecl *D, const Expr *Exp,
LDat = FSet.findLock(Analyzer->FactMan, Cp);
if (!LDat) {
Analyzer->Handler.handleMutexNotHeld("", D, POK, Cp.toString(),
- LK_Shared, Exp->getExprLoc());
+ LK_Shared, Loc);
}
return;
}
@@ -1290,30 +1290,25 @@ void BuildLockset::warnIfMutexNotHeld(const NamedDecl *D, const Expr *Exp,
// Warn that there's no precise match.
std::string PartMatchStr = LDat->toString();
StringRef PartMatchName(PartMatchStr);
- Analyzer->Handler.handleMutexNotHeld(DiagKind, D, POK,
- Cp.toString(),
- LK, Exp->getExprLoc(),
- &PartMatchName);
+ Analyzer->Handler.handleMutexNotHeld(DiagKind, D, POK, Cp.toString(),
+ LK, Loc, &PartMatchName);
} else {
// Warn that there's no match at all.
- Analyzer->Handler.handleMutexNotHeld(DiagKind, D, POK,
- Cp.toString(),
- LK, Exp->getExprLoc());
+ Analyzer->Handler.handleMutexNotHeld(DiagKind, D, POK, Cp.toString(),
+ LK, Loc);
}
NoError = false;
}
// Make sure the mutex we found is the right kind.
if (NoError && LDat && !LDat->isAtLeast(LK)) {
- Analyzer->Handler.handleMutexNotHeld(DiagKind, D, POK,
- Cp.toString(),
- LK, Exp->getExprLoc());
+ Analyzer->Handler.handleMutexNotHeld(DiagKind, D, POK, Cp.toString(),
+ LK, Loc);
}
}
/// \brief Warn if the LSet contains the given lock.
void BuildLockset::warnIfMutexHeld(const NamedDecl *D, const Expr *Exp,
- Expr *MutexExp,
- StringRef DiagKind) {
+ Expr *MutexExp, StringRef DiagKind) {
CapabilityExpr Cp = Analyzer->SxBuilder.translateAttrExpr(MutexExp, D, Exp);
if (Cp.isInvalid()) {
warnInvalidLock(Analyzer->Handler, MutexExp, D, Exp, DiagKind);
@@ -1337,6 +1332,23 @@ void BuildLockset::warnIfMutexHeld(const NamedDecl *D, const Expr *Exp,
void BuildLockset::checkAccess(const Expr *Exp, AccessKind AK) {
Exp = Exp->IgnoreParenCasts();
+ SourceLocation Loc = Exp->getExprLoc();
+
+ if (Analyzer->Handler.issueBetaWarnings()) {
+ // Local variables of reference type cannot be re-assigned;
+ // map them to their initializer.
+ while (auto *DRE = dyn_cast<DeclRefExpr>(Exp)) {
+ auto *VD = dyn_cast<VarDecl>(DRE->getDecl()->getCanonicalDecl());
+ if (VD && VD->isLocalVarDecl() && VD->getType()->isReferenceType()) {
+ if (auto *E = VD->getInit()) {
+ Exp = E;
+ continue;
+ }
+ }
+ break;
+ }
+ }
+
if (const UnaryOperator *UO = dyn_cast<UnaryOperator>(Exp)) {
// For dereferences
if (UO->getOpcode() == clang::UO_Deref)
@@ -1362,14 +1374,15 @@ void BuildLockset::checkAccess(const Expr *Exp, AccessKind AK) {
if (D->hasAttr<GuardedVarAttr>() && FSet.isEmpty(Analyzer->FactMan)) {
Analyzer->Handler.handleNoMutexHeld("mutex", D, POK_VarAccess, AK,
- Exp->getExprLoc());
+ Loc);
}
for (const auto *I : D->specific_attrs<GuardedByAttr>())
warnIfMutexNotHeld(D, Exp, AK, I->getArg(), POK_VarAccess,
- ClassifyDiagnostic(I));
+ ClassifyDiagnostic(I), Loc);
}
+
/// \brief Checks pt_guarded_by and pt_guarded_var attributes.
void BuildLockset::checkPtAccess(const Expr *Exp, AccessKind AK) {
while (true) {
@@ -1400,7 +1413,7 @@ void BuildLockset::checkPtAccess(const Expr *Exp, AccessKind AK) {
for (auto const *I : D->specific_attrs<PtGuardedByAttr>())
warnIfMutexNotHeld(D, Exp, AK, I->getArg(), POK_VarDereference,
- ClassifyDiagnostic(I));
+ ClassifyDiagnostic(I), Exp->getExprLoc());
}
/// \brief Process a function call, method call, constructor call,
@@ -1480,7 +1493,8 @@ void BuildLockset::handleCall(Expr *Exp, const NamedDecl *D, VarDecl *VD) {
RequiresCapabilityAttr *A = cast<RequiresCapabilityAttr>(At);
for (auto *Arg : A->args())
warnIfMutexNotHeld(D, Exp, A->isShared() ? AK_Read : AK_Written, Arg,
- POK_FunctionCall, ClassifyDiagnostic(A));
+ POK_FunctionCall, ClassifyDiagnostic(A),
+ Exp->getExprLoc());
break;
}
OpenPOWER on IntegriCloud