Tokenizer::simplifyAttribute; Set function attribute for function pointer

This commit is contained in:
Daniel Marjamäki 2021-06-26 14:23:39 +02:00
parent 66956ed959
commit 2a2e071a85
3 changed files with 25 additions and 6 deletions

View File

@ -10903,6 +10903,8 @@ void Tokenizer::simplifyAttribute()
prev = prev->previous();
if (Token::simpleMatch(prev, ")") && Token::Match(prev->link()->previous(), "%name% ("))
functok = prev->link()->previous();
else if ((!prev || Token::Match(prev, "[;{}*]")) && Token::Match(tok->previous(), "%name%"))
functok = tok->previous();
}
for (Token *attr = tok->tokAt(2); attr->str() != ")"; attr = attr->next()) {

View File

@ -4151,9 +4151,9 @@ static void valueFlowForwardAssign(Token* const tok,
}
static std::list<ValueFlow::Value> truncateValues(std::list<ValueFlow::Value> values,
const ValueType* dst,
const ValueType* src,
const Settings* settings)
const ValueType* dst,
const ValueType* src,
const Settings* settings)
{
if (!dst || !dst->isIntegral())
return values;
@ -4238,7 +4238,7 @@ static void valueFlowAfterAssign(TokenList *tokenlist, SymbolDatabase* symboldat
continue;
std::list<ValueFlow::Value> values = truncateValues(
tok->astOperand2()->values(), tok->astOperand1()->valueType(), tok->astOperand2()->valueType(), settings);
tok->astOperand2()->values(), tok->astOperand1()->valueType(), tok->astOperand2()->valueType(), settings);
// Remove known values
std::set<ValueFlow::Value::ValueType> types;
if (tok->astOperand1()->hasKnownValue()) {

View File

@ -255,7 +255,8 @@ private:
TEST_CASE(removedeclspec);
TEST_CASE(removeattribute);
TEST_CASE(functionAttributeBefore);
TEST_CASE(functionAttributeBefore1);
TEST_CASE(functionAttributeBefore2);
TEST_CASE(functionAttributeAfter);
TEST_CASE(functionAttributeListBefore);
TEST_CASE(functionAttributeListAfter);
@ -3506,7 +3507,7 @@ private:
ASSERT_EQUALS("struct Payload_IR_config { uint8_t tap [ 16 ] ; } ;", tokenizeAndStringify("struct __attribute__((packed, gcc_struct)) Payload_IR_config { uint8_t tap[16]; };"));
}
void functionAttributeBefore() {
void functionAttributeBefore1() {
const char code[] = "void __attribute__((pure)) __attribute__((nothrow)) __attribute__((const)) func1();\n"
"void __attribute__((__pure__)) __attribute__((__nothrow__)) __attribute__((__const__)) func2();\n"
"void __attribute__((nothrow)) __attribute__((pure)) __attribute__((const)) func3();\n"
@ -3537,6 +3538,22 @@ private:
ASSERT(func5 && func5->isAttributeNoreturn());
}
void functionAttributeBefore2() {
const char code[] = "extern vas_f *VAS_Fail __attribute__((__noreturn__));";
const char expected[] = "extern vas_f * VAS_Fail ;";
errout.str("");
// tokenize..
Tokenizer tokenizer(&settings0, this);
std::istringstream istr(code);
tokenizer.tokenize(istr, "test.cpp");
ASSERT_EQUALS(expected, tokenizer.tokens()->stringifyList(nullptr, false));
const Token * VAS_Fail = Token::findsimplematch(tokenizer.tokens(), "VAS_Fail");
ASSERT(VAS_Fail && VAS_Fail->isAttributeNoreturn());
}
void functionAttributeAfter() {
const char code[] = "void func1() __attribute__((pure)) __attribute__((nothrow)) __attribute__((const));\n"
"void func2() __attribute__((__pure__)) __attribute__((__nothrow__)) __attribute__((__const__));\n"