| 2805 | } |
| 2806 | |
| 2807 | void CheckClassImpl::initializerListOrder() |
| 2808 | { |
| 2809 | if (!mSettings.isPremiumEnabled("initializerList")) { |
| 2810 | if (!mSettings.severity.isEnabled(Severity::style)) |
| 2811 | return; |
| 2812 | |
| 2813 | // This check is not inconclusive. However it only determines if the initialization |
| 2814 | // order is incorrect. It does not determine if being out of order causes |
| 2815 | // a real error. Out of order is not necessarily an error but you can never |
| 2816 | // have an error if the list is in order so this enforces defensive programming. |
| 2817 | if (!mSettings.certainty.isEnabled(Certainty::inconclusive)) |
| 2818 | return; |
| 2819 | } |
| 2820 | |
| 2821 | logChecker("CheckClass::initializerListOrder"); // style,inconclusive |
| 2822 | |
| 2823 | for (const Scope * scope : mSymbolDatabase->classAndStructScopes) { |
| 2824 | |
| 2825 | // iterate through all member functions looking for constructors |
| 2826 | for (auto func = scope->functionList.cbegin(); func != scope->functionList.cend(); ++func) { |
| 2827 | if (func->isConstructor() && func->hasBody()) { |
| 2828 | // check for initializer list |
| 2829 | const Token *tok = func->arg->link()->next(); |
| 2830 | |
| 2831 | if (tok->str() == ":") { |
| 2832 | std::vector<VarInfo> vars; |
| 2833 | tok = tok->next(); |
| 2834 | |
| 2835 | // find all variable initializations in list |
| 2836 | for (; tok && tok != func->functionScope->bodyStart; tok = tok->next()) { |
| 2837 | if (Token::Match(tok, "%name% (|{")) { |
| 2838 | const Token* const end = tok->linkAt(1); |
| 2839 | const Variable *var = scope->getVariable(tok->str()); |
| 2840 | if (var) |
| 2841 | vars.emplace_back(var, tok); |
| 2842 | else |
| 2843 | tok = end; |
| 2844 | |
| 2845 | for (; tok != end; tok = tok->next()) { |
| 2846 | if (Token::Match(tok->astParent(), ".|::")) |
| 2847 | continue; |
| 2848 | if (const Variable* argVar = scope->getVariable(tok->str())) { |
| 2849 | if (scope != argVar->scope()) |
| 2850 | continue; |
| 2851 | if (argVar->isStatic()) |
| 2852 | continue; |
| 2853 | if (tok->variable() && tok->variable()->isArgument()) |
| 2854 | continue; |
| 2855 | if (var->isPointer() && (argVar->isArray() || Token::simpleMatch(tok->astParent(), "&"))) |
| 2856 | continue; |
| 2857 | if (var->isReference()) |
| 2858 | continue; |
| 2859 | if (Token::simpleMatch(tok->astParent(), "=")) |
| 2860 | continue; |
| 2861 | vars.back().initArgs.emplace_back(argVar); |
| 2862 | } |
| 2863 | } |
| 2864 | } |
no test coverage detected