summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2014-09-12 14:46:23 +0200
committerStephan Bergmann <sbergman@redhat.com>2014-09-12 14:46:54 +0200
commite333adb1ff0ffc36a78e50dc4061c1dfb0593d71 (patch)
tree0cec7f74b1032eff1c06b1417fcf97815054c247
parent86aed3ca6a35aa78f3ce2a587d151d39d21f880f (diff)
loplugin:salbool: exclude sal_Bool vars passed to non-const ref
Change-Id: I45b323b326cc56cfc48e0abaa52d51fd86adbf79
-rw-r--r--compilerplugins/clang/salbool.cxx47
1 files changed, 47 insertions, 0 deletions
diff --git a/compilerplugins/clang/salbool.cxx b/compilerplugins/clang/salbool.cxx
index 5eddba6b5379..6cca0faa3455 100644
--- a/compilerplugins/clang/salbool.cxx
+++ b/compilerplugins/clang/salbool.cxx
@@ -119,6 +119,8 @@ public:
bool VisitUnaryAddrOf(UnaryOperator const * op);
+ bool VisitCallExpr(CallExpr * expr);
+
bool VisitCStyleCastExpr(CStyleCastExpr * expr);
bool VisitCXXStaticCastExpr(CXXStaticCastExpr * expr);
@@ -210,6 +212,51 @@ bool SalBool::VisitUnaryAddrOf(UnaryOperator const * op) {
return true;
}
+bool SalBool::VisitCallExpr(CallExpr * expr) {
+ Decl const * d = expr->getCalleeDecl();
+ FunctionProtoType const * ft = nullptr;
+ if (d != nullptr) {
+ FunctionDecl const * fd = dyn_cast<FunctionDecl>(d);
+ if (fd != nullptr) {
+ PointerType const * pt = fd->getType()->getAs<PointerType>();
+ QualType t2(pt == nullptr ? fd->getType() : pt->getPointeeType());
+ ft = t2->getAs<FunctionProtoType>();
+ assert(
+ ft != nullptr || !compiler.getLangOpts().CPlusPlus
+ || (fd->getBuiltinID() != Builtin::NotBuiltin
+ && isa<FunctionNoProtoType>(t2)));
+ // __builtin_*s have no proto type?
+ } else {
+ VarDecl const * vd = dyn_cast<VarDecl>(d);
+ if (vd != nullptr) {
+ PointerType const * pt = vd->getType()->getAs<PointerType>();
+ ft = (pt == nullptr ? vd->getType() : pt->getPointeeType())
+ ->getAs<FunctionProtoType>();
+ }
+ }
+ }
+ if (ft != nullptr) {
+ for (unsigned i = 0; i != compat::getNumParams(*ft); ++i) {
+ QualType t(compat::getParamType(*ft, i));
+ if (t->isLValueReferenceType()) {
+ t = t.getNonReferenceType();
+ if (!t.isConstQualified() && isSalBool(t)
+ && i < expr->getNumArgs())
+ {
+ DeclRefExpr * ref = dyn_cast<DeclRefExpr>(expr->getArg(i));
+ if (ref != nullptr) {
+ VarDecl const * d = dyn_cast<VarDecl>(ref->getDecl());
+ if (d != nullptr) {
+ varDecls_.erase(d);
+ }
+ }
+ }
+ }
+ }
+ }
+ return true;
+}
+
bool SalBool::VisitCStyleCastExpr(CStyleCastExpr * expr) {
if (ignoreLocation(expr)) {
return true;