ExprEngine: Better handling of pointers
This commit is contained in:
parent
6c9839a585
commit
ec4b7c1f4b
|
@ -269,6 +269,18 @@ std::string ExprEngine::ArrayValue::getRange() const
|
|||
return r.str();
|
||||
}
|
||||
|
||||
std::string ExprEngine::PointerValue::getRange() const
|
||||
{
|
||||
std::string r;
|
||||
if (data)
|
||||
r = "->" + data->getRange();
|
||||
if (null)
|
||||
r += std::string(r.empty() ? "" : ",") + "null";
|
||||
if (uninitData)
|
||||
r += std::string(r.empty() ? "" : ",") + "->?";
|
||||
return r;
|
||||
}
|
||||
|
||||
std::string ExprEngine::BinOpResult::getRange() const
|
||||
{
|
||||
int128_t minValue, maxValue;
|
||||
|
@ -670,14 +682,28 @@ static ExprEngine::ValuePtr createStructVal(const Scope *structScope, Data &data
|
|||
|
||||
static ExprEngine::ValuePtr createVariableValue(const Variable &var, Data &data)
|
||||
{
|
||||
if (!var.nameToken() || !var.valueType())
|
||||
if (!var.nameToken())
|
||||
return ExprEngine::ValuePtr();
|
||||
if (var.valueType()->pointer > 0)
|
||||
return std::make_shared<ExprEngine::PointerValue>(data.getNewSymbolName(), std::make_shared<ExprEngine::UninitValue>());
|
||||
if (var.valueType()->isIntegral())
|
||||
return getValueRangeFromValueType(data.getNewSymbolName(), var.valueType(), *data.settings);
|
||||
if (var.valueType()->type == ValueType::Type::RECORD)
|
||||
return createStructVal(var.valueType()->typeScope, data);
|
||||
const ValueType *valueType = var.valueType();
|
||||
if (!valueType || valueType->type == ValueType::Type::UNKNOWN_TYPE)
|
||||
valueType = var.nameToken()->valueType();
|
||||
if (!valueType || valueType->type == ValueType::Type::UNKNOWN_TYPE)
|
||||
return ExprEngine::ValuePtr();
|
||||
|
||||
if (valueType->pointer > 0) {
|
||||
ValueType vt(*valueType);
|
||||
vt.pointer = 0;
|
||||
auto intRange = getValueRangeFromValueType(data.getNewSymbolName(), &vt, *data.settings);
|
||||
return std::make_shared<ExprEngine::PointerValue>(data.getNewSymbolName(), intRange, true, true);
|
||||
}
|
||||
if (valueType->isIntegral())
|
||||
return getValueRangeFromValueType(data.getNewSymbolName(), valueType, *data.settings);
|
||||
if (valueType->type == ValueType::Type::RECORD)
|
||||
return createStructVal(valueType->typeScope, data);
|
||||
if (valueType->smartPointerType) {
|
||||
auto structValue = createStructVal(valueType->smartPointerType->classScope, data);
|
||||
return std::make_shared<ExprEngine::PointerValue>(data.getNewSymbolName(), structValue, true, false);
|
||||
}
|
||||
return ExprEngine::ValuePtr();
|
||||
}
|
||||
|
||||
|
|
|
@ -108,14 +108,19 @@ namespace ExprEngine {
|
|||
|
||||
class PointerValue: public Value {
|
||||
public:
|
||||
PointerValue(const std::string &name, ValuePtr data) : Value(name), data(data) {}
|
||||
PointerValue(const std::string &name, ValuePtr data, bool null, bool uninitData)
|
||||
: Value(name)
|
||||
, data(data)
|
||||
, null(null)
|
||||
, uninitData(uninitData) {
|
||||
}
|
||||
ValueType type() const override {
|
||||
return ValueType::PointerValue;
|
||||
}
|
||||
std::string getRange() const override {
|
||||
return "*" + data->getRange();
|
||||
}
|
||||
std::string getRange() const override;
|
||||
ValuePtr data;
|
||||
bool null;
|
||||
bool uninitData;
|
||||
};
|
||||
|
||||
class ArrayValue: public Value {
|
||||
|
|
|
@ -30,6 +30,7 @@ public:
|
|||
private:
|
||||
void run() OVERRIDE {
|
||||
TEST_CASE(argPointer);
|
||||
TEST_CASE(argSmartPointer);
|
||||
TEST_CASE(argStruct);
|
||||
|
||||
TEST_CASE(expr1);
|
||||
|
@ -61,6 +62,7 @@ private:
|
|||
std::string getRange(const char code[], const std::string &str) {
|
||||
Settings settings;
|
||||
settings.platform(cppcheck::Platform::Unix64);
|
||||
settings.library.smartPointers.insert("std::shared_ptr");
|
||||
Tokenizer tokenizer(&settings, this);
|
||||
std::istringstream istr(code);
|
||||
tokenizer.tokenize(istr, "test.cpp");
|
||||
|
@ -79,7 +81,11 @@ private:
|
|||
}
|
||||
|
||||
void argPointer() {
|
||||
ASSERT_EQUALS("?", getRange("void f(unsigned char *p) { a = *p; }", "*p"));
|
||||
ASSERT_EQUALS("->0:255,null,->?", getRange("void f(unsigned char *p) { a = *p; }", "p"));
|
||||
}
|
||||
|
||||
void argSmartPointer() {
|
||||
ASSERT_EQUALS("->$1,null", getRange("struct S { int x; }; void f(std::shared_ptr<S> ptr) { x = ptr; }", "ptr"));
|
||||
}
|
||||
|
||||
void argStruct() {
|
||||
|
|
Loading…
Reference in New Issue