in src/checks/level1/returning-data-from-temporary.cpp [74:137]
void ReturningDataFromTemporary::handleMemberCall(CXXMemberCallExpr *memberCall, bool onlyTemporaries)
{
if (!memberCall) {
return;
}
CXXMethodDecl *method = memberCall->getMethodDecl();
if (!method) {
return;
}
const auto methodName = method->getQualifiedNameAsString();
if (methodName != "QByteArray::data" && methodName != "QByteArray::operator const char *" && methodName != "QByteArray::constData") {
return;
}
Expr *obj = memberCall->getImplicitObjectArgument();
Stmt *t = obj;
DeclRefExpr *declRef = nullptr;
CXXBindTemporaryExpr *temporaryExpr = nullptr;
while (t) {
if (dyn_cast<ImplicitCastExpr>(t) || dyn_cast<MaterializeTemporaryExpr>(t) || dyn_cast<CXXFunctionalCastExpr>(t)) {
t = clazy::getFirstChild(t);
continue;
}
if (!onlyTemporaries) {
declRef = dyn_cast<DeclRefExpr>(t);
if (declRef) {
break;
}
}
temporaryExpr = dyn_cast<CXXBindTemporaryExpr>(t);
if (temporaryExpr) {
break;
}
break;
}
if (!temporaryExpr && !declRef) {
return;
}
if (declRef) {
auto *varDecl = dyn_cast<VarDecl>(declRef->getDecl());
if (!varDecl || varDecl->isStaticLocal() || clazy::valueIsConst(varDecl->getType())) {
return;
}
QualType qt = varDecl->getType();
if (qt.isNull() || qt->isReferenceType()) {
return;
}
} else if (temporaryExpr) {
if (clazy::valueIsConst(temporaryExpr->getType())) {
return;
}
}
emitWarning(memberCall, "Returning data of temporary QByteArray");
}