Skip to content

Commit 255eebc

Browse files
author
Your Name
committed
Merge
2 parents 98d309e + 4517bc7 commit 255eebc

18 files changed

Lines changed: 332 additions & 152 deletions

.selfcheck_suppressions

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ templateInstantiation:test/testutils.cpp
6262

6363
naming-varname:externals/simplecpp/simplecpp.h
6464
naming-privateMemberVariable:externals/simplecpp/simplecpp.h
65+
# false positive; lambda captures its owner
66+
danglingLifetime:externals/simplecpp/simplecpp.h:505
6567

6668
# TODO: these warnings need to be addressed upstream
6769
uninitMemberVar:externals/tinyxml2/tinyxml2.h

cfg/gtk.cfg

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2251,6 +2251,7 @@
22512251
</function>
22522252
<!-- GList * g_list_find (GList *list, gconstpointer data); -->
22532253
<function name="g_list_find">
2254+
<pure/>
22542255
<leak-ignore/>
22552256
<noreturn>false</noreturn>
22562257
<returnValue type="GList"/>
@@ -5218,6 +5219,7 @@
52185219
<!-- gboolean g_str_has_prefix (const gchar* str, const gchar* prefix); -->
52195220
<!-- gboolean g_str_has_suffix (const gchar* str, const gchar* prefix); -->
52205221
<function name="g_str_has_prefix,g_str_has_suffix">
5222+
<pure/>
52215223
<leak-ignore/>
52225224
<noreturn>false</noreturn>
52235225
<returnValue type="gboolean"/>
@@ -6586,6 +6588,7 @@
65866588
</function>
65876589
<!-- gboolean g_error_matches(const GError *error, GQuark domain, gint code); -->
65886590
<function name="g_error_matches">
6591+
<pure/>
65896592
<noreturn>false</noreturn>
65906593
<returnValue type="gboolean"/>
65916594
<use-retval/>

cfg/qt.cfg

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,6 @@
410410
</arg>
411411
<arg nr="4" default="0">
412412
<not-uninit/>
413-
<not-bool/>
414413
</arg>
415414
<arg nr="5" default="0">
416415
<not-uninit/>

lib/checkclass.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2608,9 +2608,12 @@ bool CheckClassImpl::checkConstFunc(const Scope *scope, const Function *func, Me
26082608
return false;
26092609
} else {
26102610
if (lhs->isAssignmentOp()) {
2611-
const Variable* lhsVar = lhs->previous()->variable();
2612-
if (lhsVar && !lhsVar->isConst() && lhsVar->isReference() && lhs == lhsVar->nameToken()->next())
2613-
return false;
2611+
if (const Variable* lhsVar = lhs->previous()->variable()) {
2612+
if (!lhsVar->isConst() && lhsVar->isReference() && lhs == lhsVar->nameToken()->next())
2613+
return false;
2614+
if (lhsVar->isPointer() && v && v->isArray() && !(lhsVar->valueType() && lhsVar->valueType()->isConst(/*indirect*/ 1)))
2615+
return false;
2616+
}
26142617
}
26152618
}
26162619

lib/cppcheck.cpp

Lines changed: 85 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
#include <exception> // IWYU pragma: keep
6262
#include <fstream>
6363
#include <iostream>
64+
#include <iterator>
6465
#include <map>
6566
#include <new>
6667
#include <set>
@@ -100,9 +101,9 @@ class CppCheck::CppCheckLogger : public ErrorLogger
100101
closePlist();
101102
}
102103

103-
void setRemarkComments(std::vector<RemarkComment> remarkComments)
104+
void addRemarkComments(const std::vector<RemarkComment> &remarkComments)
104105
{
105-
mRemarkComments = std::move(remarkComments);
106+
mRemarkComments.insert(mRemarkComments.end(), remarkComments.begin(), remarkComments.end());
106107
}
107108

108109
void setLocationMacros(const Token* startTok, const std::vector<std::string>& files)
@@ -124,17 +125,25 @@ class CppCheck::CppCheckLogger : public ErrorLogger
124125
mErrorList.clear();
125126
}
126127

127-
void openPlist(const std::string& filename, const std::vector<std::string>& files)
128+
void openPlist(const std::string& filename)
128129
{
129130
mPlistFile.open(filename);
130-
mPlistFile << ErrorLogger::plistHeader(version(), files);
131+
mPlistFile << ErrorLogger::plistHeader(version());
132+
}
133+
134+
void setPlistFilenames(std::vector<std::string> files)
135+
{
136+
if (mPlistFile.is_open()) {
137+
mPlistFilenames = std::move(files);
138+
}
131139
}
132140

133141
void closePlist()
134142
{
135143
if (mPlistFile.is_open()) {
136-
mPlistFile << ErrorLogger::plistFooter();
144+
mPlistFile << ErrorLogger::plistFooter(mPlistFilenames);
137145
mPlistFile.close();
146+
mPlistFilenames.clear();
138147
}
139148
}
140149

@@ -282,6 +291,7 @@ class CppCheck::CppCheckLogger : public ErrorLogger
282291
std::map<Location, std::set<std::string>> mLocationMacros; // What macros are used on a location?
283292

284293
std::ofstream mPlistFile;
294+
std::vector<std::string> mPlistFilenames;
285295

286296
unsigned int mExitCode{};
287297

@@ -898,7 +908,7 @@ unsigned int CppCheck::checkFile(const FileWithDetails& file, const std::string
898908
return checkInternal(file, cfgname, f);
899909
}
900910

901-
void CppCheck::checkPlistOutput(const FileWithDetails& file, const std::vector<std::string>& files)
911+
void CppCheck::checkPlistOutput(const FileWithDetails& file)
902912
{
903913
if (!mSettings.plistOutput.empty()) {
904914
const bool slashFound = file.spath().find('/') != std::string::npos;
@@ -909,7 +919,7 @@ void CppCheck::checkPlistOutput(const FileWithDetails& file, const std::vector<s
909919
// the hash is added to handle when files in different folders have the same name
910920
const std::size_t fileNameHash = std::hash<std::string> {}(file.spath());
911921
filename = mSettings.plistOutput + noSuffixFilename + "_" + std::to_string(fileNameHash) + ".plist";
912-
mLogger->openPlist(filename, files);
922+
mLogger->openPlist(filename);
913923
}
914924
}
915925

@@ -1000,24 +1010,16 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str
10001010
if (preprocessor.reportOutput(outputList, true))
10011011
return mLogger->exitcode();
10021012

1003-
if (!preprocessor.loadFiles(files))
1004-
return mLogger->exitcode();
1005-
1006-
checkPlistOutput(file, files);
1013+
checkPlistOutput(file);
10071014

1008-
std::string dumpProlog;
1015+
std::string dumpFooter;
10091016
if (mSettings.dump || !mSettings.addons.empty()) {
1010-
dumpProlog += getDumpFileContentsRawTokens(files, tokens1);
1017+
dumpFooter += getDumpFileContentsRawTokensFooter(tokens1);
10111018
}
10121019

10131020
// Parse comments and then remove them
1014-
mLogger->setRemarkComments(preprocessor.getRemarkComments());
1021+
mLogger->addRemarkComments(preprocessor.getRemarkComments());
10151022
preprocessor.inlineSuppressions(mSuppressions.nomsg);
1016-
if (mSettings.dump || !mSettings.addons.empty()) {
1017-
std::ostringstream oss;
1018-
mSuppressions.nomsg.dump(oss);
1019-
dumpProlog += oss.str();
1020-
}
10211023
preprocessor.removeComments();
10221024

10231025
if (!mSettings.buildDir.empty()) {
@@ -1040,19 +1042,45 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str
10401042
}
10411043

10421044
// Get directives
1043-
std::list<Directive> directives = preprocessor.createDirectives();
1045+
std::list<Directive> directives;
1046+
preprocessor.createDirectives(directives);
10441047
preprocessor.simplifyPragmaAsm();
10451048

1049+
std::set<std::string> configurations;
1050+
std::set<std::string> configDefines = { "__cplusplus" };
1051+
1052+
// Insert library defines
1053+
const auto getDefineName = [](const std::string &defineString) {
1054+
return defineString.substr(0, defineString.find_first_of("( "));
1055+
};
1056+
std::transform(mSettings.library.defines().begin(),
1057+
mSettings.library.defines().end(),
1058+
std::inserter(configDefines, configDefines.end()),
1059+
getDefineName);
1060+
1061+
preprocessor.setLoadCallback([&](simplecpp::FileData &data) {
1062+
// Do preprocessing on included file
1063+
mLogger->addRemarkComments(preprocessor.getRemarkComments(data.tokens));
1064+
preprocessor.inlineSuppressions(data.tokens, mSuppressions.nomsg);
1065+
Preprocessor::removeComments(data.tokens);
1066+
Preprocessor::createDirectives(data.tokens, directives);
1067+
Preprocessor::simplifyPragmaAsm(data.tokens);
1068+
// Discover new configurations from included file
1069+
if (configurations.size() < maxConfigs)
1070+
preprocessor.getConfigs(data.filename, data.tokens, configDefines, configurations);
1071+
});
1072+
10461073
preprocessor.setPlatformInfo();
10471074

10481075
// Get configurations..
1049-
std::set<std::string> configurations;
10501076
if (maxConfigs > 1) {
10511077
Timer::run("Preprocessor::getConfigs", mTimerResults, [&]() {
1052-
configurations = preprocessor.getConfigs();
1078+
configurations = { "" };
1079+
preprocessor.getConfigs(configDefines, configurations);
1080+
preprocessor.loadFiles(files);
10531081
});
10541082
} else {
1055-
configurations.insert(mSettings.userDefines);
1083+
configurations = { mSettings.userDefines };
10561084
}
10571085

10581086
if (mSettings.checkConfiguration) {
@@ -1089,7 +1117,6 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str
10891117
createDumpFile(mSettings, file, fdump, dumpFile);
10901118
if (fdump.is_open()) {
10911119
fdump << getLibraryDumpData();
1092-
fdump << dumpProlog;
10931120
if (!mSettings.dump)
10941121
filesDeleter.addFile(dumpFile);
10951122
}
@@ -1259,12 +1286,20 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str
12591286
}
12601287

12611288
// TODO: will not be closed if we encountered an exception
1262-
// dumped all configs, close root </dumps> element now
12631289
if (fdump.is_open()) {
1290+
// dump all filenames, raw tokens, suppressions
1291+
std::string dumpHeader = getDumpFileContentsRawTokensHeader(files);
1292+
fdump << getDumpFileContentsRawTokens(dumpHeader, dumpFooter);
1293+
mSuppressions.nomsg.dump(fdump);
1294+
// dumped all configs, close root </dumps> element now
12641295
fdump << "</dumps>" << std::endl;
12651296
fdump.close();
12661297
}
12671298

1299+
if (!mSettings.plistOutput.empty()) {
1300+
mLogger->setPlistFilenames(std::move(files));
1301+
}
1302+
12681303
executeAddons(dumpFile, file);
12691304
} catch (const TerminateException &) {
12701305
// Analysis is terminated
@@ -1892,16 +1927,39 @@ bool CppCheck::isPremiumCodingStandardId(const std::string& id) const {
18921927
return false;
18931928
}
18941929

1895-
std::string CppCheck::getDumpFileContentsRawTokens(const std::vector<std::string>& files, const simplecpp::TokenList& tokens1) const {
1930+
std::string CppCheck::getDumpFileContentsRawTokens(const std::vector<std::string>& files, const simplecpp::TokenList& tokens1) const
1931+
{
1932+
std::string header = getDumpFileContentsRawTokensHeader(files);
1933+
std::string footer = getDumpFileContentsRawTokensFooter(tokens1);
1934+
return getDumpFileContentsRawTokens(header, footer);
1935+
}
1936+
1937+
std::string CppCheck::getDumpFileContentsRawTokens(const std::string& header, const std::string& footer)
1938+
{
18961939
std::string dumpProlog;
18971940
dumpProlog += " <rawtokens>\n";
1941+
dumpProlog += header;
1942+
dumpProlog += footer;
1943+
dumpProlog += " </rawtokens>\n";
1944+
return dumpProlog;
1945+
}
1946+
1947+
std::string CppCheck::getDumpFileContentsRawTokensHeader(const std::vector<std::string>& files) const
1948+
{
1949+
std::string dumpProlog;
18981950
for (unsigned int i = 0; i < files.size(); ++i) {
18991951
dumpProlog += " <file index=\"";
19001952
dumpProlog += std::to_string(i);
19011953
dumpProlog += "\" name=\"";
19021954
dumpProlog += ErrorLogger::toxml(Path::getRelativePath(files[i], mSettings.basePaths));
19031955
dumpProlog += "\"/>\n";
19041956
}
1957+
return dumpProlog;
1958+
}
1959+
1960+
std::string CppCheck::getDumpFileContentsRawTokensFooter(const simplecpp::TokenList& tokens1)
1961+
{
1962+
std::string dumpProlog;
19051963
for (const simplecpp::Token *tok = tokens1.cfront(); tok; tok = tok->next) {
19061964
dumpProlog += " <tok ";
19071965

@@ -1913,7 +1971,7 @@ std::string CppCheck::getDumpFileContentsRawTokens(const std::vector<std::string
19131971
dumpProlog += std::to_string(tok->location.line);
19141972
dumpProlog += "\" ";
19151973

1916-
dumpProlog +="column=\"";
1974+
dumpProlog += "column=\"";
19171975
dumpProlog += std::to_string(tok->location.col);
19181976
dumpProlog += "\" ";
19191977

@@ -1923,6 +1981,5 @@ std::string CppCheck::getDumpFileContentsRawTokens(const std::vector<std::string
19231981

19241982
dumpProlog += "/>\n";
19251983
}
1926-
dumpProlog += " </rawtokens>\n";
19271984
return dumpProlog;
19281985
}

lib/cppcheck.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,9 @@ class CPPCHECKLIB CppCheck {
153153
* @brief Get dumpfile <rawtokens> contents, this is only public for testing purposes
154154
*/
155155
std::string getDumpFileContentsRawTokens(const std::vector<std::string>& files, const simplecpp::TokenList& tokens1) const;
156+
static std::string getDumpFileContentsRawTokens(const std::string& header, const std::string& footer);
157+
std::string getDumpFileContentsRawTokensHeader(const std::vector<std::string>& files) const;
158+
static std::string getDumpFileContentsRawTokensFooter(const simplecpp::TokenList& tokens1);
156159

157160
std::string getLibraryDumpData() const;
158161

@@ -183,7 +186,7 @@ class CPPCHECKLIB CppCheck {
183186
*/
184187
unsigned int checkFile(const FileWithDetails& file, const std::string &cfgname);
185188

186-
void checkPlistOutput(const FileWithDetails& file, const std::vector<std::string>& files);
189+
void checkPlistOutput(const FileWithDetails& file);
187190

188191
/**
189192
* @brief Check a file using buffer

lib/errorlogger.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -821,20 +821,15 @@ std::string ErrorLogger::toxml(const std::string &str)
821821
return xml;
822822
}
823823

824-
std::string ErrorLogger::plistHeader(const std::string &version, const std::vector<std::string> &files)
824+
std::string ErrorLogger::plistHeader(const std::string &version)
825825
{
826826
std::ostringstream ostr;
827827
ostr << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"
828828
<< "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\r\n"
829829
<< "<plist version=\"1.0\">\r\n"
830830
<< "<dict>\r\n"
831831
<< " <key>clang_version</key>\r\n"
832-
<< "<string>cppcheck version " << version << "</string>\r\n"
833-
<< " <key>files</key>\r\n"
834-
<< " <array>\r\n";
835-
for (const std::string & file : files)
836-
ostr << " <string>" << ErrorLogger::toxml(file) << "</string>\r\n";
837-
ostr << " </array>\r\n"
832+
<< " <string>cppcheck version " << version << "</string>\r\n"
838833
<< " <key>diagnostics</key>\r\n"
839834
<< " <array>\r\n";
840835
return ostr.str();

lib/errorlogger.h

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include <ctime>
3030
#include <list>
3131
#include <set>
32+
#include <sstream>
3233
#include <string>
3334
#include <utility>
3435
#include <vector>
@@ -272,12 +273,19 @@ class CPPCHECKLIB ErrorLogger {
272273
*/
273274
static std::string toxml(const std::string &str);
274275

275-
static std::string plistHeader(const std::string &version, const std::vector<std::string> &files);
276+
static std::string plistHeader(const std::string &version);
276277
static std::string plistData(const ErrorMessage &msg);
277-
static const char *plistFooter() {
278-
return " </array>\r\n"
279-
"</dict>\r\n"
280-
"</plist>";
278+
static std::string plistFooter(const std::vector<std::string>& files) {
279+
std::ostringstream ostr;
280+
ostr << " </array>\r\n"
281+
<< " <key>files</key>\r\n"
282+
<< " <array>\r\n";
283+
for (const std::string& file : files)
284+
ostr << " <string>" << ErrorLogger::toxml(file) << "</string>\r\n";
285+
ostr << " </array>\r\n"
286+
<< "</dict>\r\n"
287+
<< "</plist>";
288+
return ostr.str();
281289
}
282290

283291
static bool isCriticalErrorId(const std::string& id) {

0 commit comments

Comments
 (0)