Tokenizer::simplifyAttribute; Set function attribute for function pointer
This commit is contained in:
parent
66956ed959
commit
2a2e071a85
|
@ -10903,6 +10903,8 @@ void Tokenizer::simplifyAttribute()
|
||||||
prev = prev->previous();
|
prev = prev->previous();
|
||||||
if (Token::simpleMatch(prev, ")") && Token::Match(prev->link()->previous(), "%name% ("))
|
if (Token::simpleMatch(prev, ")") && Token::Match(prev->link()->previous(), "%name% ("))
|
||||||
functok = prev->link()->previous();
|
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()) {
|
for (Token *attr = tok->tokAt(2); attr->str() != ")"; attr = attr->next()) {
|
||||||
|
|
|
@ -4151,9 +4151,9 @@ static void valueFlowForwardAssign(Token* const tok,
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::list<ValueFlow::Value> truncateValues(std::list<ValueFlow::Value> values,
|
static std::list<ValueFlow::Value> truncateValues(std::list<ValueFlow::Value> values,
|
||||||
const ValueType* dst,
|
const ValueType* dst,
|
||||||
const ValueType* src,
|
const ValueType* src,
|
||||||
const Settings* settings)
|
const Settings* settings)
|
||||||
{
|
{
|
||||||
if (!dst || !dst->isIntegral())
|
if (!dst || !dst->isIntegral())
|
||||||
return values;
|
return values;
|
||||||
|
@ -4238,7 +4238,7 @@ static void valueFlowAfterAssign(TokenList *tokenlist, SymbolDatabase* symboldat
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
std::list<ValueFlow::Value> values = truncateValues(
|
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
|
// Remove known values
|
||||||
std::set<ValueFlow::Value::ValueType> types;
|
std::set<ValueFlow::Value::ValueType> types;
|
||||||
if (tok->astOperand1()->hasKnownValue()) {
|
if (tok->astOperand1()->hasKnownValue()) {
|
||||||
|
|
|
@ -255,7 +255,8 @@ private:
|
||||||
|
|
||||||
TEST_CASE(removedeclspec);
|
TEST_CASE(removedeclspec);
|
||||||
TEST_CASE(removeattribute);
|
TEST_CASE(removeattribute);
|
||||||
TEST_CASE(functionAttributeBefore);
|
TEST_CASE(functionAttributeBefore1);
|
||||||
|
TEST_CASE(functionAttributeBefore2);
|
||||||
TEST_CASE(functionAttributeAfter);
|
TEST_CASE(functionAttributeAfter);
|
||||||
TEST_CASE(functionAttributeListBefore);
|
TEST_CASE(functionAttributeListBefore);
|
||||||
TEST_CASE(functionAttributeListAfter);
|
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]; };"));
|
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"
|
const char code[] = "void __attribute__((pure)) __attribute__((nothrow)) __attribute__((const)) func1();\n"
|
||||||
"void __attribute__((__pure__)) __attribute__((__nothrow__)) __attribute__((__const__)) func2();\n"
|
"void __attribute__((__pure__)) __attribute__((__nothrow__)) __attribute__((__const__)) func2();\n"
|
||||||
"void __attribute__((nothrow)) __attribute__((pure)) __attribute__((const)) func3();\n"
|
"void __attribute__((nothrow)) __attribute__((pure)) __attribute__((const)) func3();\n"
|
||||||
|
@ -3537,6 +3538,22 @@ private:
|
||||||
ASSERT(func5 && func5->isAttributeNoreturn());
|
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() {
|
void functionAttributeAfter() {
|
||||||
const char code[] = "void func1() __attribute__((pure)) __attribute__((nothrow)) __attribute__((const));\n"
|
const char code[] = "void func1() __attribute__((pure)) __attribute__((nothrow)) __attribute__((const));\n"
|
||||||
"void func2() __attribute__((__pure__)) __attribute__((__nothrow__)) __attribute__((__const__));\n"
|
"void func2() __attribute__((__pure__)) __attribute__((__nothrow__)) __attribute__((__const__));\n"
|
||||||
|
|
Loading…
Reference in New Issue