Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions lib/tokenize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -630,7 +630,7 @@ namespace {
start = start->next();

// TODO handle unnamed structs etc
if (Token::Match(start, "const| enum|struct|union|class %name% {")) {
if (Token::Match(start, "const| enum|struct|union|class %name%| {")) {
const std::pair<Token*, Token*> rangeBefore(start, Token::findsimplematch(start, "{"));

// find typedef name token
Expand All @@ -640,6 +640,8 @@ namespace {
const std::pair<Token*, Token*> rangeQualifiers(rangeBefore.second->link()->next(), nameToken);

if (Token::Match(nameToken, "%name% ;")) {
if (Token::Match(rangeBefore.second->previous(), "enum|struct|union|class {"))
rangeBefore.second->previous()->insertToken(nameToken->str());
mRangeType = rangeBefore;
mRangeTypeQualifiers = rangeQualifiers;
Token* typeName = rangeBefore.second->previous();
Expand Down Expand Up @@ -774,7 +776,7 @@ namespace {
}

// Inherited type => skip "struct" / "class"
if (Token::Match(mRangeType.first, "const| struct|class %name% {") && Token::Match(tok->previous(), "public|protected|private")) {
if (Token::Match(mRangeType.first, "const| struct|class %name% {") && Token::Match(tok->previous(), "public|protected|private|<")) {
tok->originalName(tok->str());
tok->str(mRangeType.second->previous()->str());
return;
Expand Down
11 changes: 10 additions & 1 deletion test/testcondition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5025,7 +5025,7 @@ class TestCondition : public TestFixture {
}

// #9353
check("typedef struct { std::string s; } X;\n"
check("struct X { std::string s; };\n"
"void f(const std::vector<X>&v) {\n"
" for (std::vector<X>::const_iterator it = v.begin(); it != v.end(); ++it)\n"
" if (!it->s.empty()) {\n"
Expand All @@ -5034,6 +5034,15 @@ class TestCondition : public TestFixture {
"}\n");
ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:5]: (style) Condition '!it->s.empty()' is always true\n", errout.str());

check("struct X { std::string s; };\n"
"void f(const std::vector<struct X>&v) {\n"
" for (std::vector<struct X>::const_iterator it = v.begin(); it != v.end(); ++it)\n"
" if (!it->s.empty()) {\n"
" if (!it->s.empty()) {}\n"
" }\n"
"}\n");
TODO_ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:5]: (style) Condition '!it->s.empty()' is always true\n", "", errout.str());

// #10508
check("bool f(const std::string& a, const std::string& b) {\n"
" return a.empty() || (b.empty() && a.empty());\n"
Expand Down
23 changes: 15 additions & 8 deletions test/testsimplifytypedef.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class TestSimplifyTypedef : public TestFixture {
TEST_CASE(cstruct3);
TEST_CASE(cstruct3);
TEST_CASE(cstruct4);
TEST_CASE(cenum1);
TEST_CASE(cfunction1);
TEST_CASE(cfunction2);
TEST_CASE(cfunction3);
Expand Down Expand Up @@ -372,8 +373,8 @@ class TestSimplifyTypedef : public TestFixture {
void cstruct2() {
const char code[] = "typedef enum { A, B } t;\n"
"t x;";
ASSERT_EQUALS("enum t { A , B } ; t x ;", simplifyTypedef(code));
ASSERT_EQUALS("enum t { A , B } ; t x ;", simplifyTypedefC(code));
ASSERT_EQUALS("enum t { A , B } ; enum t x ;", simplifyTypedef(code));
ASSERT_EQUALS("enum t { A , B } ; enum t x ;", simplifyTypedefC(code));
}

void cstruct3() {
Expand All @@ -388,6 +389,12 @@ class TestSimplifyTypedef : public TestFixture {
ASSERT_EQUALS("struct s { int a ; int b ; } ; struct s x { } ;", simplifyTypedefC(code));
}

void cenum1() {
const char code[] = "typedef enum { a, b } E;\n"
"E e;";
ASSERT_EQUALS("enum E { a , b } ; enum E e ;", simplifyTypedefC(code));
}

void cfunction1() {
const char code[] = "typedef int callback(int);\n"
"callback* cb;";
Expand Down Expand Up @@ -694,13 +701,13 @@ class TestSimplifyTypedef : public TestFixture {
const char expected[] =
"struct t { int a ; } ; "
"struct U { int a ; } ; "
"struct Unnamed0 { int a ; } ; "
"struct V { int a ; } ; "
"struct s s ; "
"struct s * ps ; "
"struct t t ; "
"struct t * tp ; "
"struct U u ; "
"struct Unnamed0 * v ;";
"struct V * v ;";

ASSERT_EQUALS(expected, tok(code, false));
}
Expand All @@ -720,13 +727,13 @@ class TestSimplifyTypedef : public TestFixture {
const char expected[] =
"union t { int a ; float b ; } ; "
"union U { int a ; float b ; } ; "
"union Unnamed0 { int a ; float b ; } ; "
"union V { int a ; float b ; } ; "
"union s s ; "
"union s * ps ; "
"union t t ; "
"union t * tp ; "
"union U u ; "
"union Unnamed0 * v ;";
"union V * v ;";

ASSERT_EQUALS(expected, tok(code, false));
}
Expand All @@ -739,7 +746,7 @@ class TestSimplifyTypedef : public TestFixture {

const char expected[] = "enum abc { a = 0 , b = 1 , c = 2 } ; "
"enum xyz { x = 0 , y = 1 , z = 2 } ; "
"abc e1 ; "
"enum abc e1 ; "
"enum xyz e2 ;";

ASSERT_EQUALS(expected, tok(code, false));
Expand Down Expand Up @@ -1837,7 +1844,7 @@ class TestSimplifyTypedef : public TestFixture {
" localEntitiyAddFunc_t f;\n"
"}";
// The expected result..
const char expected[] = "enum qboolean { qfalse , qtrue } ; void f ( ) { qboolean b ; qboolean ( * f ) ( struct le_s * , entity_t * ) ; }";
const char expected[] = "enum qboolean { qfalse , qtrue } ; void f ( ) { enum qboolean b ; enum qboolean ( * f ) ( struct le_s * , entity_t * ) ; }";
ASSERT_EQUALS(expected, tok(code, false));
ASSERT_EQUALS("", errout.str());
}
Expand Down