Skip to content

Commit 7ecdb30

Browse files
committed
Fixed danmar#5771 (false positive: (warning) When using 'char' variables in bit operations, sign extension can generate unexpected results.)
1 parent 146bf11 commit 7ecdb30

File tree

2 files changed

+29
-0
lines changed

2 files changed

+29
-0
lines changed

lib/checkother.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,21 @@ static bool isOppositeCond(const Token * const cond1, const Token * const cond2,
168168
(comp1 == ">=" && comp2 == "<"));
169169
}
170170

171+
static bool isPossibleCast(const Token * const startPar)
172+
{
173+
if (!Token::Match(startPar, "( %type%"))
174+
return false;
175+
const Token *tok;
176+
for (tok = startPar->tokAt(2); tok; tok = tok->next()) {
177+
if (tok->str() == ")")
178+
return true;
179+
if (tok->varId()>0)
180+
return false;
181+
if (!Token::Match(tok,"%type%|*|&"))
182+
return false;
183+
}
184+
return tok != nullptr;
185+
}
171186

172187
//----------------------------------------------------------------------------------
173188
// The return value of fgetc(), getc(), ungetc(), getchar() etc. is an integer value.
@@ -2104,6 +2119,10 @@ void CheckOther::checkCharVariable()
21042119
else
21052120
continue;
21062121

2122+
// (x) & y => if x is a possible type then assume & is a address-of operator
2123+
if (Token::simpleMatch(tok->previous(), ") &") && isPossibleCast(tok->linkAt(-1)))
2124+
continue;
2125+
21072126
// it's ok with a bitwise and where the other operand is 0xff or less..
21082127
if (tok->str() == "&" && tok2 && tok2->isNumber() && MathLib::isGreater("0x100", tok2->str()))
21092128
continue;

test/testcharvar.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ class TestCharVar : public TestFixture {
3939
TEST_CASE(bitop1);
4040
TEST_CASE(bitop2);
4141
TEST_CASE(bitop3);
42+
TEST_CASE(bitop4); // (long)&c
4243
TEST_CASE(return1);
4344
TEST_CASE(assignChar);
4445
TEST_CASE(and03);
@@ -160,6 +161,15 @@ class TestCharVar : public TestFixture {
160161
ASSERT_EQUALS("[test.cpp:2]: (warning) When using 'char' variables in bit operations, sign extension can generate unexpected results.\n", errout.str());
161162
}
162163

164+
void bitop4() {
165+
check("long f(char c) {\n"
166+
" long a;\n"
167+
" a = (long)&c;\n"
168+
" return a;\n"
169+
"}");
170+
ASSERT_EQUALS("", errout.str());
171+
}
172+
163173
void return1() {
164174
check("void foo()\n"
165175
"{\n"

0 commit comments

Comments
 (0)