Skip to content

Commit 1228697

Browse files
Merge branch 'main' into chr_internal
2 parents 915001c + bd694db commit 1228697

22 files changed

+418
-180
lines changed

Diff for: Makefile

+50-50
Large diffs are not rendered by default.

Diff for: gui/erroritem.cpp

+3-5
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,10 @@ ErrorItem::ErrorItem(const ErrorMessage &errmsg)
5151
, cwe(errmsg.cwe.id)
5252
, hash(errmsg.hash)
5353
, symbolNames(QString::fromStdString(errmsg.symbolNames()))
54+
, remark(QString::fromStdString(errmsg.remark))
5455
{
55-
for (std::list<ErrorMessage::FileLocation>::const_iterator loc = errmsg.callStack.cbegin();
56-
loc != errmsg.callStack.cend();
57-
++loc) {
58-
errorPath << QErrorPathItem(*loc);
59-
}
56+
for (const auto& loc: errmsg.callStack)
57+
errorPath << QErrorPathItem(loc);
6058
}
6159

6260
QString ErrorItem::tool() const

Diff for: gui/erroritem.h

+2
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ class ErrorItem {
9191
unsigned long long hash;
9292
QList<QErrorPathItem> errorPath;
9393
QString symbolNames;
94+
QString remark;
9495

9596
// Special GUI properties
9697
QString sinceDate;
@@ -122,6 +123,7 @@ class ErrorLine {
122123
QString message;
123124
QString sinceDate;
124125
QString tags;
126+
QString remark;
125127
};
126128

127129
/// @}

Diff for: gui/resultstree.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ static constexpr char SINCEDATE[] = "sinceDate";
7777
static constexpr char SYMBOLNAMES[] = "symbolNames";
7878
static constexpr char SUMMARY[] = "summary";
7979
static constexpr char TAGS[] = "tags";
80+
static constexpr char REMARK[] = "remark";
8081

8182
// These must match column headers given in ResultsTree::translate()
8283
static constexpr int COLUMN_SINCE_DATE = 6;
@@ -185,6 +186,7 @@ bool ResultsTree::addErrorItem(const ErrorItem &item)
185186
if (const ProjectFile *activeProject = ProjectFile::getActiveProject()) {
186187
line.tags = activeProject->getWarningTags(item.hash);
187188
}
189+
line.remark = item.remark;
188190
//Create the base item for the error and ensure it has a proper
189191
//file item as a parent
190192
QStandardItem* fileItem = ensureFileItem(loc.file, item.file0, hide);
@@ -213,6 +215,7 @@ bool ResultsTree::addErrorItem(const ErrorItem &item)
213215
data[SINCEDATE] = item.sinceDate;
214216
data[SYMBOLNAMES] = item.symbolNames;
215217
data[TAGS] = line.tags;
218+
data[REMARK] = line.remark;
216219
data[HIDE] = hide;
217220
stditem->setData(QVariant(data));
218221

@@ -1295,6 +1298,7 @@ void ResultsTree::readErrorItem(const QStandardItem *error, ErrorItem *item) con
12951298
item->file0 = data[FILE0].toString();
12961299
item->sinceDate = data[SINCEDATE].toString();
12971300
item->tags = data[TAGS].toString();
1301+
item->remark = data[REMARK].toString();
12981302

12991303
if (error->rowCount() == 0) {
13001304
QErrorPathItem e;

Diff for: gui/xmlreportv2.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ static const QString TagsAttribute = "tag";
4949
static const QString FilenameAttribute = "file";
5050
static const QString IncludedFromFilenameAttribute = "file0";
5151
static const QString InconclusiveAttribute = "inconclusive";
52+
static const QString RemarkAttribute = "remark";
5253
static const QString InfoAttribute = "info";
5354
static const QString LineAttribute = "line";
5455
static const QString ColumnAttribute = "column";
@@ -137,6 +138,8 @@ void XmlReportV2::writeError(const ErrorItem &error)
137138
mXmlWriter->writeAttribute(VerboseAttribute, message);
138139
if (error.inconclusive)
139140
mXmlWriter->writeAttribute(InconclusiveAttribute, "true");
141+
if (!error.remark.isEmpty())
142+
mXmlWriter->writeAttribute(RemarkAttribute, error.remark);
140143
if (error.cwe > 0)
141144
mXmlWriter->writeAttribute(CWEAttribute, QString::number(error.cwe));
142145
if (error.hash > 0)
@@ -231,6 +234,8 @@ ErrorItem XmlReportV2::readError(const QXmlStreamReader *reader)
231234
item.message = XmlReport::unquoteMessage(message);
232235
if (attribs.hasAttribute(QString(), InconclusiveAttribute))
233236
item.inconclusive = true;
237+
if (attribs.hasAttribute(QString(), RemarkAttribute))
238+
item.remark = attribs.value(QString(), RemarkAttribute).toString();
234239
if (attribs.hasAttribute(QString(), CWEAttribute))
235240
item.cwe = attribs.value(QString(), CWEAttribute).toInt();
236241
if (attribs.hasAttribute(QString(), HashAttribute))

Diff for: lib/cppcheck.cpp

+21-1
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,7 @@ unsigned int CppCheck::checkFile(const std::string& filename, const std::string
706706
}
707707

708708
// Parse comments and then remove them
709+
mRemarkComments = preprocessor.getRemarkComments(tokens1);
709710
preprocessor.inlineSuppressions(tokens1, mSettings.supprs.nomsg);
710711
if (mSettings.dump || !mSettings.addons.empty()) {
711712
std::ostringstream oss;
@@ -1613,7 +1614,26 @@ void CppCheck::reportErr(const ErrorMessage &msg)
16131614
mExitCode = 1;
16141615
}
16151616

1616-
mErrorLogger.reportErr(msg);
1617+
std::string remark;
1618+
if (!msg.callStack.empty()) {
1619+
for (const auto& r: mRemarkComments) {
1620+
if (r.file != msg.callStack.back().getfile(false))
1621+
continue;
1622+
if (r.lineNumber != msg.callStack.back().line)
1623+
continue;
1624+
remark = r.str;
1625+
break;
1626+
}
1627+
}
1628+
1629+
if (!remark.empty()) {
1630+
ErrorMessage msg2(msg);
1631+
msg2.remark = remark;
1632+
mErrorLogger.reportErr(msg2);
1633+
} else {
1634+
mErrorLogger.reportErr(msg);
1635+
}
1636+
16171637
// check if plistOutput should be populated and the current output file is open and the error is not suppressed
16181638
if (!mSettings.plistOutput.empty() && mPlistFile.is_open() && !mSettings.supprs.nomsg.isSuppressed(errorMessage)) {
16191639
// add error to plist output file

Diff for: lib/cppcheck.h

+3
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ struct FileSettings;
4545
class CheckUnusedFunctions;
4646
class Tokenizer;
4747
class FileWithDetails;
48+
class RemarkComment;
4849

4950
namespace simplecpp { class TokenList; }
5051

@@ -254,6 +255,8 @@ class CPPCHECKLIB CppCheck : ErrorLogger {
254255
std::ofstream mPlistFile;
255256

256257
std::unique_ptr<CheckUnusedFunctions> mUnusedFunctionsCheck;
258+
259+
std::vector<RemarkComment> mRemarkComments;
257260
};
258261

259262
/// @}

Diff for: lib/errorlogger.cpp

+15-15
Original file line numberDiff line numberDiff line change
@@ -274,11 +274,9 @@ std::string ErrorMessage::serialize() const
274274
serializeString(oss, severityToString(severity));
275275
serializeString(oss, std::to_string(cwe.id));
276276
serializeString(oss, std::to_string(hash));
277+
serializeString(oss, fixInvalidChars(remark));
277278
serializeString(oss, file0);
278-
if (certainty == Certainty::inconclusive) {
279-
const std::string text("inconclusive");
280-
serializeString(oss, text);
281-
}
279+
serializeString(oss, (certainty == Certainty::inconclusive) ? "1" : "0");
282280

283281
const std::string saneShortMessage = fixInvalidChars(mShortMessage);
284282
const std::string saneVerboseMessage = fixInvalidChars(mVerboseMessage);
@@ -312,9 +310,9 @@ void ErrorMessage::deserialize(const std::string &data)
312310
callStack.clear();
313311

314312
std::istringstream iss(data);
315-
std::array<std::string, 7> results;
313+
std::array<std::string, 9> results;
316314
std::size_t elem = 0;
317-
while (iss.good() && elem < 7) {
315+
while (iss.good() && elem < 9) {
318316
unsigned int len = 0;
319317
if (!(iss >> len))
320318
throw InternalError(nullptr, "Internal Error: Deserialization of error message failed - invalid length");
@@ -332,11 +330,6 @@ void ErrorMessage::deserialize(const std::string &data)
332330

333331
if (!iss.good())
334332
throw InternalError(nullptr, "Internal Error: Deserialization of error message failed - premature end of data");
335-
336-
if (temp == "inconclusive") {
337-
certainty = Certainty::inconclusive;
338-
continue;
339-
}
340333
}
341334

342335
results[elem++] = std::move(temp);
@@ -345,7 +338,7 @@ void ErrorMessage::deserialize(const std::string &data)
345338
if (!iss.good())
346339
throw InternalError(nullptr, "Internal Error: Deserialization of error message failed - premature end of data");
347340

348-
if (elem != 7)
341+
if (elem != 9)
349342
throw InternalError(nullptr, "Internal Error: Deserialization of error message failed - insufficient elements");
350343

351344
id = std::move(results[0]);
@@ -362,9 +355,12 @@ void ErrorMessage::deserialize(const std::string &data)
362355
if (!strToInt(results[3], hash, &err))
363356
throw InternalError(nullptr, "Internal Error: Deserialization of error message failed - invalid hash - " + err);
364357
}
365-
file0 = std::move(results[4]);
366-
mShortMessage = std::move(results[5]);
367-
mVerboseMessage = std::move(results[6]);
358+
remark = std::move(results[4]);
359+
file0 = std::move(results[5]);
360+
if (results[6] == "1")
361+
certainty = Certainty::inconclusive;
362+
mShortMessage = std::move(results[7]);
363+
mVerboseMessage = std::move(results[8]);
368364

369365
unsigned int stackSize = 0;
370366
if (!(iss >> stackSize))
@@ -496,6 +492,9 @@ std::string ErrorMessage::toXML() const
496492
if (!file0.empty())
497493
printer.PushAttribute("file0", file0.c_str());
498494

495+
if (!remark.empty())
496+
printer.PushAttribute("remark", fixInvalidChars(remark).c_str());
497+
499498
for (std::list<FileLocation>::const_reverse_iterator it = callStack.crbegin(); it != callStack.crend(); ++it) {
500499
printer.OpenElement("location", false);
501500
printer.PushAttribute("file", it->getfile().c_str());
@@ -641,6 +640,7 @@ std::string ErrorMessage::toString(bool verbose, const std::string &templateForm
641640
findAndReplace(result, "{severity}", severityToString(severity));
642641
findAndReplace(result, "{cwe}", std::to_string(cwe.id));
643642
findAndReplace(result, "{message}", verbose ? mVerboseMessage : mShortMessage);
643+
findAndReplace(result, "{remark}", remark);
644644
if (!callStack.empty()) {
645645
if (result.find("{callstack}") != std::string::npos)
646646
findAndReplace(result, "{callstack}", ErrorLogger::callStackToString(callStack));

Diff for: lib/errorlogger.h

+3
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,9 @@ class CPPCHECKLIB ErrorMessage {
171171
CWE cwe;
172172
Certainty certainty;
173173

174+
/** remark from REMARK comment */
175+
std::string remark;
176+
174177
/** Warning hash */
175178
std::size_t hash;
176179

Diff for: lib/preprocessor.cpp

+74-10
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,19 @@ static bool parseInlineSuppressionCommentToken(const simplecpp::Token *tok, std:
153153
return true;
154154
}
155155

156+
static std::string getRelativeFilename(const simplecpp::Token* tok, const Settings &settings) {
157+
std::string relativeFilename(tok->location.file());
158+
if (settings.relativePaths) {
159+
for (const std::string & basePath : settings.basePaths) {
160+
const std::string bp = basePath + "/";
161+
if (relativeFilename.compare(0,bp.size(),bp)==0) {
162+
relativeFilename = relativeFilename.substr(bp.size());
163+
}
164+
}
165+
}
166+
return Path::simplifyPath(relativeFilename);
167+
}
168+
156169
static void addInlineSuppressions(const simplecpp::TokenList &tokens, const Settings &settings, SuppressionList &suppressions, std::list<BadInlineSuppression> &bad)
157170
{
158171
std::list<SuppressionList::Suppression> inlineSuppressionsBlockBegin;
@@ -193,16 +206,7 @@ static void addInlineSuppressions(const simplecpp::TokenList &tokens, const Sett
193206
continue;
194207

195208
// Relative filename
196-
std::string relativeFilename(tok->location.file());
197-
if (settings.relativePaths) {
198-
for (const std::string & basePath : settings.basePaths) {
199-
const std::string bp = basePath + "/";
200-
if (relativeFilename.compare(0,bp.size(),bp)==0) {
201-
relativeFilename = relativeFilename.substr(bp.size());
202-
}
203-
}
204-
}
205-
relativeFilename = Path::simplifyPath(relativeFilename);
209+
const std::string relativeFilename = getRelativeFilename(tok, settings);
206210

207211
// Macro name
208212
std::string macroName;
@@ -295,6 +299,17 @@ void Preprocessor::inlineSuppressions(const simplecpp::TokenList &tokens, Suppre
295299
}
296300
}
297301

302+
std::vector<RemarkComment> Preprocessor::getRemarkComments(const simplecpp::TokenList &tokens) const
303+
{
304+
std::vector<RemarkComment> ret;
305+
addRemarkComments(tokens, ret);
306+
for (std::map<std::string,simplecpp::TokenList*>::const_iterator it = mTokenLists.cbegin(); it != mTokenLists.cend(); ++it) {
307+
if (it->second)
308+
addRemarkComments(*it->second, ret);
309+
}
310+
return ret;
311+
}
312+
298313
std::list<Directive> Preprocessor::createDirectives(const simplecpp::TokenList &tokens) const
299314
{
300315
// directive list..
@@ -998,3 +1013,52 @@ void Preprocessor::simplifyPragmaAsmPrivate(simplecpp::TokenList *tokenList)
9981013
tokenList->deleteToken(tok4->next);
9991014
}
10001015
}
1016+
1017+
1018+
void Preprocessor::addRemarkComments(const simplecpp::TokenList &tokens, std::vector<RemarkComment> &remarkComments) const
1019+
{
1020+
for (const simplecpp::Token *tok = tokens.cfront(); tok; tok = tok->next) {
1021+
if (!tok->comment)
1022+
continue;
1023+
1024+
const std::string& comment = tok->str();
1025+
1026+
// is it a remark comment?
1027+
const std::string::size_type pos1 = comment.find_first_not_of("/* \t");
1028+
if (pos1 == std::string::npos)
1029+
continue;
1030+
const std::string::size_type pos2 = comment.find_first_of(": \t", pos1);
1031+
if (pos2 != pos1 + 6 || comment.compare(pos1, 6, "REMARK") != 0)
1032+
continue;
1033+
const std::string::size_type pos3 = comment.find_first_not_of(": \t", pos2);
1034+
if (pos3 == std::string::npos)
1035+
continue;
1036+
if (comment.compare(0,2,"/*") == 0 && pos3 + 2 >= tok->str().size())
1037+
continue;
1038+
1039+
const std::string::size_type pos4 = (comment.compare(0,2,"/*") == 0) ? comment.size()-2 : comment.size();
1040+
const std::string remarkText = comment.substr(pos3, pos4-pos3);
1041+
1042+
// Get remarked token
1043+
const simplecpp::Token* remarkedToken = nullptr;
1044+
for (const simplecpp::Token* after = tok->next; after; after = after->next) {
1045+
if (after->comment)
1046+
continue;
1047+
remarkedToken = after;
1048+
break;
1049+
}
1050+
for (const simplecpp::Token* prev = tok->previous; prev; prev = prev->previous) {
1051+
if (prev->comment)
1052+
continue;
1053+
if (sameline(prev, tok))
1054+
remarkedToken = prev;
1055+
break;
1056+
}
1057+
1058+
// Relative filename
1059+
const std::string relativeFilename = getRelativeFilename(remarkedToken, mSettings);
1060+
1061+
// Add the suppressions.
1062+
remarkComments.emplace_back(relativeFilename, remarkedToken->location.line, remarkText);
1063+
}
1064+
}

Diff for: lib/preprocessor.h

+22
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,24 @@ struct CPPCHECKLIB Directive {
6060
Directive(std::string _file, const int _linenr, const std::string &_str);
6161
};
6262

63+
class CPPCHECKLIB RemarkComment {
64+
public:
65+
RemarkComment(std::string file, unsigned int lineNumber, std::string str)
66+
: file(std::move(file))
67+
, lineNumber(lineNumber)
68+
, str(std::move(str))
69+
{}
70+
71+
/** name of file */
72+
std::string file;
73+
74+
/** line number for the code that the remark comment is about */
75+
unsigned int lineNumber;
76+
77+
/** remark text */
78+
std::string str;
79+
};
80+
6381
/// @addtogroup Core
6482
/// @{
6583

@@ -96,6 +114,8 @@ class CPPCHECKLIB WARN_UNUSED Preprocessor {
96114

97115
std::set<std::string> getConfigs(const simplecpp::TokenList &tokens) const;
98116

117+
std::vector<RemarkComment> getRemarkComments(const simplecpp::TokenList &tokens) const;
118+
99119
void handleErrors(const simplecpp::OutputList &outputList, bool throwError);
100120

101121
bool loadFiles(const simplecpp::TokenList &rawtokens, std::vector<std::string> &files);
@@ -138,6 +158,8 @@ class CPPCHECKLIB WARN_UNUSED Preprocessor {
138158

139159
static bool hasErrors(const simplecpp::OutputList &outputList);
140160

161+
void addRemarkComments(const simplecpp::TokenList &tokens, std::vector<RemarkComment> &remarkComments) const;
162+
141163
const Settings& mSettings;
142164
ErrorLogger &mErrorLogger;
143165

0 commit comments

Comments
 (0)