Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 17 additions & 28 deletions test/testvalueflow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,9 @@ class TestValueFlow : public TestFixture {
TestValueFlow() : TestFixture("TestValueFlow") {}

private:
/*const*/ Settings settings = settingsBuilder().library("std.cfg").build();
const Settings settings = settingsBuilder().library("std.cfg").build();

void run() override {
// strcpy, abort cfg
constexpr char cfg[] = "<?xml version=\"1.0\"?>\n"
"<def>\n"
" <function name=\"strcpy\"> <arg nr=\"1\"><not-null/></arg> </function>\n"
" <function name=\"abort\"> <noreturn>true</noreturn> </function>\n" // abort is a noreturn function
"</def>";
settings = settingsBuilder(settings).libraryxml(cfg).build();

mNewTemplate = true;
TEST_CASE(valueFlowNumber);
Expand Down Expand Up @@ -437,9 +430,10 @@ class TestValueFlow : public TestFixture {
return false;
}

bool testValueOfX_(const char* file, int line, const char code[], unsigned int linenr, int value, ValueFlow::Value::ValueType type) {
bool testValueOfX_(const char* file, int line, const char code[], unsigned int linenr, int value, ValueFlow::Value::ValueType type, const Settings* s = nullptr) {
const Settings& curSettings = s ? *s : settings;
// Tokenize..
SimpleTokenizer tokenizer(settings, *this);
SimpleTokenizer tokenizer(curSettings, *this);
ASSERT_LOC(tokenizer.tokenize(code), file, line);

for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next()) {
Expand Down Expand Up @@ -5871,21 +5865,19 @@ class TestValueFlow : public TestFixture {
ASSERT_EQUALS(false, value.isKnown());

// #13959
const Settings settingsOld = settings;
settings.standards.c = Standards::C23;
const Settings settingsC23 = settingsBuilder(settings).c(Standards::C23).build();
code = "void f(int* p) {\n"
" if (p == nullptr)\n"
" return;\n"
" if (p) {}\n"
"}\n";
value = valueOfTok(code, "p ) { }", &settings, /*cpp*/ false);
value = valueOfTok(code, "p ) { }", &settingsC23, /*cpp*/ false);
ASSERT_EQUALS(1, value.intvalue);
ASSERT_EQUALS(true, value.isKnown());

settings.standards.c = Standards::C17;
value = valueOfTok(code, "p ) { }", &settings, /*cpp*/ false);
const Settings settingsC17 = settingsBuilder(settings).c(Standards::C17).build();
value = valueOfTok(code, "p ) { }", &settingsC17, /*cpp*/ false);
ASSERT(value == ValueFlow::Value());
settings = settingsOld;
}

void valueFlowSizeofForwardDeclaredEnum() {
Expand Down Expand Up @@ -7754,56 +7746,55 @@ class TestValueFlow : public TestFixture {
void valueFlowDynamicBufferSize() {
const char *code;

const Settings settingsOld = settings; // TODO: get rid of this
settings = settingsBuilder(settings).library("posix.cfg").library("bsd.cfg").build();
const Settings settingsCfg = settingsBuilder(settings).library("posix.cfg").library("bsd.cfg").build();

code = "void* f() {\n"
" void* x = malloc(10);\n"
" return x;\n"
"}";
ASSERT_EQUALS(true, testValueOfX(code, 3U, 10, ValueFlow::Value::ValueType::BUFFER_SIZE));
ASSERT_EQUALS(true, testValueOfX(code, 3U, 10, ValueFlow::Value::ValueType::BUFFER_SIZE, &settingsCfg));

code = "void* f() {\n"
" void* x = calloc(4, 5);\n"
" return x;\n"
"}";
ASSERT_EQUALS(true, testValueOfX(code, 3U, 20, ValueFlow::Value::ValueType::BUFFER_SIZE));
ASSERT_EQUALS(true, testValueOfX(code, 3U, 20, ValueFlow::Value::ValueType::BUFFER_SIZE, &settingsCfg));

code = "void* f() {\n"
" const char* y = \"abcd\";\n"
" const char* x = strdup(y);\n"
" return x;\n"
"}";
ASSERT_EQUALS(true, testValueOfX(code, 4U, 5, ValueFlow::Value::ValueType::BUFFER_SIZE));
ASSERT_EQUALS(true, testValueOfX(code, 4U, 5, ValueFlow::Value::ValueType::BUFFER_SIZE, &settingsCfg));

code = "void* f() {\n"
" void* y = malloc(10);\n"
" void* x = realloc(y, 20);\n"
" return x;\n"
"}";
ASSERT_EQUALS(true, testValueOfX(code, 4U, 20, ValueFlow::Value::ValueType::BUFFER_SIZE));
ASSERT_EQUALS(true, testValueOfX(code, 4U, 20, ValueFlow::Value::ValueType::BUFFER_SIZE, &settingsCfg));

code = "void* f() {\n"
" void* y = calloc(10, 4);\n"
" void* x = reallocarray(y, 20, 5);\n"
" return x;\n"
"}";
ASSERT_EQUALS(true, testValueOfX(code, 4U, 100, ValueFlow::Value::ValueType::BUFFER_SIZE));
ASSERT_EQUALS(true, testValueOfX(code, 4U, 100, ValueFlow::Value::ValueType::BUFFER_SIZE, &settingsCfg));

code = "struct A {};\n" // #14305
"void* f() {\n"
" A* x = new A();\n"
" return x;\n"
"}";
ASSERT_EQUALS(true, testValueOfX(code, 4U, 1, ValueFlow::Value::ValueType::BUFFER_SIZE));
ASSERT_EQUALS(true, testValueOfX(code, 4U, 1, ValueFlow::Value::ValueType::BUFFER_SIZE, &settingsCfg));

code = "struct A {};\n"
"void* f() {\n"
" void* x = new A;\n"
" return x;\n"
"}";
{
auto values = tokenValues(code, "x ; }");
auto values = tokenValues(code, "x ; }", &settingsCfg);
ASSERT_EQUALS(1, values.size());
ASSERT(values.front().isSymbolicValue());
// TODO: add BUFFER_SIZE value = 1
Expand All @@ -7814,9 +7805,7 @@ class TestValueFlow : public TestFixture {
" B* x = new B();\n"
" return x;\n"
"}";
ASSERT_EQUALS(true, testValueOfX(code, 4U, 4, ValueFlow::Value::ValueType::BUFFER_SIZE));

settings = settingsOld;
ASSERT_EQUALS(true, testValueOfX(code, 4U, 4, ValueFlow::Value::ValueType::BUFFER_SIZE, &settingsCfg));
}

void valueFlowSafeFunctionParameterValues() {
Expand Down
Loading