Skip to content
Open
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
4 changes: 2 additions & 2 deletions lib/token.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1281,7 +1281,7 @@ std::string Token::stringify(const stringifyOptions& options) const
ret += "long ";
}
}
if (options.macro && isExpandedMacro())
if (options.macro && hasMacroName())
ret += '$';
if (isName() && mStr.find(' ') != std::string::npos) {
for (const char i : mStr) {
Expand Down Expand Up @@ -1697,7 +1697,7 @@ static void indent(std::string &str, const nonneg int indent1, const nonneg int

void Token::astStringVerboseRecursive(std::string& ret, const nonneg int indent1, const nonneg int indent2) const
{
if (isExpandedMacro())
if (hasMacroName())
ret += '$';
ret += mStr;
if (mImpl->mValueType)
Expand Down
11 changes: 11 additions & 0 deletions lib/token.h
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,18 @@ class CPPCHECKLIB Token {
void isStandardType(const bool b) {
setFlag(fIsStandardType, b);
}
/**
* Is this token macro code at this location? Tokens copied from a
* typedef are excluded, see hasMacroName().
*/
bool isExpandedMacro() const {
return mImpl->mMacroName && !isSimplifiedTypedef();
}
/**
* Did the token text originate from a macro? Also true for tokens copied
* from a typedef. Intended for dump output and copying tokens.
*/
bool hasMacroName() const {
return !!mImpl->mMacroName;
}
bool isCast() const {
Expand Down
4 changes: 3 additions & 1 deletion lib/tokenize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1034,6 +1034,8 @@ namespace {
to = to->next();
to->isSimplifiedTypedef(true);
to->isExternC(from->isExternC());
if (from->hasMacroName())
to->setMacroName(from->getMacroName());
Comment thread
wjakobsson marked this conversation as resolved.
Resolved
}
return to;
}
Expand Down Expand Up @@ -6382,7 +6384,7 @@ void Tokenizer::dump(std::ostream &out) const
outs += " isCast=\"true\"";
if (tok->isExternC())
outs += " externLang=\"C\"";
if (tok->isExpandedMacro())
if (tok->hasMacroName())
outs += " macroName=\"" + tok->getMacroName() + "\"";
if (tok->isTemplateArg()) {
outs += " isTemplateArg=\"true\"";
Expand Down
2 changes: 2 additions & 0 deletions lib/tokenlist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,8 @@ Token *TokenList::copyTokens(Token *dest, const Token *first, const Token *last,
tok2->flags(tok->flags());
tok2->varId(tok->varId());
tok2->setTokenDebug(tok->getTokenDebug());
if (tok->hasMacroName())
tok2->setMacroName(tok->getMacroName());
Comment thread
wjakobsson marked this conversation as resolved.
Resolved

// Check for links and fix them up
if (Token::Match(tok2, "(|[|{"))
Expand Down
18 changes: 18 additions & 0 deletions test/testother.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7508,6 +7508,16 @@ class TestOther : public TestFixture {
" {}\n"
"}\n");
ASSERT_EQUALS("", errout_str());

// typedef of macro, same typedef in both branches
checkP("#define INT int\n"
"typedef INT T;\n"
"void g(T);\n"
"void f(bool c) {\n"
" if (c) { T x = 1; g(x); }\n"
" else { T x = 1; g(x); }\n"
"}\n");
ASSERT_EQUALS("[test.cpp:6:3] -> [test.cpp:5:3]: (style, inconclusive) Found duplicate branches for 'if' and 'else'. [duplicateBranch]\n", errout_str());
}

void duplicateBranch2() {
Expand Down Expand Up @@ -7634,6 +7644,14 @@ class TestOther : public TestFixture {
}

void duplicateExpression1() {
// typedef of macro is not macro code at the point of use
checkP("#define INT int\n"
"typedef INT T;\n"
"void foo(int a) {\n"
" if ((T)a == (T)a) { }\n"
"}\n");
ASSERT_EQUALS("[test.cpp:4:14]: (style) Same expression on both sides of '=='. [duplicateExpression]\n", errout_str());

check("void foo(int a) {\n"
" if (a == a) { }\n"
"}\n");
Expand Down
11 changes: 11 additions & 0 deletions test/testsimplifytypedef.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ class TestSimplifyTypedef : public TestFixture {
TEST_CASE(simplifyTypedefShadow); // #4445 - shadow variable

TEST_CASE(simplifyTypedefMacro);
TEST_CASE(simplifyTypedefMacroName);

TEST_CASE(simplifyTypedefOriginalName1);
TEST_CASE(simplifyTypedefOriginalName2);
Expand Down Expand Up @@ -4547,6 +4548,16 @@ class TestSimplifyTypedef : public TestFixture {
simplifyTypedefP(code));
}

void simplifyTypedefMacroName() {
const char code[] = "#define A int\n"
"typedef void (*F)(A x);\n"
"void f(F g);\n";
SimpleTokenizer2 tokenizer(settings0, *this, code, "test.c");
tokenizer.createLinks();
tokenizer.simplifyTypedef();
ASSERT_EQUALS("void f ( void ( * g ) ( $int x ) ) ;", tokenizer.tokens()->stringifyList(false, true, false, false, false));
}

void simplifyTypedefOriginalName1() {
const char code[] = "typedef unsigned char uint8_t;\n"
"typedef float (*rFunctionPointer_fp)(uint8_t, uint8_t);\n"
Expand Down
11 changes: 11 additions & 0 deletions test/testsimplifyusing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ class TestSimplifyUsing : public TestFixture {
TEST_CASE(simplifyUsing10720);
TEST_CASE(simplifyUsing13873); // function declaration
TEST_CASE(simplifyUsing14877);
TEST_CASE(simplifyUsingMacroName);

TEST_CASE(scopeInfo1);
TEST_CASE(scopeInfo2);
Expand Down Expand Up @@ -1725,6 +1726,16 @@ class TestSimplifyUsing : public TestFixture {
ASSERT_EQUALS(expected, tok(code));
}

void simplifyUsingMacroName() {
const char code[] = "#define A int\n"
"using F = void (*)(A x);\n"
"void f(F g);\n";
const Settings settings = settingsBuilder(settings0).cpp(Standards::CPPLatest).build();
SimpleTokenizer2 tokenizer(settings, *this, code, "test.cpp");
ASSERT(tokenizer.simplifyTokens1(""));
ASSERT_EQUALS("void f ( void ( * g ) ( $int ) ) ;", tokenizer.tokens()->stringifyList(false, true, false, false, false));
}

void scopeInfo1() {
const char code[] = "struct A {\n"
" enum class Mode { UNKNOWN, ENABLED, NONE, };\n"
Expand Down
Loading