Skip to content
Merged
Show file tree
Hide file tree
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
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -621,7 +621,7 @@ test/testbool.o: test/testbool.cpp lib/astutils.h lib/check.h lib/checkbool.h li
test/testboost.o: test/testboost.cpp lib/astutils.h lib/check.h lib/checkboost.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h test/testsuite.h
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testboost.o test/testboost.cpp

test/testbufferoverrun.o: test/testbufferoverrun.cpp externals/tinyxml2/tinyxml2.h lib/astutils.h lib/check.h lib/checkbufferoverrun.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h test/testsuite.h
test/testbufferoverrun.o: test/testbufferoverrun.cpp externals/simplecpp/simplecpp.h externals/tinyxml2/tinyxml2.h lib/astutils.h lib/check.h lib/checkbufferoverrun.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h test/testsuite.h
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testbufferoverrun.o test/testbufferoverrun.cpp

test/testbughuntingchecks.o: test/testbughuntingchecks.cpp lib/astutils.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/exprengine.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h test/testsuite.h
Expand Down
9 changes: 7 additions & 2 deletions lib/valueflow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5224,8 +5224,12 @@ struct ConditionHandler {
if (!top)
return;

if (top->previous()->isExpandedMacro())
return;
if (top->previous()->isExpandedMacro()) {
for (std::list<ValueFlow::Value>* values : {&thenValues, &elseValues}) {
for (ValueFlow::Value& v : *values)
v.macro = true;
}
}

if (!Token::Match(top->previous(), "if|while|for ("))
return;
Expand Down Expand Up @@ -7545,6 +7549,7 @@ ValueFlow::Value::Value(const Token* c, long long val, Bound b)
varId(0),
safe(false),
conditional(false),
macro(false),
defaultArg(false),
indirect(0),
path(0),
Expand Down
4 changes: 4 additions & 0 deletions lib/valueflow.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ namespace ValueFlow {
varId(0U),
safe(false),
conditional(false),
macro(false),
defaultArg(false),
indirect(0),
path(0),
Expand Down Expand Up @@ -346,6 +347,9 @@ namespace ValueFlow {
/** Conditional value */
bool conditional;

/** Value is is from an expanded macro */
bool macro;

/** Is this value passed as default parameter to the function? */
bool defaultArg;

Expand Down
68 changes: 66 additions & 2 deletions test/testbufferoverrun.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,15 @@
#include "config.h"
#include "ctu.h"
#include "library.h"
#include "preprocessor.h"
#include "settings.h"
#include "testsuite.h"
#include "tokenize.h"

#include <tinyxml2.h>
#include <list>
#include <simplecpp.h>
#include <string>

#include <tinyxml2.h>

class TestBufferOverrun : public TestFixture {
public:
Expand Down Expand Up @@ -67,6 +68,45 @@ class TestBufferOverrun : public TestFixture {
checkBufferOverrun.runChecks(&tokenizer, &settings, this);
}

void checkP(const char code[], const char* filename = "test.cpp")
{
// Clear the error buffer..
errout.str("");

Settings* settings = &settings0;
settings->severity.enable(Severity::style);
settings->severity.enable(Severity::warning);
settings->severity.enable(Severity::portability);
settings->severity.enable(Severity::performance);
settings->standards.c = Standards::CLatest;
settings->standards.cpp = Standards::CPPLatest;
settings->certainty.enable(Certainty::inconclusive);
settings->certainty.disable(Certainty::experimental);

// Raw tokens..
std::vector<std::string> files(1, filename);
std::istringstream istr(code);
const simplecpp::TokenList tokens1(istr, files, files[0]);

// Preprocess..
simplecpp::TokenList tokens2(files);
std::map<std::string, simplecpp::TokenList*> filedata;
simplecpp::preprocess(tokens2, tokens1, files, filedata, simplecpp::DUI());

Preprocessor preprocessor(*settings, nullptr);
preprocessor.setDirectives(tokens1);

// Tokenizer..
Tokenizer tokenizer(settings, this);
tokenizer.createTokens(std::move(tokens2));
tokenizer.simplifyTokens1("");
tokenizer.setPreprocessor(&preprocessor);

// Check for buffer overruns..
CheckBufferOverrun checkBufferOverrun(&tokenizer, settings, this);
checkBufferOverrun.runChecks(&tokenizer, settings, this);
}

void run() OVERRIDE {
LOAD_LIB_2(settings0.library, "std.cfg");

Expand Down Expand Up @@ -136,6 +176,7 @@ class TestBufferOverrun : public TestFixture {
TEST_CASE(array_index_57); // #10023
TEST_CASE(array_index_58); // #7524
TEST_CASE(array_index_59); // #10413
TEST_CASE(array_index_60); // #10617, #9824
TEST_CASE(array_index_multidim);
TEST_CASE(array_index_switch_in_for);
TEST_CASE(array_index_for_in_for); // FP: #2634
Expand Down Expand Up @@ -1665,6 +1706,29 @@ class TestBufferOverrun : public TestFixture {
ASSERT_EQUALS("", errout.str());
}

void array_index_60()
{
checkP("#define CKR(B) if (!(B)) { return -1; }\n"
"int f(int i) {\n"
" const int A[3] = {};\n"
" CKR(i < 3);\n"
" if (i > 0)\n"
" i = A[i];\n"
" return i;\n"
"}\n");
ASSERT_EQUALS("", errout.str());

checkP("#define ASSERT(expression, action) if (expression) {action;}\n"
"int array[5];\n"
"void func (int index) {\n"
" ASSERT(index > 5, return);\n"
" array[index]++;\n"
"}\n");
ASSERT_EQUALS(
"[test.cpp:4] -> [test.cpp:5]: (warning) Either the condition 'index>5' is redundant or the array 'array[5]' is accessed at index 5, which is out of bounds.\n",
errout.str());
}

void array_index_multidim() {
check("void f()\n"
"{\n"
Expand Down