Refactorization:
- Merged messages exceptThrowInNoexecptFunction, exceptThrowInNoThrowFunction, exceptThrowInAttributeNoThrowFunction and exceptThrowInDeclspecNoThrowFunction into a single message. - Merged Token::fIsDeclspecNothrow into Token::fIsAttributeNothrow
This commit is contained in:
parent
4d5bf28b33
commit
7452613479
|
@ -243,7 +243,7 @@ void CheckExceptionSafety::nothrowThrows()
|
|||
if (!function)
|
||||
continue;
|
||||
|
||||
// check noexcept functions
|
||||
// check noexcept and noexcept(true) functions
|
||||
if (function->isNoExcept() &&
|
||||
(!function->noexceptArg || function->noexceptArg->str() == "true")) {
|
||||
const Token *throws = functionThrows(function);
|
||||
|
@ -255,21 +255,14 @@ void CheckExceptionSafety::nothrowThrows()
|
|||
else if (function->isThrow() && !function->throwArg) {
|
||||
const Token *throws = functionThrows(function);
|
||||
if (throws)
|
||||
nothrowThrowError(throws);
|
||||
noexceptThrowError(throws);
|
||||
}
|
||||
|
||||
// check __attribute__((nothrow)) functions
|
||||
// check __attribute__((nothrow)) or __declspec(nothrow) functions
|
||||
else if (function->isAttributeNothrow()) {
|
||||
const Token *throws = functionThrows(function);
|
||||
if (throws)
|
||||
nothrowAttributeThrowError(throws);
|
||||
}
|
||||
|
||||
// check __declspec(nothrow) functions
|
||||
else if (function->isDeclspecNothrow()) {
|
||||
const Token *throws = functionThrows(function);
|
||||
if (throws)
|
||||
nothrowDeclspecThrowError(throws);
|
||||
noexceptThrowError(throws);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -109,24 +109,8 @@ private:
|
|||
"as a (const) reference which is usually recommended in C++.");
|
||||
}
|
||||
|
||||
/** Don't throw exceptions in noexcept functions */
|
||||
void noexceptThrowError(const Token * const tok) {
|
||||
reportError(tok, Severity::error, "exceptThrowInNoexecptFunction", "Exception thrown in noexcept function.");
|
||||
}
|
||||
|
||||
/** Don't throw exceptions in throw() functions */
|
||||
void nothrowThrowError(const Token * const tok) {
|
||||
reportError(tok, Severity::error, "exceptThrowInNoThrowFunction", "Exception thrown in throw() function.");
|
||||
}
|
||||
|
||||
/** Don't throw exceptions in __attribute__((nothrow)) functions */
|
||||
void nothrowAttributeThrowError(const Token * const tok) {
|
||||
reportError(tok, Severity::error, "exceptThrowInAttributeNoThrowFunction", "Exception thrown in __attribute__((nothrow)) function.");
|
||||
}
|
||||
|
||||
/** Don't throw exceptions in __declspec(nothrow) functions */
|
||||
void nothrowDeclspecThrowError(const Token * const tok) {
|
||||
reportError(tok, Severity::error, "exceptThrowInDeclspecNoThrowFunction", "Exception thrown in __declspec(nothrow) function.");
|
||||
reportError(tok, Severity::error, "throwInNoexceptFunction", "Exception thrown in function declared not to throw exceptions.");
|
||||
}
|
||||
|
||||
/** Missing exception specification */
|
||||
|
@ -149,9 +133,6 @@ private:
|
|||
c.rethrowCopyError(0, "varname");
|
||||
c.catchExceptionByValueError(0);
|
||||
c.noexceptThrowError(0);
|
||||
c.nothrowThrowError(0);
|
||||
c.nothrowAttributeThrowError(0);
|
||||
c.nothrowDeclspecThrowError(0);
|
||||
c.unhandledExceptionSpecificationError(0, 0, "funcname");
|
||||
}
|
||||
|
||||
|
@ -167,10 +148,7 @@ private:
|
|||
"- Throwing exception during invalid state\n"
|
||||
"- Throwing a copy of a caught exception instead of rethrowing the original exception\n"
|
||||
"- Exception caught by value instead of by reference\n"
|
||||
"- Throwing exception in noexcept function\n"
|
||||
"- Throwing exception in nothrow() function\n"
|
||||
"- Throwing exception in __attribute__((nothrow)) function\n"
|
||||
"- Throwing exception in __declspec(nothrow) function\n"
|
||||
"- Throwing exception in noexcept, nothrow(), __attribute__((nothrow)) or __declspec(nothrow) function\n"
|
||||
"- Unhandled exception specification when calling function foo()\n";
|
||||
}
|
||||
};
|
||||
|
|
|
@ -2785,7 +2785,7 @@ void CheckMemoryLeakNoVar::checkForUnsafeArgAlloc(const Scope *scope)
|
|||
// Scan through the arguments to the function call
|
||||
for (const Token *tok2 = tok->tokAt(2); tok2 && tok2 != endParamToken; tok2 = tok2->nextArgument()) {
|
||||
const Function *pFunc = tok2->function();
|
||||
const bool isNothrow = pFunc && (pFunc->isDeclspecNothrow() || pFunc->isAttributeNothrow());
|
||||
const bool isNothrow = pFunc && pFunc->isAttributeNothrow();
|
||||
|
||||
if (Token::Match(tok2, "shared_ptr|unique_ptr < %var% > ( new %var%")) {
|
||||
pointerType = tok2->str();
|
||||
|
|
|
@ -2121,7 +2121,6 @@ void SymbolDatabase::printOut(const char *title) const
|
|||
std::cout << " isAttributePure: " << (func->isAttributePure() ? "true" : "false") << std::endl;
|
||||
std::cout << " isAttributeNoreturn: " << (func->isAttributeNoreturn() ? "true" : "false") << std::endl;
|
||||
std::cout << " isAttributeNothrow: " << (func->isAttributeNothrow() ? "true" : "false") << std::endl;
|
||||
std::cout << " isDeclspecNothrow: " << (func->isDeclspecNothrow() ? "true" : "false") << std::endl;
|
||||
std::cout << " noexceptArg: " << (func->noexceptArg ? func->noexceptArg->str() : "none") << std::endl;
|
||||
std::cout << " throwArg: " << (func->throwArg ? func->throwArg->str() : "none") << std::endl;
|
||||
std::cout << " tokenDef: " << func->tokenDef->str() << " " <<_tokenizer->list.fileLine(func->tokenDef) << std::endl;
|
||||
|
|
|
@ -659,9 +659,6 @@ public:
|
|||
bool isAttributeNothrow() const {
|
||||
return tokenDef->isAttributeNothrow();
|
||||
}
|
||||
bool isDeclspecNothrow() const {
|
||||
return tokenDef->isDeclspecNothrow();
|
||||
}
|
||||
|
||||
bool hasBody() const {
|
||||
return getFlag(fHasBody);
|
||||
|
|
13
lib/token.h
13
lib/token.h
|
@ -372,12 +372,6 @@ public:
|
|||
void isAttributeNothrow(bool value) {
|
||||
setFlag(fIsAttributeNothrow, value);
|
||||
}
|
||||
bool isDeclspecNothrow() const {
|
||||
return getFlag(fIsDeclspecNothrow);
|
||||
}
|
||||
void isDeclspecNothrow(bool value) {
|
||||
setFlag(fIsDeclspecNothrow, value);
|
||||
}
|
||||
|
||||
static const Token *findsimplematch(const Token *tok, const char pattern[]);
|
||||
static const Token *findsimplematch(const Token *tok, const char pattern[], const Token *end);
|
||||
|
@ -783,10 +777,9 @@ private:
|
|||
fIsAttributeUnused = (1 << 9), // __attribute__((unused))
|
||||
fIsAttributePure = (1 << 10), // __attribute__((pure))
|
||||
fIsAttributeConst = (1 << 11), // __attribute__((const))
|
||||
fIsAttributeNoreturn = (1 << 12), // __attribute__((noreturn)) __declspec(noreturn)
|
||||
fIsAttributeNothrow = (1 << 13), // __attribute__((nothrow))
|
||||
fIsDeclspecNothrow = (1 << 14), // __declspec(nothrow)
|
||||
fIsAttributeUsed = (1 << 15) // __attribute__((used))
|
||||
fIsAttributeNoreturn = (1 << 12), // __attribute__((noreturn)), __declspec(noreturn)
|
||||
fIsAttributeNothrow = (1 << 13), // __attribute__((nothrow)), __declspec(nothrow)
|
||||
fIsAttributeUsed = (1 << 14) // __attribute__((used))
|
||||
};
|
||||
|
||||
unsigned int _flags;
|
||||
|
|
|
@ -9196,7 +9196,7 @@ void Tokenizer::simplifyDeclspec()
|
|||
if (tok->strAt(2) == "noreturn")
|
||||
tok1->isAttributeNoreturn(true);
|
||||
else
|
||||
tok1->isDeclspecNothrow(true);
|
||||
tok1->isAttributeNothrow(true);
|
||||
}
|
||||
} else if (tok->strAt(2) == "property")
|
||||
tok->next()->link()->insertToken("__property");
|
||||
|
|
|
@ -332,9 +332,9 @@ private:
|
|||
"void func4() noexcept(false) { throw 1; }\n"
|
||||
"void func5() noexcept(true) { func1(); }\n"
|
||||
"void func6() noexcept(false) { func1(); }\n");
|
||||
ASSERT_EQUALS("[test.cpp:2]: (error) Exception thrown in noexcept function.\n"
|
||||
"[test.cpp:3]: (error) Exception thrown in noexcept function.\n"
|
||||
"[test.cpp:5]: (error) Exception thrown in noexcept function.\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:2]: (error) Exception thrown in function declared not to throw exceptions.\n"
|
||||
"[test.cpp:3]: (error) Exception thrown in function declared not to throw exceptions.\n"
|
||||
"[test.cpp:5]: (error) Exception thrown in function declared not to throw exceptions.\n", errout.str());
|
||||
|
||||
// avoid false positives
|
||||
check("const char *func() noexcept { return 0; }\n");
|
||||
|
@ -347,8 +347,8 @@ private:
|
|||
"void func3() throw(int) { throw 1; }\n"
|
||||
"void func4() throw() { func1(); }\n"
|
||||
"void func5() throw(int) { func1(); }\n");
|
||||
ASSERT_EQUALS("[test.cpp:2]: (error) Exception thrown in throw() function.\n"
|
||||
"[test.cpp:4]: (error) Exception thrown in throw() function.\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:2]: (error) Exception thrown in function declared not to throw exceptions.\n"
|
||||
"[test.cpp:4]: (error) Exception thrown in function declared not to throw exceptions.\n", errout.str());
|
||||
|
||||
// avoid false positives
|
||||
check("const char *func() throw() { return 0; }\n");
|
||||
|
@ -383,8 +383,8 @@ private:
|
|||
check("void func1() throw(int) { throw 1; }\n"
|
||||
"void func2() __attribute((nothrow)); void func2() { throw 1; }\n"
|
||||
"void func3() __attribute((nothrow)); void func3() { func1(); }\n");
|
||||
ASSERT_EQUALS("[test.cpp:2]: (error) Exception thrown in __attribute__((nothrow)) function.\n"
|
||||
"[test.cpp:3]: (error) Exception thrown in __attribute__((nothrow)) function.\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:2]: (error) Exception thrown in function declared not to throw exceptions.\n"
|
||||
"[test.cpp:3]: (error) Exception thrown in function declared not to throw exceptions.\n", errout.str());
|
||||
|
||||
// avoid false positives
|
||||
check("const char *func() __attribute((nothrow)); void func1() { return 0; }\n");
|
||||
|
@ -404,8 +404,8 @@ private:
|
|||
check("void func1() throw(int) { throw 1; }\n"
|
||||
"void __declspec(nothrow) func2() { throw 1; }\n"
|
||||
"void __declspec(nothrow) func3() { func1(); }\n");
|
||||
ASSERT_EQUALS("[test.cpp:2]: (error) Exception thrown in __declspec(nothrow) function.\n"
|
||||
"[test.cpp:3]: (error) Exception thrown in __declspec(nothrow) function.\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:2]: (error) Exception thrown in function declared not to throw exceptions.\n"
|
||||
"[test.cpp:3]: (error) Exception thrown in function declared not to throw exceptions.\n", errout.str());
|
||||
|
||||
// avoid false positives
|
||||
check("const char *func() __attribute((nothrow)); void func1() { return 0; }\n");
|
||||
|
|
|
@ -2592,7 +2592,7 @@ private:
|
|||
const Function *func = findFunctionByName("func", &db->scopeList.front());
|
||||
ASSERT_EQUALS(true, func != nullptr);
|
||||
if (func)
|
||||
ASSERT_EQUALS(true, func->isDeclspecNothrow());
|
||||
ASSERT_EQUALS(true, func->isAttributeNothrow());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue