Skip to content

Commit e8435b9

Browse files
pfultz2danmar
authored andcommitted
Fix issue 9306: Adjust shiftTooManyBitsSigned for C++14 (#2127)
1 parent 1a25d3f commit e8435b9

2 files changed

Lines changed: 19 additions & 4 deletions

File tree

lib/checktype.cpp

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ void CheckType::checkTooBigBitwiseShift()
5757
if (mSettings->platformType == Settings::Unspecified)
5858
return;
5959

60+
const bool cpp14 = mSettings->standards.cpp >= Standards::CPP14;
61+
62+
if (cpp14 && !mSettings->isEnabled(Settings::PORTABILITY))
63+
return;
64+
6065
for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) {
6166
// C++ and macro: OUT(x<<y)
6267
if (mTokenizer->isCPP() && Token::Match(tok, "[;{}] %name% (") && Token::simpleMatch(tok->linkAt(2), ") ;") && tok->next()->isUpperCaseName() && !tok->next()->function())
@@ -91,7 +96,7 @@ void CheckType::checkTooBigBitwiseShift()
9196

9297
// Get biggest rhs value. preferably a value which doesn't have 'condition'.
9398
const ValueFlow::Value * value = tok->astOperand2()->getValueGE(lhsbits, mSettings);
94-
if (value && mSettings->isEnabled(value, false))
99+
if (value && mSettings->isEnabled(value, false) && !cpp14)
95100
tooBigBitwiseShiftError(tok, lhsbits, *value);
96101
else if (lhstype->sign == ValueType::Sign::SIGNED) {
97102
value = tok->astOperand2()->getValueGE(lhsbits-1, mSettings);
@@ -124,19 +129,28 @@ void CheckType::tooBigSignedBitwiseShiftError(const Token *tok, int lhsbits, con
124129
{
125130
const char id[] = "shiftTooManyBitsSigned";
126131

132+
const bool cpp14 = mSettings->standards.cpp >= Standards::CPP14;
133+
134+
std::string behaviour = "undefined";
135+
if (cpp14)
136+
behaviour = "implementation-defined";
127137
if (!tok) {
128-
reportError(tok, Severity::error, id, "Shifting signed 32-bit value by 31 bits is undefined behaviour", CWE758, false);
138+
reportError(tok, Severity::error, id, "Shifting signed 32-bit value by 31 bits is " + behaviour + " behaviour", CWE758, false);
129139
return;
130140
}
131141

132142
const ErrorPath errorPath = getErrorPath(tok, &rhsbits, "Shift");
133143

134144
std::ostringstream errmsg;
135-
errmsg << "Shifting signed " << lhsbits << "-bit value by " << rhsbits.intvalue << " bits is undefined behaviour";
145+
errmsg << "Shifting signed " << lhsbits << "-bit value by " << rhsbits.intvalue << " bits is " + behaviour + " behaviour";
136146
if (rhsbits.condition)
137147
errmsg << ". See condition at line " << rhsbits.condition->linenr() << ".";
138148

139-
reportError(errorPath, rhsbits.errorSeverity() ? Severity::error : Severity::warning, id, errmsg.str(), CWE758, rhsbits.isInconclusive());
149+
Severity::SeverityType severity = rhsbits.errorSeverity() ? Severity::error : Severity::warning;
150+
if (cpp14)
151+
severity = Severity::portability;
152+
153+
reportError(errorPath, severity, id, errmsg.str(), CWE758, rhsbits.isInconclusive());
140154
}
141155

142156
//---------------------------------------------------------------------------

test/testtype.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ class TestType : public TestFixture {
5050
settings = &_settings;
5151
}
5252
settings->addEnabled("warning");
53+
settings->standards.setCPP("c++11");
5354

5455
// Tokenize..
5556
Tokenizer tokenizer(settings, this);

0 commit comments

Comments
 (0)