summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorDeLesley Hutchins <delesley@google.com>2013-11-08 19:42:01 +0000
committerDeLesley Hutchins <delesley@google.com>2013-11-08 19:42:01 +0000
commite73d6b605c2476777b0d3899b9eb2e690d5e69de (patch)
tree31eb73a17f019350f3e98de2e01f0beaafa4055e /clang/lib
parent003c5e1db9e3c7a7d52da11dbd19c89add7ac6e7 (diff)
downloadbcm5719-llvm-e73d6b605c2476777b0d3899b9eb2e690d5e69de.tar.gz
bcm5719-llvm-e73d6b605c2476777b0d3899b9eb2e690d5e69de.zip
Thread-safety analysis: check guarded_by and pt_guarded_by on array access.
Currently supported only with -Wthread-safety-beta. llvm-svn: 194275
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Analysis/ThreadSafety.cpp33
1 files changed, 31 insertions, 2 deletions
diff --git a/clang/lib/Analysis/ThreadSafety.cpp b/clang/lib/Analysis/ThreadSafety.cpp
index df163aaf6d6..0a40b577cdc 100644
--- a/clang/lib/Analysis/ThreadSafety.cpp
+++ b/clang/lib/Analysis/ThreadSafety.cpp
@@ -1875,6 +1875,13 @@ void BuildLockset::checkAccess(const Expr *Exp, AccessKind AK) {
return;
}
+ if (const ArraySubscriptExpr *AE = dyn_cast<ArraySubscriptExpr>(Exp)) {
+ if (Analyzer->Handler.issueBetaWarnings()) {
+ checkPtAccess(AE->getLHS(), AK);
+ return;
+ }
+ }
+
if (const MemberExpr *ME = dyn_cast<MemberExpr>(Exp)) {
if (ME->isArrow())
checkPtAccess(ME->getBase(), AK);
@@ -1898,7 +1905,27 @@ void BuildLockset::checkAccess(const Expr *Exp, AccessKind AK) {
/// \brief Checks pt_guarded_by and pt_guarded_var attributes.
void BuildLockset::checkPtAccess(const Expr *Exp, AccessKind AK) {
- Exp = Exp->IgnoreParenCasts();
+ if (Analyzer->Handler.issueBetaWarnings()) {
+ while (true) {
+ if (const ParenExpr *PE = dyn_cast<ParenExpr>(Exp)) {
+ Exp = PE->getSubExpr();
+ continue;
+ }
+ if (const CastExpr *CE = dyn_cast<CastExpr>(Exp)) {
+ if (CE->getCastKind() == CK_ArrayToPointerDecay) {
+ // If it's an actual array, and not a pointer, then it's elements
+ // are protected by GUARDED_BY, not PT_GUARDED_BY;
+ checkAccess(CE->getSubExpr(), AK);
+ return;
+ }
+ Exp = CE->getSubExpr();
+ continue;
+ }
+ break;
+ }
+ }
+ else
+ Exp = Exp->IgnoreParenCasts();
const ValueDecl *D = getValueDecl(Exp);
if (!D || !D->hasAttrs())
@@ -2095,6 +2122,7 @@ void BuildLockset::VisitBinaryOperator(BinaryOperator *BO) {
checkAccess(BO->getLHS(), AK_Written);
}
+
/// Whenever we do an LValue to Rvalue cast, we are reading a variable and
/// need to ensure we hold any required mutexes.
/// FIXME: Deal with non-primitive types.
@@ -2135,7 +2163,8 @@ void BuildLockset::VisitCallExpr(CallExpr *Exp) {
break;
}
case OO_Star:
- case OO_Arrow: {
+ case OO_Arrow:
+ case OO_Subscript: {
if (Analyzer->Handler.issueBetaWarnings()) {
const Expr *Obj = OE->getArg(0);
checkAccess(Obj, AK_Read);
OpenPOWER on IntegriCloud