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:
parent
d3a10d3675
commit
a48c8abcda
2
Makefile
2
Makefile
|
@ -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
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
Loading…
Reference in New Issue