Fix 8124: False positive va_end missing with lambda (#1577)

Skip lambdas, to avoid false positives due to possible
return statements in lambdas.

Also, run dmake.
This commit is contained in:
rikardfalkeborn 2019-01-10 18:32:17 +01:00 committed by Daniel Marjamäki
parent d3a10d3675
commit a48c8abcda
3 changed files with 32 additions and 1 deletions

View File

@ -430,7 +430,7 @@ $(SRCDIR)/checkunusedfunctions.o: lib/checkunusedfunctions.cpp lib/checkunusedfu
$(SRCDIR)/checkunusedvar.o: lib/checkunusedvar.cpp lib/checkunusedvar.h lib/check.h lib/config.h lib/errorlogger.h lib/suppressions.h lib/settings.h lib/importproject.h lib/platform.h lib/utils.h lib/library.h lib/mathlib.h lib/standards.h lib/timer.h lib/token.h lib/valueflow.h lib/templatesimplifier.h lib/tokenize.h lib/tokenlist.h lib/astutils.h lib/symboldatabase.h $(SRCDIR)/checkunusedvar.o: lib/checkunusedvar.cpp lib/checkunusedvar.h lib/check.h lib/config.h lib/errorlogger.h lib/suppressions.h lib/settings.h lib/importproject.h lib/platform.h lib/utils.h lib/library.h lib/mathlib.h lib/standards.h lib/timer.h lib/token.h lib/valueflow.h lib/templatesimplifier.h lib/tokenize.h lib/tokenlist.h lib/astutils.h lib/symboldatabase.h
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CFG) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(SRCDIR)/checkunusedvar.o $(SRCDIR)/checkunusedvar.cpp $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CFG) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(SRCDIR)/checkunusedvar.o $(SRCDIR)/checkunusedvar.cpp
$(SRCDIR)/checkvaarg.o: lib/checkvaarg.cpp lib/checkvaarg.h lib/check.h lib/config.h lib/errorlogger.h lib/suppressions.h lib/settings.h lib/importproject.h lib/platform.h lib/utils.h lib/library.h lib/mathlib.h lib/standards.h lib/timer.h lib/token.h lib/valueflow.h lib/templatesimplifier.h lib/tokenize.h lib/tokenlist.h lib/symboldatabase.h $(SRCDIR)/checkvaarg.o: lib/checkvaarg.cpp lib/checkvaarg.h lib/check.h lib/config.h lib/errorlogger.h lib/suppressions.h lib/settings.h lib/importproject.h lib/platform.h lib/utils.h lib/library.h lib/mathlib.h lib/standards.h lib/timer.h lib/token.h lib/valueflow.h lib/templatesimplifier.h lib/tokenize.h lib/tokenlist.h lib/astutils.h lib/symboldatabase.h
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CFG) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(SRCDIR)/checkvaarg.o $(SRCDIR)/checkvaarg.cpp $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CFG) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(SRCDIR)/checkvaarg.o $(SRCDIR)/checkvaarg.cpp
$(SRCDIR)/cppcheck.o: lib/cppcheck.cpp lib/cppcheck.h lib/analyzerinfo.h lib/config.h lib/errorlogger.h lib/suppressions.h lib/importproject.h lib/platform.h lib/utils.h lib/check.h lib/settings.h lib/library.h lib/mathlib.h lib/standards.h lib/timer.h lib/token.h lib/valueflow.h lib/templatesimplifier.h lib/tokenize.h lib/tokenlist.h lib/checkunusedfunctions.h lib/ctu.h lib/path.h lib/preprocessor.h lib/version.h $(SRCDIR)/cppcheck.o: lib/cppcheck.cpp lib/cppcheck.h lib/analyzerinfo.h lib/config.h lib/errorlogger.h lib/suppressions.h lib/importproject.h lib/platform.h lib/utils.h lib/check.h lib/settings.h lib/library.h lib/mathlib.h lib/standards.h lib/timer.h lib/token.h lib/valueflow.h lib/templatesimplifier.h lib/tokenize.h lib/tokenlist.h lib/checkunusedfunctions.h lib/ctu.h lib/path.h lib/preprocessor.h lib/version.h

View File

@ -18,6 +18,7 @@
#include "checkvaarg.h" #include "checkvaarg.h"
#include "astutils.h"
#include "errorlogger.h" #include "errorlogger.h"
#include "settings.h" #include "settings.h"
#include "symboldatabase.h" #include "symboldatabase.h"
@ -107,6 +108,10 @@ void CheckVaarg::va_list_usage()
const Token* tok = var->nameToken()->next(); const Token* tok = var->nameToken()->next();
for (; tok && tok != var->scope()->bodyEnd; tok = tok->next()) { for (; tok && tok != var->scope()->bodyEnd; tok = tok->next()) {
// Skip lambdas
const Token* tok2 = findLambdaEndToken(tok);
if (tok2)
tok = tok2;
if (Token::Match(tok, "va_start ( %varid%", var->declarationId())) { if (Token::Match(tok, "va_start ( %varid%", var->declarationId())) {
if (open) if (open)
va_start_subsequentCallsError(tok, var->name()); va_start_subsequentCallsError(tok, var->name());

View File

@ -155,6 +155,32 @@ private:
" va_end(arg_ptr);\n" " va_end(arg_ptr);\n"
"}"); "}");
ASSERT_EQUALS("[test.cpp:4]: (error) va_list 'arg_ptr' was opened but not closed by va_end().\n", errout.str()); ASSERT_EQUALS("[test.cpp:4]: (error) va_list 'arg_ptr' was opened but not closed by va_end().\n", errout.str());
// #8124
check("void f(int n, ...)\n"
"{\n"
" va_list ap;\n"
" va_start(ap, n);\n"
" std::vector<std::string> v(n);\n"
" std::generate_n(v.begin(), n, [&ap]()\n"
" {\n"
" return va_arg(ap, const char*);\n"
" });\n"
" va_end(ap);\n"
"}\n");
ASSERT_EQUALS("", errout.str());
check("void f(int n, ...)\n"
"{\n"
" va_list ap;\n"
" va_start(ap, n);\n"
" std::vector<std::string> v(n);\n"
" std::generate_n(v.begin(), n, [&ap]()\n"
" {\n"
" return va_arg(ap, const char*);\n"
" });\n"
"}\n");
ASSERT_EQUALS("[test.cpp:10]: (error) va_list 'ap' was opened but not closed by va_end().\n", errout.str());
} }
void va_list_usedBeforeStarted() { void va_list_usedBeforeStarted() {