Fix 10617, 9824: conditions in expanded macro (#3578)

This commit is contained in:
Paul Fultz II 2021-11-25 11:40:15 -06:00 committed by GitHub
parent 085d25f1b1
commit 33ad30f4da
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 78 additions and 5 deletions

View File

@ -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

View File

@ -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;
@ -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),

View File

@ -98,6 +98,7 @@ namespace ValueFlow {
varId(0U),
safe(false),
conditional(false),
macro(false),
defaultArg(false),
indirect(0),
path(0),
@ -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;

View File

@ -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:
@ -67,6 +68,45 @@ private:
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");
@ -136,6 +176,7 @@ private:
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
@ -1665,6 +1706,29 @@ private:
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"