| 2944 | //--------------------------------------------------------------------------- |
| 2945 | |
| 2946 | void CheckClassImpl::checkVirtualFunctionCallInConstructor() |
| 2947 | { |
| 2948 | if (!mSettings.severity.isEnabled(Severity::warning)) |
| 2949 | return; |
| 2950 | logChecker("CheckClass::checkVirtualFunctionCallInConstructor"); // warning |
| 2951 | std::map<const Function *, std::list<const Token *>> virtualFunctionCallsMap; |
| 2952 | for (const Scope *scope : mSymbolDatabase->functionScopes) { |
| 2953 | if (scope->function == nullptr || !scope->function->hasBody() || |
| 2954 | !(scope->function->isConstructor() || |
| 2955 | scope->function->isDestructor())) |
| 2956 | continue; |
| 2957 | |
| 2958 | const std::list<const Token *> & virtualFunctionCalls = getVirtualFunctionCalls(*scope->function, virtualFunctionCallsMap); |
| 2959 | for (const Token *callToken : virtualFunctionCalls) { |
| 2960 | std::list<const Token *> callstack(1, callToken); |
| 2961 | getFirstVirtualFunctionCallStack(virtualFunctionCallsMap, callToken, callstack); |
| 2962 | if (callstack.empty()) |
| 2963 | continue; |
| 2964 | const Function* const func = callstack.back()->function(); |
| 2965 | if (!(func->hasVirtualSpecifier() || func->hasOverrideSpecifier())) |
| 2966 | continue; |
| 2967 | if (func->isPure()) |
| 2968 | pureVirtualFunctionCallInConstructorError(scope->function, callstack, callstack.back()->str()); |
| 2969 | else if (!func->hasFinalSpecifier() && |
| 2970 | !(func->nestedIn && func->nestedIn->classDef && func->nestedIn->classDef->isFinalType())) |
| 2971 | virtualFunctionCallInConstructorError(scope->function, callstack, callstack.back()->str()); |
| 2972 | } |
| 2973 | } |
| 2974 | } |
| 2975 | |
| 2976 | const std::list<const Token *> & CheckClassImpl::getVirtualFunctionCalls(const Function & function, |
| 2977 | std::map<const Function *, std::list<const Token *>> & virtualFunctionCallsMap) |