| 3319 | |
| 3320 | template<class Predicate> |
| 3321 | static bool checkReturns(const Function* function, bool unknown, bool emptyEnableIf, Predicate pred) |
| 3322 | { |
| 3323 | if (!function) |
| 3324 | return false; |
| 3325 | if (function->type != FunctionType::eFunction && function->type != FunctionType::eOperatorEqual && function->type != FunctionType::eLambda) |
| 3326 | return false; |
| 3327 | const Token* defStart = function->retDef; |
| 3328 | if (!defStart) |
| 3329 | return unknown; |
| 3330 | const Token* defEnd = function->returnDefEnd(); |
| 3331 | if (!defEnd) |
| 3332 | return unknown; |
| 3333 | if (defEnd == defStart) |
| 3334 | return unknown; |
| 3335 | if (pred(defStart, defEnd)) |
| 3336 | return true; |
| 3337 | if (Token::Match(defEnd->tokAt(-1), "*|&|&&")) |
| 3338 | return false; |
| 3339 | // void STDCALL foo() |
| 3340 | while (defEnd->previous() != defStart && Token::Match(defEnd->tokAt(-2), "%name%|> %name%") && |
| 3341 | !Token::Match(defEnd->tokAt(-2), "const|volatile")) |
| 3342 | defEnd = defEnd->previous(); |
| 3343 | // enable_if |
| 3344 | const Token* enableIfEnd = nullptr; |
| 3345 | if (Token::simpleMatch(defEnd->previous(), ">")) |
| 3346 | enableIfEnd = defEnd->previous(); |
| 3347 | else if (Token::simpleMatch(defEnd->tokAt(-3), "> :: type")) |
| 3348 | enableIfEnd = defEnd->tokAt(-3); |
| 3349 | if (enableIfEnd && enableIfEnd->link() && |
| 3350 | Token::Match(enableIfEnd->link()->previous(), "enable_if|enable_if_t|EnableIf")) { |
| 3351 | if (const Token* start = getEnableIfReturnType(enableIfEnd->link())) { |
| 3352 | defStart = start; |
| 3353 | defEnd = enableIfEnd; |
| 3354 | } else { |
| 3355 | return emptyEnableIf; |
| 3356 | } |
| 3357 | } |
| 3358 | assert(defEnd != defStart); |
| 3359 | if (pred(defStart, defEnd)) |
| 3360 | return true; |
| 3361 | if (isUnknownType(defStart, defEnd)) { |
| 3362 | const Token* tok = function->token ? function->token->next() : function->tokenDef->next(); |
| 3363 | if (tok->valueType() && tok->valueType()->type >= ValueType::Type::RECORD) |
| 3364 | return false; |
| 3365 | return unknown; |
| 3366 | } |
| 3367 | return false; |
| 3368 | } |
| 3369 | |
| 3370 | bool Function::returnsConst(const Function* function, bool unknown) |
| 3371 | { |
no test coverage detected