Fixed #9814 (False positive: functionConst, trailing return type)

This commit is contained in:
Daniel Marjamäki 2020-07-24 19:40:04 +02:00
parent ad8d8ca11d
commit 6a839ad511
2 changed files with 28 additions and 18 deletions

View File

@ -1788,28 +1788,29 @@ void CheckClass::checkConst()
// don't warn for friend/static/virtual functions
if (func.isFriend() || func.isStatic() || func.hasVirtualSpecifier())
continue;
// get last token of return type
const Token *previous = func.tokenDef->previous();
// does the function return a pointer or reference?
if (Token::Match(previous, "*|&")) {
if (func.retDef->str() != "const")
continue;
} else if (Token::Match(previous->previous(), "*|& >")) {
const Token *temp = previous->previous();
bool foundConst = false;
while (!Token::Match(temp->previous(), ";|}|{|public:|protected:|private:")) {
temp = temp->previous();
if (temp->str() == "const") {
foundConst = true;
// is non-const pointer/reference returned?
{
bool isConst = false;
bool isPointerOrReference = false;
for (const Token *typeToken = func.retDef; typeToken; typeToken = typeToken->next()) {
if (Token::Match(typeToken, "(|{|;"))
break;
if (!isPointerOrReference && typeToken->str() == "const") {
isConst = true;
break;
}
if (Token::Match(typeToken, "*|&")) {
isPointerOrReference = true;
break;
}
}
if (!foundConst)
if (isPointerOrReference)
continue;
} else if (func.isOperator() && Token::Match(previous, ";|{|}|public:|private:|protected:")) { // Operator without return type: conversion operator
}
if (func.isOperator()) { // Operator without return type: conversion operator
const std::string& opName = func.tokenDef->str();
if (opName.compare(8, 5, "const") != 0 && (endsWith(opName,'&') || endsWith(opName,'*')))
continue;
@ -1819,7 +1820,7 @@ void CheckClass::checkConst()
} else {
// don't warn for unknown types..
// LPVOID, HDC, etc
if (previous->str().size() > 2 && !previous->type() && previous->isUpperCaseName())
if (func.retDef->str().size() > 2 && !func.retDef->type() && func.retDef->isUpperCaseName())
continue;
}

View File

@ -198,6 +198,7 @@ private:
TEST_CASE(constRangeBasedFor); // #5514
TEST_CASE(const_shared_ptr);
TEST_CASE(constPtrToConstPtr);
TEST_CASE(constTrailingReturnType);
TEST_CASE(initializerListOrder);
TEST_CASE(initializerListUsage);
@ -6314,6 +6315,14 @@ private:
ASSERT_EQUALS("[test.cpp:4]: (style, inconclusive) Technically the member function 'Fred::getData' can be const.\n", errout.str());
}
void constTrailingReturnType() { // #9814
checkConst("struct A {\n"
" int x = 1;\n"
" auto get() -> int & { return x; }\n"
"};");
ASSERT_EQUALS("", errout.str());
}
void checkInitializerListOrder(const char code[]) {
// Clear the error log
errout.str("");