This commit is contained in:
parent
aa6df06f43
commit
2b74a2084e
|
@ -695,6 +695,15 @@ namespace {
|
|||
mRangeAfterVar.second = mEndToken;
|
||||
return;
|
||||
}
|
||||
if (Token::Match(type, "%name% (") && Token::simpleMatch(type->linkAt(1), ") ;") && !type->isStandardType()) {
|
||||
mNameToken = type;
|
||||
mEndToken = type->linkAt(1)->next();
|
||||
mRangeType.first = start;
|
||||
mRangeType.second = type;
|
||||
mRangeAfterVar.first = mNameToken->next();
|
||||
mRangeAfterVar.second = mEndToken;
|
||||
return;
|
||||
}
|
||||
}
|
||||
// TODO: handle all typedefs
|
||||
if ((false))
|
||||
|
@ -710,6 +719,15 @@ namespace {
|
|||
return mUsed;
|
||||
}
|
||||
|
||||
bool isInvalidConstFunctionType(const std::map<std::string, TypedefSimplifier>& m) const {
|
||||
if (!Token::Match(mTypedefToken, "typedef const %name% %name% ;"))
|
||||
return false;
|
||||
const auto it = m.find(mTypedefToken->strAt(2));
|
||||
if (it == m.end())
|
||||
return false;
|
||||
return Token::Match(it->second.mNameToken, "%name% (");
|
||||
}
|
||||
|
||||
bool fail() const {
|
||||
return mFail;
|
||||
}
|
||||
|
@ -823,6 +841,15 @@ namespace {
|
|||
Token *after = tok3;
|
||||
while (Token::Match(after, "%name%|*|&|&&|::"))
|
||||
after = after->next();
|
||||
if (Token::Match(mNameToken, "%name% (") && Token::simpleMatch(tok3->next(), "*")) {
|
||||
while (Token::Match(after, "(|["))
|
||||
after = after->link()->next();
|
||||
if (after) {
|
||||
tok3->insertToken("(");
|
||||
after->previous()->insertToken(")");
|
||||
Token::createMutualLinks(tok3->next(), after->previous());
|
||||
}
|
||||
}
|
||||
|
||||
bool useAfterVarRange = true;
|
||||
if (Token::simpleMatch(mRangeAfterVar.first, "[")) {
|
||||
|
@ -920,6 +947,8 @@ namespace {
|
|||
return true;
|
||||
if (Token::Match(tok->previous(), "; %name% ;"))
|
||||
return false;
|
||||
if (Token::Match(tok->previous(), "<|, %name% * ,|>"))
|
||||
return true;
|
||||
for (const Token* after = tok->next(); after; after = after->next()) {
|
||||
if (Token::Match(after, "%name%|::|&|*|&&"))
|
||||
continue;
|
||||
|
@ -1014,6 +1043,9 @@ void Tokenizer::simplifyTypedef()
|
|||
if (indentlevel == 0 && tok->str() == "typedef") {
|
||||
TypedefSimplifier ts(tok, typeNum);
|
||||
if (!ts.fail() && numberOfTypedefs[ts.name()] == 1) {
|
||||
if (mSettings->severity.isEnabled(Severity::portability) && ts.isInvalidConstFunctionType(typedefs))
|
||||
reportError(tok->next(), Severity::portability, "invalidConstFunctionType",
|
||||
"It is unspecified behavior to const qualify a function type.");
|
||||
typedefs.emplace(ts.name(), ts);
|
||||
if (!ts.isStructEtc())
|
||||
tok = ts.endToken();
|
||||
|
|
|
@ -42,7 +42,7 @@ public:
|
|||
private:
|
||||
// If there are unused templates, keep those
|
||||
const Settings settings0 = settingsBuilder().severity(Severity::style).checkUnusedTemplates().build();
|
||||
const Settings settings1 = settingsBuilder().checkUnusedTemplates().build();
|
||||
const Settings settings1 = settingsBuilder().severity(Severity::portability).checkUnusedTemplates().build();
|
||||
const Settings settings2 = settingsBuilder().severity(Severity::style).checkUnusedTemplates().build();
|
||||
|
||||
void run() override {
|
||||
|
@ -57,6 +57,9 @@ private:
|
|||
TEST_CASE(cstruct3);
|
||||
TEST_CASE(cstruct3);
|
||||
TEST_CASE(cstruct4);
|
||||
TEST_CASE(cfunction1);
|
||||
TEST_CASE(cfunction2);
|
||||
TEST_CASE(cfunction3);
|
||||
TEST_CASE(cfp1);
|
||||
TEST_CASE(cfp2);
|
||||
TEST_CASE(cfp4);
|
||||
|
@ -382,6 +385,26 @@ private:
|
|||
ASSERT_EQUALS("struct s { int a ; int b ; } ; struct s x { } ;", simplifyTypedefC(code));
|
||||
}
|
||||
|
||||
void cfunction1() {
|
||||
const char code[] = "typedef int callback(int);\n"
|
||||
"callback* cb;";
|
||||
ASSERT_EQUALS("int ( * cb ) ( int ) ;", simplifyTypedefC(code));
|
||||
}
|
||||
|
||||
void cfunction2() {
|
||||
const char code[] = "typedef int callback(int);\n"
|
||||
"typedef callback* callbackPtr;\n"
|
||||
"callbackPtr cb;";
|
||||
ASSERT_EQUALS("int ( * cb ) ( int ) ;", simplifyTypedefC(code));
|
||||
}
|
||||
|
||||
void cfunction3() {
|
||||
const char code[] = "typedef int f(int);\n"
|
||||
"typedef const f cf;\n";
|
||||
simplifyTypedefC(code);
|
||||
ASSERT_EQUALS("[file.c:2]: (portability) It is unspecified behavior to const qualify a function type.\n", errout.str());
|
||||
}
|
||||
|
||||
void cfp1() {
|
||||
const char code[] = "typedef void (*fp)(void * p);\n"
|
||||
"fp x;";
|
||||
|
@ -3532,7 +3555,7 @@ private:
|
|||
"func7 f7;";
|
||||
|
||||
// The expected result..
|
||||
const char expected[] = "; C f1 ( ) ; "
|
||||
const char expected[] = "C f1 ( ) ; "
|
||||
"C ( * f2 ) ( ) ; "
|
||||
"C ( & f3 ) ( ) ; "
|
||||
"C ( * f4 ) ( ) ; "
|
||||
|
@ -3561,7 +3584,7 @@ private:
|
|||
|
||||
// The expected result..
|
||||
// C const -> const C
|
||||
const char expected[] = "; const C f1 ( ) ; "
|
||||
const char expected[] = "const C f1 ( ) ; "
|
||||
"const C ( * f2 ) ( ) ; "
|
||||
"const C ( & f3 ) ( ) ; "
|
||||
"const C ( * f4 ) ( ) ; "
|
||||
|
@ -3589,7 +3612,7 @@ private:
|
|||
"func7 f7;";
|
||||
|
||||
// The expected result..
|
||||
const char expected[] = "; const C f1 ( ) ; "
|
||||
const char expected[] = "const C f1 ( ) ; "
|
||||
"const C ( * f2 ) ( ) ; "
|
||||
"const C ( & f3 ) ( ) ; "
|
||||
"const C ( * f4 ) ( ) ; "
|
||||
|
@ -3617,7 +3640,7 @@ private:
|
|||
"func7 f7;";
|
||||
|
||||
// The expected result..
|
||||
const char expected[] = "; C * f1 ( ) ; "
|
||||
const char expected[] = "C * f1 ( ) ; "
|
||||
"C * ( * f2 ) ( ) ; "
|
||||
"C * ( & f3 ) ( ) ; "
|
||||
"C * ( * f4 ) ( ) ; "
|
||||
|
@ -3645,7 +3668,7 @@ private:
|
|||
"func7 f7;";
|
||||
|
||||
// The expected result..
|
||||
const char expected[] = "; const C * f1 ( ) ; "
|
||||
const char expected[] = "const C * f1 ( ) ; "
|
||||
"const C * ( * f2 ) ( ) ; "
|
||||
"const C * ( & f3 ) ( ) ; "
|
||||
"const C * ( * f4 ) ( ) ; "
|
||||
|
@ -3674,7 +3697,7 @@ private:
|
|||
|
||||
// The expected result..
|
||||
// C const -> const C
|
||||
const char expected[] = "; const C * f1 ( ) ; "
|
||||
const char expected[] = "const C * f1 ( ) ; "
|
||||
"const C * ( * f2 ) ( ) ; "
|
||||
"const C * ( & f3 ) ( ) ; "
|
||||
"const C * ( * f4 ) ( ) ; "
|
||||
|
|
|
@ -3599,7 +3599,7 @@ private:
|
|||
ASSERT_EQUALS("unsigned int ( * f ) ( ) ;", tokenizeAndStringify("unsigned int (*f)();"));
|
||||
ASSERT_EQUALS("unsigned int * ( * f ) ( ) ;", tokenizeAndStringify("unsigned int * (*f)();"));
|
||||
ASSERT_EQUALS("void ( * f [ 2 ] ) ( ) ;", tokenizeAndStringify("void (*f[2])();"));
|
||||
TODO_ASSERT_EQUALS("void ( * f [ 2 ] ) ( ) ;", "void ( * f ) ( void ) [ 2 ] ;", tokenizeAndStringify("typedef void func_t(void); func_t *f[2];"));
|
||||
ASSERT_EQUALS("void ( * f [ 2 ] ) ( void ) ;", tokenizeAndStringify("typedef void func_t(void); func_t *f[2];"));
|
||||
}
|
||||
|
||||
void simplifyFunctionPointers2() {
|
||||
|
|
Loading…
Reference in New Issue