Fixed #9814 (False positive: functionConst, trailing return type)
This commit is contained in:
parent
ad8d8ca11d
commit
6a839ad511
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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("");
|
||||
|
|
Loading…
Reference in New Issue