| 3861 | } |
| 3862 | |
| 3863 | void CheckOtherImpl::checkEvaluationOrder() |
| 3864 | { |
| 3865 | logChecker("CheckOther::checkEvaluationOrder"); |
| 3866 | const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); |
| 3867 | for (const Scope * functionScope : symbolDatabase->functionScopes) { |
| 3868 | for (const Token* tok = functionScope->bodyStart; tok != functionScope->bodyEnd; tok = tok->next()) { |
| 3869 | if (!tok->isIncDecOp() && !tok->isAssignmentOp()) |
| 3870 | continue; |
| 3871 | if (!tok->astOperand1()) |
| 3872 | continue; |
| 3873 | if (isDesignatedInitializer(tok->astOperand1())) |
| 3874 | continue; |
| 3875 | for (const Token *tok2 = tok;; tok2 = tok2->astParent()) { |
| 3876 | // If ast parent is a sequence point then break |
| 3877 | const Token * const parent = tok2->astParent(); |
| 3878 | if (!parent) |
| 3879 | break; |
| 3880 | if (Token::Match(parent, "%oror%|&&|?|:|;")) |
| 3881 | break; |
| 3882 | if (parent->str() == ",") { |
| 3883 | const Token *par = parent; |
| 3884 | while (Token::simpleMatch(par,",")) |
| 3885 | par = par->astParent(); |
| 3886 | // not function or in a while clause => break |
| 3887 | if (!(par && par->str() == "(" && par->astOperand2() && par->strAt(-1) != "while")) |
| 3888 | break; |
| 3889 | // control flow (if|while|etc) => break |
| 3890 | if (Token::simpleMatch(par->link(),") {")) |
| 3891 | break; |
| 3892 | // sequence point in function argument: dostuff((1,2),3) => break |
| 3893 | par = par->next(); |
| 3894 | while (par && (par->previous() != parent)) |
| 3895 | par = par->nextArgument(); |
| 3896 | if (!par) |
| 3897 | break; |
| 3898 | } |
| 3899 | if (parent->str() == "(" && parent->astOperand2()) |
| 3900 | break; |
| 3901 | |
| 3902 | bool foundError{false}, foundUnspecified{false}, bSelfAssignmentError{false}; |
| 3903 | if (mTokenizer->isCPP() && mSettings.standards.cpp >= Standards::CPP11) { |
| 3904 | if (mSettings.standards.cpp >= Standards::CPP17) |
| 3905 | foundError = checkEvaluationOrderCpp17(tok, tok2, parent, mSettings, foundUnspecified); |
| 3906 | else |
| 3907 | foundError = checkEvaluationOrderCpp11(tok, tok2, parent, mSettings); |
| 3908 | } |
| 3909 | else |
| 3910 | foundError = checkEvaluationOrderC(tok, tok2, parent, mSettings, bSelfAssignmentError); |
| 3911 | |
| 3912 | if (foundError) { |
| 3913 | unknownEvaluationOrder(parent, foundUnspecified); |
| 3914 | break; |
| 3915 | } |
| 3916 | if (bSelfAssignmentError) { |
| 3917 | selfAssignmentError(parent, tok->astOperand1()->expressionString()); |
| 3918 | break; |
| 3919 | } |
| 3920 | } |
no test coverage detected