Fixed #10196 ("Unhandled char constant 'x'" with non-standard escape character)
This commit is contained in:
parent
0a84ad874c
commit
abb4200316
|
@ -835,7 +835,8 @@ unsigned int CppCheck::checkFile(const std::string& filename, const std::string
|
||||||
ErrorMessage::FileLocation loc(tokenizer.list.getSourceFilePath(), 0, 0);
|
ErrorMessage::FileLocation loc(tokenizer.list.getSourceFilePath(), 0, 0);
|
||||||
ErrorMessage::FileLocation loc2(filename, 0, 0);
|
ErrorMessage::FileLocation loc2(filename, 0, 0);
|
||||||
locationList.push_back(loc2);
|
locationList.push_back(loc2);
|
||||||
locationList.push_back(loc);
|
if (filename != tokenizer.list.getSourceFilePath())
|
||||||
|
locationList.push_back(loc);
|
||||||
}
|
}
|
||||||
ErrorMessage errmsg(locationList,
|
ErrorMessage errmsg(locationList,
|
||||||
tokenizer.list.getSourceFilePath(),
|
tokenizer.list.getSourceFilePath(),
|
||||||
|
|
|
@ -505,13 +505,8 @@ MathLib::bigint MathLib::toLongNumber(const std::string & str)
|
||||||
return static_cast<bigint>(doubleval);
|
return static_cast<bigint>(doubleval);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isCharLiteral(str)) {
|
if (isCharLiteral(str))
|
||||||
try {
|
return simplecpp::characterLiteralToLL(str);
|
||||||
return simplecpp::characterLiteralToLL(str);
|
|
||||||
} catch (const std::exception& e) {
|
|
||||||
throw InternalError(nullptr, "Internal Error. MathLib::toLongNumber: characterLiteralToLL(" + str + ") => " + e.what());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const biguint ret = std::stoull(str, nullptr, 10);
|
const biguint ret = std::stoull(str, nullptr, 10);
|
||||||
|
|
|
@ -2766,6 +2766,19 @@ bool Tokenizer::simplifyTokens1(const std::string &configuration)
|
||||||
ValueFlow::setValues(&list, mSymbolDatabase, mErrorLogger, mSettings);
|
ValueFlow::setValues(&list, mSymbolDatabase, mErrorLogger, mSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Warn about unhandled character literals
|
||||||
|
if (mSettings->severity.isEnabled(Severity::information)) {
|
||||||
|
for (const Token *tok = tokens(); tok; tok = tok->next()) {
|
||||||
|
if (tok->tokType() == Token::eChar && tok->values().empty()) {
|
||||||
|
try {
|
||||||
|
simplecpp::characterLiteralToLL(tok->str());
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
unhandledCharLiteral(tok, e.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mSymbolDatabase->setArrayDimensionsUsingValueFlow();
|
mSymbolDatabase->setArrayDimensionsUsingValueFlow();
|
||||||
|
|
||||||
printDebugOutput(1);
|
printDebugOutput(1);
|
||||||
|
@ -9528,6 +9541,21 @@ void Tokenizer::cppcheckError(const Token *tok) const
|
||||||
printDebugOutput(0);
|
printDebugOutput(0);
|
||||||
throw InternalError(tok, "Analysis failed. If the code is valid then please report this failure.", InternalError::INTERNAL);
|
throw InternalError(tok, "Analysis failed. If the code is valid then please report this failure.", InternalError::INTERNAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Tokenizer::unhandledCharLiteral(const Token *tok, const std::string& msg) const
|
||||||
|
{
|
||||||
|
std::string s = tok ? (" " + tok->str()) : "";
|
||||||
|
for (int i = 0; i < s.size(); ++i) {
|
||||||
|
if ((unsigned char)s[i] >= 0x80)
|
||||||
|
s.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
reportError(tok,
|
||||||
|
Severity::information,
|
||||||
|
"cppcheckUnhandledChar",
|
||||||
|
"Character literal" + s + " is not handled. " + msg);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper function to check whether number is equal to integer constant X
|
* Helper function to check whether number is equal to integer constant X
|
||||||
* or floating point pattern X.0
|
* or floating point pattern X.0
|
||||||
|
|
|
@ -652,6 +652,8 @@ public:
|
||||||
/** Warn about unknown macro(s), configuration is recommended */
|
/** Warn about unknown macro(s), configuration is recommended */
|
||||||
NORETURN void unknownMacroError(const Token *tok1) const;
|
NORETURN void unknownMacroError(const Token *tok1) const;
|
||||||
|
|
||||||
|
void unhandledCharLiteral(const Token *tok, const std::string& msg) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/** Report that there is an unhandled "class x y {" code */
|
/** Report that there is an unhandled "class x y {" code */
|
||||||
|
|
|
@ -913,10 +913,14 @@ size_t ValueFlow::getSizeOf(const ValueType &vt, const Settings *settings)
|
||||||
static Token * valueFlowSetConstantValue(Token *tok, const Settings *settings, bool cpp)
|
static Token * valueFlowSetConstantValue(Token *tok, const Settings *settings, bool cpp)
|
||||||
{
|
{
|
||||||
if ((tok->isNumber() && MathLib::isInt(tok->str())) || (tok->tokType() == Token::eChar)) {
|
if ((tok->isNumber() && MathLib::isInt(tok->str())) || (tok->tokType() == Token::eChar)) {
|
||||||
ValueFlow::Value value(MathLib::toLongNumber(tok->str()));
|
try {
|
||||||
if (!tok->isTemplateArg())
|
ValueFlow::Value value(MathLib::toLongNumber(tok->str()));
|
||||||
value.setKnown();
|
if (!tok->isTemplateArg())
|
||||||
setTokenValue(tok, value, settings);
|
value.setKnown();
|
||||||
|
setTokenValue(tok, value, settings);
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
// Bad character literal
|
||||||
|
}
|
||||||
} else if (tok->isNumber() && MathLib::isFloat(tok->str())) {
|
} else if (tok->isNumber() && MathLib::isFloat(tok->str())) {
|
||||||
ValueFlow::Value value;
|
ValueFlow::Value value;
|
||||||
value.valueType = ValueFlow::Value::ValueType::FLOAT;
|
value.valueType = ValueFlow::Value::ValueType::FLOAT;
|
||||||
|
|
Loading…
Reference in New Issue