Skip to content
Merged
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));

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to be the only test that actually needs the special settings, and only bsd.cfg at that.

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