Fixed #6978 (False positive: unusedLabel shown for labels that are used in some preprocessor configurations)

This commit is contained in:
Daniel Marjamäki 2020-06-30 18:26:24 +02:00
parent 0583763cc6
commit ddd21a260f
4 changed files with 48 additions and 16 deletions

View File

@ -2637,6 +2637,7 @@ void CheckOther::checkUnusedLabel()
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
for (const Scope * scope : symbolDatabase->functionScopes) {
const bool hasIfdef = mTokenizer->hasIfdef(scope->bodyStart, scope->bodyEnd);
for (const Token* tok = scope->bodyStart; tok != scope->bodyEnd; tok = tok->next()) {
if (!tok->scope()->isExecutable())
tok = tok->scope()->bodyEnd;
@ -2644,25 +2645,35 @@ void CheckOther::checkUnusedLabel()
if (Token::Match(tok, "{|}|; %name% :") && tok->strAt(1) != "default") {
const std::string tmp("goto " + tok->strAt(1));
if (!Token::findsimplematch(scope->bodyStart->next(), tmp.c_str(), tmp.size(), scope->bodyEnd->previous()))
unusedLabelError(tok->next(), tok->next()->scope()->type == Scope::eSwitch);
unusedLabelError(tok->next(), tok->next()->scope()->type == Scope::eSwitch, hasIfdef);
}
}
}
}
void CheckOther::unusedLabelError(const Token* tok, bool inSwitch)
void CheckOther::unusedLabelError(const Token* tok, bool inSwitch, bool hasIfdef)
{
if (inSwitch) {
if (!tok || mSettings->isEnabled(Settings::WARNING))
reportError(tok, Severity::warning, "unusedLabelSwitch",
"$symbol:" + (tok ? tok->str() : emptyString) + "\n"
"Label '$symbol' is not used. Should this be a 'case' of the enclosing switch()?", CWE398, false);
} else {
if (!tok || mSettings->isEnabled(Settings::STYLE))
reportError(tok, Severity::style, "unusedLabel",
"$symbol:" + (tok ? tok->str() : emptyString) + "\n"
"Label '$symbol' is not used.", CWE398, false);
}
if (tok && !mSettings->isEnabled(inSwitch ? Settings::WARNING : Settings::STYLE))
return;
std::string id = "unusedLabel";
if (inSwitch)
id += "Switch";
if (hasIfdef)
id += "Configuration";
std::string msg = "$symbol:" + (tok ? tok->str() : emptyString) + "\nLabel '$symbol' is not used.";
if (hasIfdef)
msg += " There is #if in function body so the label might be used in code that is removed by the preprocessor.";
if (inSwitch)
msg += " Should this be a 'case' of the enclosing switch()?";
reportError(tok,
inSwitch ? Severity::warning : Severity::style,
id,
msg,
CWE398,
false);
}

View File

@ -266,7 +266,7 @@ private:
void commaSeparatedReturnError(const Token *tok);
void redundantPointerOpError(const Token* tok, const std::string& varname, bool inconclusive);
void raceAfterInterlockedDecrementError(const Token* tok);
void unusedLabelError(const Token* tok, bool inSwitch);
void unusedLabelError(const Token* tok, bool inSwitch, bool hasIfdef);
void unknownEvaluationOrder(const Token* tok);
static bool isMovedParameterAllowedForInconclusiveFunction(const Token * tok);
void accessMovedError(const Token *tok, const std::string &varname, const ValueFlow::Value *value, bool inconclusive);
@ -331,8 +331,10 @@ private:
c.nanInArithmeticExpressionError(nullptr);
c.commaSeparatedReturnError(nullptr);
c.redundantPointerOpError(nullptr, "varname", false);
c.unusedLabelError(nullptr, true);
c.unusedLabelError(nullptr, false);
c.unusedLabelError(nullptr, false, false);
c.unusedLabelError(nullptr, false, true);
c.unusedLabelError(nullptr, true, false);
c.unusedLabelError(nullptr, true, true);
c.unknownEvaluationOrder(nullptr);
c.accessMovedError(nullptr, "v", nullptr, false);
c.funcArgNamesDifferent("function", 1, nullptr, nullptr);

View File

@ -24,6 +24,7 @@
#include "library.h"
#include "mathlib.h"
#include "platform.h"
#include "preprocessor.h"
#include "settings.h"
#include "standards.h"
#include "symboldatabase.h"
@ -11773,3 +11774,19 @@ bool Tokenizer::VariableMap::hasVariable(const std::string &varname) const
{
return mVariableId.find(varname) != mVariableId.end();
}
bool Tokenizer::hasIfdef(const Token *start, const Token *end) const
{
if (!mPreprocessor)
return false;
for (const Directive &d: mPreprocessor->getDirectives()) {
if (d.str.compare(0,3,"#if") == 0 &&
d.linenr >= start->linenr() &&
d.linenr <= end->linenr() &&
start->fileIndex() < list.getFiles().size() &&
d.file == list.getFiles()[start->fileIndex()])
return true;
}
return false;
}

View File

@ -568,6 +568,8 @@ public:
return mPreprocessor;
}
bool hasIfdef(const Token *start, const Token *end) const;
private:
/**