Fixed #6350 (Tokenizer::simplifyCast: set Token::isCasted when cast is removed)
This commit is contained in:
parent
95940ff0ef
commit
1b2a23b3fe
|
@ -841,7 +841,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const ArrayInfo &arrayInfo
|
|||
valueFlowCheckArrayIndex(tok->next(), arrayInfo);
|
||||
}
|
||||
|
||||
else if (isPortabilityEnabled && tok->astParent() && tok->astParent()->str() == "+") {
|
||||
else if (isPortabilityEnabled && !tok->isCasted() && tok->astParent() && tok->astParent()->str() == "+") {
|
||||
const ValueFlow::Value *index;
|
||||
if (tok == tok->astParent()->astOperand1())
|
||||
index = tok->astParent()->astOperand2()->getMaxValue(false);
|
||||
|
|
23
lib/token.h
23
lib/token.h
|
@ -313,6 +313,12 @@ public:
|
|||
void isExpandedMacro(bool m) {
|
||||
setFlag(fIsExpandedMacro, m);
|
||||
}
|
||||
bool isCasted() const {
|
||||
return getFlag(fIsCasted);
|
||||
}
|
||||
void isCasted(bool c) {
|
||||
setFlag(fIsCasted, c);
|
||||
}
|
||||
bool isAttributeConstructor() const {
|
||||
return getFlag(fIsAttributeConstructor);
|
||||
}
|
||||
|
@ -753,14 +759,15 @@ private:
|
|||
fIsLong = (1 << 3),
|
||||
fIsStandardType = (1 << 4),
|
||||
fIsExpandedMacro = (1 << 5),
|
||||
fIsAttributeConstructor = (1 << 6), // __attribute__((constructor)) __attribute__((constructor(priority)))
|
||||
fIsAttributeDestructor = (1 << 7), // __attribute__((destructor)) __attribute__((destructor(priority)))
|
||||
fIsAttributeUnused = (1 << 8), // __attribute__((unused))
|
||||
fIsAttributePure = (1 << 9), // __attribute__((pure))
|
||||
fIsAttributeConst = (1 << 10), // __attribute__((const))
|
||||
fIsAttributeNothrow = (1 << 11), // __attribute__((nothrow))
|
||||
fIsDeclspecNothrow = (1 << 12), // __declspec(nothrow)
|
||||
fIsAttributeUsed = (1 << 13) // __attribute__((used))
|
||||
fIsCasted = (1 << 6),
|
||||
fIsAttributeConstructor = (1 << 7), // __attribute__((constructor)) __attribute__((constructor(priority)))
|
||||
fIsAttributeDestructor = (1 << 8), // __attribute__((destructor)) __attribute__((destructor(priority)))
|
||||
fIsAttributeUnused = (1 << 9), // __attribute__((unused))
|
||||
fIsAttributePure = (1 << 10), // __attribute__((pure))
|
||||
fIsAttributeConst = (1 << 11), // __attribute__((const))
|
||||
fIsAttributeNothrow = (1 << 12), // __attribute__((nothrow))
|
||||
fIsDeclspecNothrow = (1 << 13), // __declspec(nothrow)
|
||||
fIsAttributeUsed = (1 << 14) // __attribute__((used))
|
||||
};
|
||||
|
||||
unsigned int _flags;
|
||||
|
|
|
@ -5004,6 +5004,7 @@ void Tokenizer::simplifyCasts()
|
|||
if (!tok->tokAt(2)->isUnsigned() && bits > 0)
|
||||
bits--;
|
||||
if (bits < 31 && value >= 0 && value < (1LL << bits)) {
|
||||
tok->linkAt(1)->next()->isCasted(true);
|
||||
Token::eraseTokens(tok, tok->next()->link()->next());
|
||||
}
|
||||
continue;
|
||||
|
@ -5023,6 +5024,15 @@ void Tokenizer::simplifyCasts()
|
|||
// Remove cast..
|
||||
Token::eraseTokens(tok, tok->next()->link()->next());
|
||||
|
||||
// Set isCasted flag.
|
||||
Token *tok2 = tok->next();
|
||||
if (!Token::Match(tok2, "%var% [|."))
|
||||
tok2->isCasted(true);
|
||||
else {
|
||||
// TODO: handle more complex expressions
|
||||
tok2->next()->isCasted(true);
|
||||
}
|
||||
|
||||
// Remove '* &'
|
||||
if (Token::simpleMatch(tok, "* &")) {
|
||||
tok->deleteNext();
|
||||
|
@ -5038,6 +5048,7 @@ void Tokenizer::simplifyCasts()
|
|||
|
||||
// Replace pointer casts of 0.. "(char *)0" => "0"
|
||||
while (Token::Match(tok->next(), "( %type% %type%| * ) 0")) {
|
||||
tok->linkAt(1)->next()->isCasted(true);
|
||||
Token::eraseTokens(tok, tok->next()->link()->next());
|
||||
if (tok->str() == ")" && tok->link()->previous()) {
|
||||
// If there was another cast before this, go back
|
||||
|
@ -5048,11 +5059,11 @@ void Tokenizer::simplifyCasts()
|
|||
|
||||
if (Token::Match(tok->next(), "dynamic_cast|reinterpret_cast|const_cast|static_cast <")) {
|
||||
Token *tok2 = tok->linkAt(2);
|
||||
|
||||
if (Token::simpleMatch(tok2, "> ("))
|
||||
Token::eraseTokens(tok, tok2->next());
|
||||
else
|
||||
if (!Token::simpleMatch(tok2, "> ("))
|
||||
break;
|
||||
|
||||
tok2->tokAt(2)->isCasted(true);
|
||||
Token::eraseTokens(tok, tok2->next());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2955,6 +2955,12 @@ private:
|
|||
" return a + 100;\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (portability) Undefined behaviour: Pointer arithmetic result does not point into or just past the end of the array.\n", errout.str());
|
||||
|
||||
check("void f() {\n" // #6350 - fp when there is cast of buffer
|
||||
" wchar_t buf[64];\n"
|
||||
" p = (unsigned char *) buf + sizeof (buf);\n"
|
||||
"}", false, "6350.c", false);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void pointer_out_of_bounds_2() {
|
||||
|
|
Loading…
Reference in New Issue