buildMutexID(CE->getSubExpr(), CallCtx);
} else if (ParenExpr *PE = dyn_cast<ParenExpr>(Exp)) {
buildMutexID(PE->getSubExpr(), CallCtx);
+ } else if (ExprWithCleanups *EWC = dyn_cast<ExprWithCleanups>(Exp)) {
+ buildMutexID(EWC->getSubExpr(), CallCtx);
} else if (isa<CharacterLiteral>(Exp) ||
- isa<CXXNullPtrLiteralExpr>(Exp) ||
- isa<GNUNullExpr>(Exp) ||
- isa<CXXBoolLiteralExpr>(Exp) ||
- isa<FloatingLiteral>(Exp) ||
- isa<ImaginaryLiteral>(Exp) ||
- isa<IntegerLiteral>(Exp) ||
- isa<StringLiteral>(Exp) ||
- isa<ObjCStringLiteral>(Exp)) {
+ isa<CXXNullPtrLiteralExpr>(Exp) ||
+ isa<GNUNullExpr>(Exp) ||
+ isa<CXXBoolLiteralExpr>(Exp) ||
+ isa<FloatingLiteral>(Exp) ||
+ isa<ImaginaryLiteral>(Exp) ||
+ isa<IntegerLiteral>(Exp) ||
+ isa<StringLiteral>(Exp) ||
+ isa<ObjCStringLiteral>(Exp)) {
return; // FIXME: Ignore literals for now
} else {
// Ignore. FIXME: mark as invalid expression?
Decl *D = *I;
if (VarDecl *VD = dyn_cast_or_null<VarDecl>(D)) {
Expr *E = VD->getInit();
+ // handle constructors that involve temporaries
+ if (ExprWithCleanups *EWC = dyn_cast_or_null<ExprWithCleanups>(E))
+ E = EWC->getSubExpr();
+
if (CXXConstructExpr *CE = dyn_cast_or_null<CXXConstructExpr>(E)) {
NamedDecl *CtorD = dyn_cast_or_null<NamedDecl>(CE->getConstructor());
if (!CtorD || !CtorD->hasAttrs())
void Release() UNLOCK_FUNCTION();
};
+
+template<class T>
+class SmartPtr {
+public:
+ SmartPtr(T* p) : ptr_(p) { }
+ SmartPtr(const SmartPtr<T>& p) : ptr_(p.ptr_) { }
+ ~SmartPtr();
+
+ T* get() const { return ptr_; }
+ T* operator->() const { return ptr_; }
+ T& operator*() const { return ptr_; }
+
+private:
+ T* ptr_;
+};
+
+
Mutex sls_mu;
Mutex sls_mu2 __attribute__((acquired_after(sls_mu)));
} // end namespace FoolishScopedLockableBug
+
+namespace TemporaryCleanupExpr {
+
+class Foo {
+ int a GUARDED_BY(getMutexPtr().get());
+
+ SmartPtr<Mutex> getMutexPtr();
+
+ void test();
+};
+
+
+void Foo::test() {
+ {
+ ReaderMutexLock lock(getMutexPtr().get());
+ int b = a;
+ } // FIXME: handle smart pointers better.
+ int b = a; // expected-warning {{reading variable 'a' requires locking 'get'}}
+}
+
+} // end namespace TemporaryCleanupExpr
+
+