This commit is contained in:
parent
aa6df06f43
commit
2b74a2084e
|
@ -695,6 +695,15 @@ namespace {
|
||||||
mRangeAfterVar.second = mEndToken;
|
mRangeAfterVar.second = mEndToken;
|
||||||
return;
|
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
|
// TODO: handle all typedefs
|
||||||
if ((false))
|
if ((false))
|
||||||
|
@ -710,6 +719,15 @@ namespace {
|
||||||
return mUsed;
|
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 {
|
bool fail() const {
|
||||||
return mFail;
|
return mFail;
|
||||||
}
|
}
|
||||||
|
@ -823,6 +841,15 @@ namespace {
|
||||||
Token *after = tok3;
|
Token *after = tok3;
|
||||||
while (Token::Match(after, "%name%|*|&|&&|::"))
|
while (Token::Match(after, "%name%|*|&|&&|::"))
|
||||||
after = after->next();
|
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;
|
bool useAfterVarRange = true;
|
||||||
if (Token::simpleMatch(mRangeAfterVar.first, "[")) {
|
if (Token::simpleMatch(mRangeAfterVar.first, "[")) {
|
||||||
|
@ -920,6 +947,8 @@ namespace {
|
||||||
return true;
|
return true;
|
||||||
if (Token::Match(tok->previous(), "; %name% ;"))
|
if (Token::Match(tok->previous(), "; %name% ;"))
|
||||||
return false;
|
return false;
|
||||||
|
if (Token::Match(tok->previous(), "<|, %name% * ,|>"))
|
||||||
|
return true;
|
||||||
for (const Token* after = tok->next(); after; after = after->next()) {
|
for (const Token* after = tok->next(); after; after = after->next()) {
|
||||||
if (Token::Match(after, "%name%|::|&|*|&&"))
|
if (Token::Match(after, "%name%|::|&|*|&&"))
|
||||||
continue;
|
continue;
|
||||||
|
@ -1014,6 +1043,9 @@ void Tokenizer::simplifyTypedef()
|
||||||
if (indentlevel == 0 && tok->str() == "typedef") {
|
if (indentlevel == 0 && tok->str() == "typedef") {
|
||||||
TypedefSimplifier ts(tok, typeNum);
|
TypedefSimplifier ts(tok, typeNum);
|
||||||
if (!ts.fail() && numberOfTypedefs[ts.name()] == 1) {
|
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);
|
typedefs.emplace(ts.name(), ts);
|
||||||
if (!ts.isStructEtc())
|
if (!ts.isStructEtc())
|
||||||
tok = ts.endToken();
|
tok = ts.endToken();
|
||||||
|
|
|
@ -42,7 +42,7 @@ public:
|
||||||
private:
|
private:
|
||||||
// If there are unused templates, keep those
|
// If there are unused templates, keep those
|
||||||
const Settings settings0 = settingsBuilder().severity(Severity::style).checkUnusedTemplates().build();
|
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();
|
const Settings settings2 = settingsBuilder().severity(Severity::style).checkUnusedTemplates().build();
|
||||||
|
|
||||||
void run() override {
|
void run() override {
|
||||||
|
@ -57,6 +57,9 @@ private:
|
||||||
TEST_CASE(cstruct3);
|
TEST_CASE(cstruct3);
|
||||||
TEST_CASE(cstruct3);
|
TEST_CASE(cstruct3);
|
||||||
TEST_CASE(cstruct4);
|
TEST_CASE(cstruct4);
|
||||||
|
TEST_CASE(cfunction1);
|
||||||
|
TEST_CASE(cfunction2);
|
||||||
|
TEST_CASE(cfunction3);
|
||||||
TEST_CASE(cfp1);
|
TEST_CASE(cfp1);
|
||||||
TEST_CASE(cfp2);
|
TEST_CASE(cfp2);
|
||||||
TEST_CASE(cfp4);
|
TEST_CASE(cfp4);
|
||||||
|
@ -382,6 +385,26 @@ private:
|
||||||
ASSERT_EQUALS("struct s { int a ; int b ; } ; struct s x { } ;", simplifyTypedefC(code));
|
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() {
|
void cfp1() {
|
||||||
const char code[] = "typedef void (*fp)(void * p);\n"
|
const char code[] = "typedef void (*fp)(void * p);\n"
|
||||||
"fp x;";
|
"fp x;";
|
||||||
|
@ -3532,7 +3555,7 @@ private:
|
||||||
"func7 f7;";
|
"func7 f7;";
|
||||||
|
|
||||||
// The expected result..
|
// The expected result..
|
||||||
const char expected[] = "; C f1 ( ) ; "
|
const char expected[] = "C f1 ( ) ; "
|
||||||
"C ( * f2 ) ( ) ; "
|
"C ( * f2 ) ( ) ; "
|
||||||
"C ( & f3 ) ( ) ; "
|
"C ( & f3 ) ( ) ; "
|
||||||
"C ( * f4 ) ( ) ; "
|
"C ( * f4 ) ( ) ; "
|
||||||
|
@ -3561,7 +3584,7 @@ private:
|
||||||
|
|
||||||
// The expected result..
|
// The expected result..
|
||||||
// C const -> const C
|
// C const -> const C
|
||||||
const char expected[] = "; const C f1 ( ) ; "
|
const char expected[] = "const C f1 ( ) ; "
|
||||||
"const C ( * f2 ) ( ) ; "
|
"const C ( * f2 ) ( ) ; "
|
||||||
"const C ( & f3 ) ( ) ; "
|
"const C ( & f3 ) ( ) ; "
|
||||||
"const C ( * f4 ) ( ) ; "
|
"const C ( * f4 ) ( ) ; "
|
||||||
|
@ -3589,7 +3612,7 @@ private:
|
||||||
"func7 f7;";
|
"func7 f7;";
|
||||||
|
|
||||||
// The expected result..
|
// The expected result..
|
||||||
const char expected[] = "; const C f1 ( ) ; "
|
const char expected[] = "const C f1 ( ) ; "
|
||||||
"const C ( * f2 ) ( ) ; "
|
"const C ( * f2 ) ( ) ; "
|
||||||
"const C ( & f3 ) ( ) ; "
|
"const C ( & f3 ) ( ) ; "
|
||||||
"const C ( * f4 ) ( ) ; "
|
"const C ( * f4 ) ( ) ; "
|
||||||
|
@ -3617,7 +3640,7 @@ private:
|
||||||
"func7 f7;";
|
"func7 f7;";
|
||||||
|
|
||||||
// The expected result..
|
// The expected result..
|
||||||
const char expected[] = "; C * f1 ( ) ; "
|
const char expected[] = "C * f1 ( ) ; "
|
||||||
"C * ( * f2 ) ( ) ; "
|
"C * ( * f2 ) ( ) ; "
|
||||||
"C * ( & f3 ) ( ) ; "
|
"C * ( & f3 ) ( ) ; "
|
||||||
"C * ( * f4 ) ( ) ; "
|
"C * ( * f4 ) ( ) ; "
|
||||||
|
@ -3645,7 +3668,7 @@ private:
|
||||||
"func7 f7;";
|
"func7 f7;";
|
||||||
|
|
||||||
// The expected result..
|
// The expected result..
|
||||||
const char expected[] = "; const C * f1 ( ) ; "
|
const char expected[] = "const C * f1 ( ) ; "
|
||||||
"const C * ( * f2 ) ( ) ; "
|
"const C * ( * f2 ) ( ) ; "
|
||||||
"const C * ( & f3 ) ( ) ; "
|
"const C * ( & f3 ) ( ) ; "
|
||||||
"const C * ( * f4 ) ( ) ; "
|
"const C * ( * f4 ) ( ) ; "
|
||||||
|
@ -3674,7 +3697,7 @@ private:
|
||||||
|
|
||||||
// The expected result..
|
// The expected result..
|
||||||
// C const -> const C
|
// C const -> const C
|
||||||
const char expected[] = "; const C * f1 ( ) ; "
|
const char expected[] = "const C * f1 ( ) ; "
|
||||||
"const C * ( * f2 ) ( ) ; "
|
"const C * ( * f2 ) ( ) ; "
|
||||||
"const C * ( & f3 ) ( ) ; "
|
"const C * ( & f3 ) ( ) ; "
|
||||||
"const C * ( * f4 ) ( ) ; "
|
"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("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])();"));
|
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() {
|
void simplifyFunctionPointers2() {
|
||||||
|
|
Loading…
Reference in New Issue