Код: Выделить всё
class A {
int member_;
public:
void set(const int& value);
const int& get();
};
< /code>
Реал -набор реализация Сохранения Сохранения передаваемого значения для внутренней переменной типа int, возвращает ссылку на эту переменную. < /p>
Это моя реализация: < /p>
#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
using namespace clang;
using namespace ento;
namespace {
class checkerObjTest : public Checker {
bool handleSet(CheckerContext &C, const CallEvent &Call) const;
public:
bool evalCall(const CallEvent &Call, CheckerContext &C) const;
using FnHandler = bool (checkerObjTest::*)(CheckerContext &, const CallEvent &Call) const;
CallDescriptionMap Functions = {
{{{"set"}, 1}, &checkerObjTest::handleSet},
};
};
} // namespace
bool checkerObjTest::handleSet(CheckerContext &C, const CallEvent &Call) const {
const CallExpr *CE = dyn_cast_or_null(Call.getOriginExpr());
if (!CE)
return false;
const CXXInstanceCall *InstCall = dyn_cast(&Call);
if (!InstCall)
return false;
// Conversion to CXXThisExpr returns null in my example, conversion to
// Expr returns a valid pointer.
//const CXXThisExpr *TE =
dyn_cast_or_null(InstCall->getCXXThisExpr());
const Expr *TE = dyn_cast_or_null(InstCall->getCXXThisExpr());
if (!TE)
return false;
unsigned Count = C.blockCount();
SValBuilder &svalBuilder = C.getSValBuilder();
const LocationContext *LCtx = C.getPredecessor()->getLocationContext();
// Create memory region for object data
// Both of these calls trigger a Loc::isLocType(type) assertion.
DefinedSVal innerDataVal = svalBuilder.getConjuredHeapSymbolVal(TE, LCtx, Count).castAs();
//DefinedSVal innerDataVal = svalBuilder.getConjuredHeapSymbolVal(CE, LCtx, Count).castAs();
return true;
}
bool checkerObjTest::evalCall(const CallEvent &Call, CheckerContext &C) const {
const FnHandler *Handler = Functions.lookup(Call);
if (Handler) {
return (this->**Handler)(C, Call);
}
return false;
}
void ento::registercheckerObjTest(CheckerManager &mgr) {
mgr.registerChecker();
}
bool ento::shouldRegistercheckerObjTest(const CheckerManager &mgr) {
if (mgr.getLangOpts().CPlusPlus)
return true;
return false;
}
< /code>
На этом простом тесте < /p>
class A {
int member_;
public:
void set(const int& value);
const int& get();
};
int main()
{
A a;
int data = 0;
a.set(data);
int res = a.get();
return res;
}
Код: Выделить всё
Assertion `Loc::isLocType(type)' failed.
Подробнее здесь: https://stackoverflow.com/questions/795 ... ype-failed