Refactorization:

- Merged messages exceptThrowInNoexecptFunction, exceptThrowInNoThrowFunction, exceptThrowInAttributeNoThrowFunction and exceptThrowInDeclspecNoThrowFunction into a single message.
- Merged Token::fIsDeclspecNothrow into Token::fIsAttributeNothrow
This commit is contained in:
PKEuS 2015-01-09 20:18:09 +01:00
parent 4d5bf28b33
commit 7452613479
9 changed files with 21 additions and 61 deletions

View File

@ -243,7 +243,7 @@ void CheckExceptionSafety::nothrowThrows()
if (!function) if (!function)
continue; continue;
// check noexcept functions // check noexcept and noexcept(true) functions
if (function->isNoExcept() && if (function->isNoExcept() &&
(!function->noexceptArg || function->noexceptArg->str() == "true")) { (!function->noexceptArg || function->noexceptArg->str() == "true")) {
const Token *throws = functionThrows(function); const Token *throws = functionThrows(function);
@ -255,21 +255,14 @@ void CheckExceptionSafety::nothrowThrows()
else if (function->isThrow() && !function->throwArg) { else if (function->isThrow() && !function->throwArg) {
const Token *throws = functionThrows(function); const Token *throws = functionThrows(function);
if (throws) if (throws)
nothrowThrowError(throws); noexceptThrowError(throws);
} }
// check __attribute__((nothrow)) functions // check __attribute__((nothrow)) or __declspec(nothrow) functions
else if (function->isAttributeNothrow()) { else if (function->isAttributeNothrow()) {
const Token *throws = functionThrows(function); const Token *throws = functionThrows(function);
if (throws) if (throws)
nothrowAttributeThrowError(throws); noexceptThrowError(throws);
}
// check __declspec(nothrow) functions
else if (function->isDeclspecNothrow()) {
const Token *throws = functionThrows(function);
if (throws)
nothrowDeclspecThrowError(throws);
} }
} }
} }

View File

@ -109,24 +109,8 @@ private:
"as a (const) reference which is usually recommended in C++."); "as a (const) reference which is usually recommended in C++.");
} }
/** Don't throw exceptions in noexcept functions */
void noexceptThrowError(const Token * const tok) { void noexceptThrowError(const Token * const tok) {
reportError(tok, Severity::error, "exceptThrowInNoexecptFunction", "Exception thrown in noexcept function."); reportError(tok, Severity::error, "throwInNoexceptFunction", "Exception thrown in function declared not to throw exceptions.");
}
/** 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.");
} }
/** Missing exception specification */ /** Missing exception specification */
@ -149,9 +133,6 @@ private:
c.rethrowCopyError(0, "varname"); c.rethrowCopyError(0, "varname");
c.catchExceptionByValueError(0); c.catchExceptionByValueError(0);
c.noexceptThrowError(0); c.noexceptThrowError(0);
c.nothrowThrowError(0);
c.nothrowAttributeThrowError(0);
c.nothrowDeclspecThrowError(0);
c.unhandledExceptionSpecificationError(0, 0, "funcname"); c.unhandledExceptionSpecificationError(0, 0, "funcname");
} }
@ -167,10 +148,7 @@ private:
"- Throwing exception during invalid state\n" "- Throwing exception during invalid state\n"
"- Throwing a copy of a caught exception instead of rethrowing the original exception\n" "- Throwing a copy of a caught exception instead of rethrowing the original exception\n"
"- Exception caught by value instead of by reference\n" "- Exception caught by value instead of by reference\n"
"- Throwing exception in noexcept function\n" "- Throwing exception in noexcept, nothrow(), __attribute__((nothrow)) or __declspec(nothrow) function\n"
"- Throwing exception in nothrow() function\n"
"- Throwing exception in __attribute__((nothrow)) function\n"
"- Throwing exception in __declspec(nothrow) function\n"
"- Unhandled exception specification when calling function foo()\n"; "- Unhandled exception specification when calling function foo()\n";
} }
}; };

View File

@ -2785,7 +2785,7 @@ void CheckMemoryLeakNoVar::checkForUnsafeArgAlloc(const Scope *scope)
// Scan through the arguments to the function call // Scan through the arguments to the function call
for (const Token *tok2 = tok->tokAt(2); tok2 && tok2 != endParamToken; tok2 = tok2->nextArgument()) { for (const Token *tok2 = tok->tokAt(2); tok2 && tok2 != endParamToken; tok2 = tok2->nextArgument()) {
const Function *pFunc = tok2->function(); 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%")) { if (Token::Match(tok2, "shared_ptr|unique_ptr < %var% > ( new %var%")) {
pointerType = tok2->str(); pointerType = tok2->str();

View File

@ -2121,7 +2121,6 @@ void SymbolDatabase::printOut(const char *title) const
std::cout << " isAttributePure: " << (func->isAttributePure() ? "true" : "false") << std::endl; std::cout << " isAttributePure: " << (func->isAttributePure() ? "true" : "false") << std::endl;
std::cout << " isAttributeNoreturn: " << (func->isAttributeNoreturn() ? "true" : "false") << std::endl; std::cout << " isAttributeNoreturn: " << (func->isAttributeNoreturn() ? "true" : "false") << std::endl;
std::cout << " isAttributeNothrow: " << (func->isAttributeNothrow() ? "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 << " noexceptArg: " << (func->noexceptArg ? func->noexceptArg->str() : "none") << std::endl;
std::cout << " throwArg: " << (func->throwArg ? func->throwArg->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; std::cout << " tokenDef: " << func->tokenDef->str() << " " <<_tokenizer->list.fileLine(func->tokenDef) << std::endl;

View File

@ -659,9 +659,6 @@ public:
bool isAttributeNothrow() const { bool isAttributeNothrow() const {
return tokenDef->isAttributeNothrow(); return tokenDef->isAttributeNothrow();
} }
bool isDeclspecNothrow() const {
return tokenDef->isDeclspecNothrow();
}
bool hasBody() const { bool hasBody() const {
return getFlag(fHasBody); return getFlag(fHasBody);

View File

@ -372,12 +372,6 @@ public:
void isAttributeNothrow(bool value) { void isAttributeNothrow(bool value) {
setFlag(fIsAttributeNothrow, 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[]);
static const Token *findsimplematch(const Token *tok, const char pattern[], const Token *end); static const Token *findsimplematch(const Token *tok, const char pattern[], const Token *end);
@ -783,10 +777,9 @@ private:
fIsAttributeUnused = (1 << 9), // __attribute__((unused)) fIsAttributeUnused = (1 << 9), // __attribute__((unused))
fIsAttributePure = (1 << 10), // __attribute__((pure)) fIsAttributePure = (1 << 10), // __attribute__((pure))
fIsAttributeConst = (1 << 11), // __attribute__((const)) fIsAttributeConst = (1 << 11), // __attribute__((const))
fIsAttributeNoreturn = (1 << 12), // __attribute__((noreturn)) __declspec(noreturn) fIsAttributeNoreturn = (1 << 12), // __attribute__((noreturn)), __declspec(noreturn)
fIsAttributeNothrow = (1 << 13), // __attribute__((nothrow)) fIsAttributeNothrow = (1 << 13), // __attribute__((nothrow)), __declspec(nothrow)
fIsDeclspecNothrow = (1 << 14), // __declspec(nothrow) fIsAttributeUsed = (1 << 14) // __attribute__((used))
fIsAttributeUsed = (1 << 15) // __attribute__((used))
}; };
unsigned int _flags; unsigned int _flags;

View File

@ -9196,7 +9196,7 @@ void Tokenizer::simplifyDeclspec()
if (tok->strAt(2) == "noreturn") if (tok->strAt(2) == "noreturn")
tok1->isAttributeNoreturn(true); tok1->isAttributeNoreturn(true);
else else
tok1->isDeclspecNothrow(true); tok1->isAttributeNothrow(true);
} }
} else if (tok->strAt(2) == "property") } else if (tok->strAt(2) == "property")
tok->next()->link()->insertToken("__property"); tok->next()->link()->insertToken("__property");

View File

@ -332,9 +332,9 @@ private:
"void func4() noexcept(false) { throw 1; }\n" "void func4() noexcept(false) { throw 1; }\n"
"void func5() noexcept(true) { func1(); }\n" "void func5() noexcept(true) { func1(); }\n"
"void func6() noexcept(false) { func1(); }\n"); "void func6() noexcept(false) { func1(); }\n");
ASSERT_EQUALS("[test.cpp:2]: (error) Exception thrown in noexcept function.\n" ASSERT_EQUALS("[test.cpp:2]: (error) Exception thrown in function declared not to throw exceptions.\n"
"[test.cpp:3]: (error) Exception thrown in noexcept function.\n" "[test.cpp:3]: (error) Exception thrown in function declared not to throw exceptions.\n"
"[test.cpp:5]: (error) Exception thrown in noexcept function.\n", errout.str()); "[test.cpp:5]: (error) Exception thrown in function declared not to throw exceptions.\n", errout.str());
// avoid false positives // avoid false positives
check("const char *func() noexcept { return 0; }\n"); check("const char *func() noexcept { return 0; }\n");
@ -347,8 +347,8 @@ private:
"void func3() throw(int) { throw 1; }\n" "void func3() throw(int) { throw 1; }\n"
"void func4() throw() { func1(); }\n" "void func4() throw() { func1(); }\n"
"void func5() throw(int) { func1(); }\n"); "void func5() throw(int) { func1(); }\n");
ASSERT_EQUALS("[test.cpp:2]: (error) Exception thrown in throw() function.\n" ASSERT_EQUALS("[test.cpp:2]: (error) Exception thrown in function declared not to throw exceptions.\n"
"[test.cpp:4]: (error) Exception thrown in throw() function.\n", errout.str()); "[test.cpp:4]: (error) Exception thrown in function declared not to throw exceptions.\n", errout.str());
// avoid false positives // avoid false positives
check("const char *func() throw() { return 0; }\n"); check("const char *func() throw() { return 0; }\n");
@ -383,8 +383,8 @@ private:
check("void func1() throw(int) { throw 1; }\n" check("void func1() throw(int) { throw 1; }\n"
"void func2() __attribute((nothrow)); void func2() { throw 1; }\n" "void func2() __attribute((nothrow)); void func2() { throw 1; }\n"
"void func3() __attribute((nothrow)); void func3() { func1(); }\n"); "void func3() __attribute((nothrow)); void func3() { func1(); }\n");
ASSERT_EQUALS("[test.cpp:2]: (error) Exception thrown in __attribute__((nothrow)) function.\n" ASSERT_EQUALS("[test.cpp:2]: (error) Exception thrown in function declared not to throw exceptions.\n"
"[test.cpp:3]: (error) Exception thrown in __attribute__((nothrow)) function.\n", errout.str()); "[test.cpp:3]: (error) Exception thrown in function declared not to throw exceptions.\n", errout.str());
// avoid false positives // avoid false positives
check("const char *func() __attribute((nothrow)); void func1() { return 0; }\n"); check("const char *func() __attribute((nothrow)); void func1() { return 0; }\n");
@ -404,8 +404,8 @@ private:
check("void func1() throw(int) { throw 1; }\n" check("void func1() throw(int) { throw 1; }\n"
"void __declspec(nothrow) func2() { throw 1; }\n" "void __declspec(nothrow) func2() { throw 1; }\n"
"void __declspec(nothrow) func3() { func1(); }\n"); "void __declspec(nothrow) func3() { func1(); }\n");
ASSERT_EQUALS("[test.cpp:2]: (error) Exception thrown in __declspec(nothrow) function.\n" ASSERT_EQUALS("[test.cpp:2]: (error) Exception thrown in function declared not to throw exceptions.\n"
"[test.cpp:3]: (error) Exception thrown in __declspec(nothrow) function.\n", errout.str()); "[test.cpp:3]: (error) Exception thrown in function declared not to throw exceptions.\n", errout.str());
// avoid false positives // avoid false positives
check("const char *func() __attribute((nothrow)); void func1() { return 0; }\n"); check("const char *func() __attribute((nothrow)); void func1() { return 0; }\n");

View File

@ -2592,7 +2592,7 @@ private:
const Function *func = findFunctionByName("func", &db->scopeList.front()); const Function *func = findFunctionByName("func", &db->scopeList.front());
ASSERT_EQUALS(true, func != nullptr); ASSERT_EQUALS(true, func != nullptr);
if (func) if (func)
ASSERT_EQUALS(true, func->isDeclspecNothrow()); ASSERT_EQUALS(true, func->isAttributeNothrow());
} }
} }