From f9bb9e3dd897ae6de23414809b6c615767e16458 Mon Sep 17 00:00:00 2001 From: Grigorii Gusev Date: Mon, 2 Oct 2023 22:43:06 +0300 Subject: [PATCH] private_removing: bugreport_1672139586 add message about var usage in function calls add correct support for iteration vars --- .../_src/Transformations/private_removing.cpp | 132 +++++++++++++++--- .../experts/Sapfor_2017/_src/Utils/errors.h | 102 +++++++------- .../_src/Utils/russian_errors_text.txt | 2 + 3 files changed, 170 insertions(+), 66 deletions(-) diff --git a/sapfor/experts/Sapfor_2017/_src/Transformations/private_removing.cpp b/sapfor/experts/Sapfor_2017/_src/Transformations/private_removing.cpp index adf7cea..69b8a2b 100644 --- a/sapfor/experts/Sapfor_2017/_src/Transformations/private_removing.cpp +++ b/sapfor/experts/Sapfor_2017/_src/Transformations/private_removing.cpp @@ -201,17 +201,30 @@ static void addMessageDependOnNonInvariant(vector& messages, string va messages.push_back(Messages(typeMessage::WARR, lineNum, messageR, messageE, 2017)); } -static void addMessageDoesNotMachMask(vector& messages, string varName, int loopLneNum) +static void addMessageDoesNotMachMask(vector& messages, string varName, int loopLineNum) { __spf_print(1, "WARR: cannot remove private var '%s' in loop %d - it doesn't match any fixed dimensions mask\n", - varName.c_str(), loopLneNum); + varName.c_str(), loopLineNum); wstring messageE, messageR; __spf_printToLongBuf(messageE, L"Cannot remove private var '%s' - it doesn't match any fixed dimensions mask", to_wstring(varName).c_str()); __spf_printToLongBuf(messageR, R188, to_wstring(varName).c_str()); - messages.push_back(Messages(typeMessage::WARR, loopLneNum, messageR, messageE, 2016)); + messages.push_back(Messages(typeMessage::WARR, loopLineNum, messageR, messageE, 2016)); +} + +static void addMessageUsageInFunctionCall(vector& messages, string varName, int loopLineNum, int lineNum) +{ + __spf_print(1, "WARR: cannot remove private var '%s' in loop %d - it is used in function call in line %d\n", + varName.c_str(), loopLineNum, lineNum); + + wstring messageE, messageR; + __spf_printToLongBuf(messageE, L"Cannot remove private var '%s' - it is used in function call in line %d", + to_wstring(varName).c_str(), lineNum); + __spf_printToLongBuf(messageR, R203, to_wstring(varName).c_str(), lineNum); + + messages.push_back(Messages(typeMessage::WARR, lineNum, messageR, messageE, 2025)); } /* ****************************************** * @@ -657,6 +670,46 @@ static vector::const_iterator findInsertedStmt(const vectorsymbol() != nullptr && (exp->variant() == FUNC_CALL || exp->variant() == PROC_CALL)) + return isSymbolInExpression(var, exp); + + return isVarUsedInFunctionCall(var, exp->lhs()) || isVarUsedInFunctionCall(var, exp->rhs()); +} + +// isArrayUsedInFunctionCall checks if arraySym is used in any function call in stmt (as argument) +// and writes message if true +static bool isArrayUsedInFunctionCall(SgSymbol* arraySym, SgStatement* stmt, vector& messages) +{ + for (SgStatement* st = stmt; st != stmt->lastNodeOfStmt(); st = st->lexNext()) + { + bool isUsed = false; + if (st->variant() == PROC_STAT) + for (int i = 0; i < 3; ++i) + if (isSymbolInExpression(arraySym, st->expr(i))) + isUsed = true; + + if (!isUsed) + for (int i = 0; i < 3; ++i) + if (isVarUsedInFunctionCall(arraySym, st->expr(i))) + isUsed = true; + + if (isUsed) + { + addMessageUsageInFunctionCall(messages, arraySym->identifier(), + stmt->lineNumber(), st->lineNumber()); + return true; + } + } + + return false; +} + // matchesFixedDimensionsMask checks if all array references have INT_VAL value in fixed dimension // and writes found mismatches to messages static bool matchesFixedDimensionsMask(const vector& arrayRefs, @@ -675,6 +728,8 @@ static bool matchesFixedDimensionsMask(const vector& arrayRefs, static bool defStmtRefsMatchesMask(SgStatement* loopStmt, const vector& fixedDimensions, SgSymbol* arraySym) { + // TODO: , VAR_REF - + // , a * i + b, i for (SgStatement* st = loopStmt; st != loopStmt->lastNodeOfStmt(); st = st->lexNext()) { if (st->variant() != ASSIGN_STAT) @@ -715,7 +770,8 @@ static string sunparseFixedDimensionsVector(const vector& fixedDimensions) { string result = "<"; result.reserve(result.size() + 7 * fixedDimensions.size()); - for (int i = 0; i < fixedDimensions.size(); ++i) { + for (int i = 0; i < fixedDimensions.size(); ++i) + { if (fixedDimensions[i] == true) result += "true"; else @@ -734,11 +790,19 @@ static string sunparseFixedDimensionsVector(const vector& fixedDimensions) static vector getFixedDimensionsMask(const vector& arrayRefs, vector& messages, int loopLineNum) { - int fixedDimensionsNumber = arrayRefs[0]->numberOfSubscripts(); - vector resultMask(fixedDimensionsNumber, true); - for (const auto arrayRef : arrayRefs) { + int numberOfDimensions = arrayRefs[0]->numberOfSubscripts(); + if (numberOfDimensions == 0) // invalid array reference + return vector{}; + + for (const auto arrayRef : arrayRefs) + if (arrayRef->numberOfSubscripts() != numberOfDimensions) // invalid array reference + return vector{}; + + vector resultMask(numberOfDimensions, true); + for (const auto arrayRef : arrayRefs) + { vector fixedDimensions = getFixedDimensionsVector(arrayRef); - for (int i = 0; i < fixedDimensionsNumber; ++i) + for (int i = 0; i < numberOfDimensions; ++i) resultMask[i] = resultMask[i] && fixedDimensions[i]; } @@ -1073,10 +1137,22 @@ static void fillFixedSubscriptsVectorsOfAllVars(SgExpression* exp, if (exp->symbol() != nullptr) { if (exp->variant() == VAR_REF) + { + for (const auto& elem : vec) + if (elem.first == exp->symbol()->identifier()) + return; + vec.push_back(make_pair(exp->symbol()->identifier(), vector{})); + } else if (exp->variant() == ARRAY_REF) + { vec.push_back(make_pair(exp->symbol()->identifier(), getFixedSubscriptsVector((SgArrayRefExp*)exp))); + + SgExprListExp* exprList = (SgExprListExp*)exp->lhs(); + for (int i = 0; i < exprList->length(); ++i) + fillFixedSubscriptsVectorsOfAllVars(exprList->elem(i), vec); + } return; } @@ -1119,6 +1195,20 @@ pair> findVarInRDSet(map return make_pair(nullptr, set{}); } +// fillIterationVariables fill vars set with iteration variables of all loops +// from stmt to outerLoopStmt +static void fillIterationVars(SgStatement *stmt, SgStatement* outerLoopStmt, set& vars) +{ + if (stmt == nullptr) + return; + + if (stmt->variant() == FOR_NODE) + vars.insert(((SgForStmt*)stmt)->doName()->identifier()); + + if (stmt->id() != outerLoopStmt->id()) + fillIterationVars(stmt->controlParent(), outerLoopStmt, vars); +} + // checkDefUsePair checks if def statement from pair can be substituted into use statement // and creates messages static bool checkDefUsePair(DefUseStmtsPair defUse, LoopGraph* loop, const CFG_Type& CFGraph, @@ -1127,9 +1217,6 @@ static bool checkDefUsePair(DefUseStmtsPair defUse, LoopGraph* loop, const CFG_T if (defUse.first->lineNumber() > defUse.second->lineNumber()) return false; - while (loop->perfectLoop != 1) - loop = loop->children[0]; - vector>> dependOnVars; SgArrayRefExp* defRef = (SgArrayRefExp*)defUse.first->expr(0); @@ -1145,14 +1232,21 @@ static bool checkDefUsePair(DefUseStmtsPair defUse, LoopGraph* loop, const CFG_T fillFixedSubscriptsVectorsOfAllVars(expToSubst, dependOnVars); } + set iterationVars{}; + fillIterationVars(defUse.second, loop->loop->GetOriginal(), iterationVars); + auto defInsAndBlock = getInstructionAndBlockByStatement(CFGraph, defUse.first); const auto& defRD_In = defInsAndBlock.second->getRD_In(); auto useInsAndBlock = getInstructionAndBlockByStatement(CFGraph, defUse.second); const auto& useRD_In = useInsAndBlock.second->getRD_In(); - for (const auto& var : dependOnVars) // checking scalar vars + for (const auto& var : dependOnVars) { - if (var.second.size() == 0) + if (var.second.size() == 0) // check scalar vars { + // iteration var doesn't obstruct the removing: + if (iterationVars.find(var.first) != iterationVars.end()) + continue; + auto defArg = findVarInRDSet(defRD_In, var.first); if (defArg.first == nullptr) // there is no any RD for common vars or parameters continue; @@ -1185,6 +1279,9 @@ static bool checkDefUsePair(DefUseStmtsPair defUse, LoopGraph* loop, const CFG_T auto defLoopStmt = getScopeLoopStmt(defUse.first); auto useLoopStmt = getScopeLoopStmt(defUse.second); + while (loop->perfectLoop != 1) // (what is it? - ) + loop = loop->children[0]; + auto defLoop = findLoop(loop, defLoopStmt); auto useLoop = findLoop(loop, useLoopStmt); @@ -1317,10 +1414,13 @@ void removePrivatesAnalysis(vector& loopGraphs, if (arrayToRemove == nullptr) // no array to remove break; - vector fixedDimensionsMask = getFixedDimensionsMask(arrayRefs, messages, loop->lineNum); + if (isArrayUsedInFunctionCall(arrayToRemove, loopStmt, messages)) + continue; - if (!matchesFixedDimensionsMask(arrayRefs, fixedDimensionsMask) - || !defStmtRefsMatchesMask(loopStmt, fixedDimensionsMask, arrayToRemove)) + vector fixedDimensionsMask = getFixedDimensionsMask(arrayRefs, messages, loop->lineNum); + if (fixedDimensionsMask.empty() || + !matchesFixedDimensionsMask(arrayRefs, fixedDimensionsMask) || + !defStmtRefsMatchesMask(loopStmt, fixedDimensionsMask, arrayToRemove)) { addMessageDoesNotMachMask(messages, arrayToRemove->identifier(), loop->lineNum); continue; diff --git a/sapfor/experts/Sapfor_2017/_src/Utils/errors.h b/sapfor/experts/Sapfor_2017/_src/Utils/errors.h index 2df946d..db929b3 100644 --- a/sapfor/experts/Sapfor_2017/_src/Utils/errors.h +++ b/sapfor/experts/Sapfor_2017/_src/Utils/errors.h @@ -274,7 +274,7 @@ static void printStackTrace() { }; } \ } while (0) -// Свободный - R203 +// Свободный - R204 // Гайд по русификации сообщений: При добавлении нового сообщения, меняется последний сводобный идентификатор. // В этом файле остаются только спецификаторы, для которых будет заполнен текст. Полный текст пишется в файле // russian_errors_text.txt. Спецификаторы там тоже сохраняются, по ним в визуализаторе будет восстановлен @@ -283,14 +283,14 @@ static void printStackTrace() { }; //russian messages //1001 static const wchar_t *R1 = L"R1:%ls#%ls#%ls"; -static const wchar_t* RR1_1 = L"RR1_1:"; -static const wchar_t* RR1_2 = L"RR1_2:"; -static const wchar_t* RR1_3 = L"RR1_3:"; -static const wchar_t* RR1_4 = L"RR1_4:"; -static const wchar_t* RR1_5 = L"RR1_5:"; -static const wchar_t* RR1_6 = L"RR1_6:"; -static const wchar_t* RR1_7 = L"RR1_7:"; -static const wchar_t* RR1_8 = L"RR1_8:"; +static const wchar_t *RR1_1 = L"RR1_1:"; +static const wchar_t *RR1_2 = L"RR1_2:"; +static const wchar_t *RR1_3 = L"RR1_3:"; +static const wchar_t *RR1_4 = L"RR1_4:"; +static const wchar_t *RR1_5 = L"RR1_5:"; +static const wchar_t *RR1_6 = L"RR1_6:"; +static const wchar_t *RR1_7 = L"RR1_7:"; +static const wchar_t *RR1_8 = L"RR1_8:"; static const wchar_t *R2 = L"R2:"; static const wchar_t *R3 = L"R3:"; @@ -339,7 +339,7 @@ static const wchar_t *R35 = L"R35:"; static const wchar_t *R36 = L"R36:%s"; //1012 static const wchar_t *R37 = L"R37:%s"; -static const wchar_t* R149 = L"R149:%s"; +static const wchar_t *R149 = L"R149:%s"; //1013 static const wchar_t *R38 = L"R38:%s"; static const wchar_t *R39 = L"R39:%s#%s#%s#%s#%d#%s"; @@ -347,8 +347,8 @@ static const wchar_t *R40 = L"R40:%s"; static const wchar_t *R41 = L"R41:%s#%s#%d#%s"; static const wchar_t *R42 = L"R42:%s#%s#%ls"; -static const wchar_t* RR42_1 = L"RR42_1:"; -static const wchar_t* RR42_2 = L"RR42_2:"; +static const wchar_t *RR42_1 = L"RR42_1:"; +static const wchar_t *RR42_2 = L"RR42_2:"; static const wchar_t *R43 = L"R43:%s#%s#%d#%d"; static const wchar_t *R44 = L"R44:%s#%s"; @@ -383,17 +383,17 @@ static const wchar_t *R59 = L"R59:%s"; static const wchar_t *R60 = L"R60:%s"; static const wchar_t *R61 = L"R61:%s"; //1027 -static const wchar_t* R179 = L"R179:"; +static const wchar_t *R179 = L"R179:"; //1028 static const wchar_t *R62 = L"R62:%s"; //1029 && 1030 -static const wchar_t* R158 = L"R158:%s"; -static const wchar_t* R159 = L"R159:%s"; -static const wchar_t* R160 = L"R160:%s"; -static const wchar_t* R161 = L"R161:%s"; -static const wchar_t* R162 = L"R162:%s"; -static const wchar_t* R163 = L"R163:%s"; -static const wchar_t* RR158_1 = L"RR158_1:"; +static const wchar_t *R158 = L"R158:%s"; +static const wchar_t *R159 = L"R159:%s"; +static const wchar_t *R160 = L"R160:%s"; +static const wchar_t *R161 = L"R161:%s"; +static const wchar_t *R162 = L"R162:%s"; +static const wchar_t *R163 = L"R163:%s"; +static const wchar_t *RR158_1 = L"RR158_1:"; //1031 static const wchar_t *R63 = L"R63:%s#%d"; //1032 @@ -464,13 +464,13 @@ static const wchar_t *R157 = L"R157:%s#%s"; //1057 static const wchar_t *R175 = L"R175:%s"; //1058 -static const wchar_t* R176 = L"R176:"; +static const wchar_t *R176 = L"R176:"; //1059 -static const wchar_t* R182 = L"R176:%s"; +static const wchar_t *R182 = L"R176:%s"; //1060 -static const wchar_t* R183 = L"R183:"; +static const wchar_t *R183 = L"R183:"; //1061 -static const wchar_t* R184 = L"R184:%s"; +static const wchar_t *R184 = L"R184:%s"; //2001 static const wchar_t *R94 = L"R94:"; @@ -500,42 +500,44 @@ static const wchar_t *R107 = L"R107:"; //2011 static const wchar_t *R177 = L"R177:"; //2012 -static const wchar_t* R173 = L"R173:"; +static const wchar_t *R173 = L"R173:"; //2013 -static const wchar_t* R174 = L"R174:%s"; +static const wchar_t *R174 = L"R174:%s"; //2014 -static const wchar_t* R180 = L"R180:%s#%s"; +static const wchar_t *R180 = L"R180:%s#%s"; //2015 -static const wchar_t* R185 = L"R185:"; -static const wchar_t* R186 = L"R186:"; -static const wchar_t* R187 = L"R187:"; -static const wchar_t* R195 = L"R195:"; +static const wchar_t *R185 = L"R185:"; +static const wchar_t *R186 = L"R186:"; +static const wchar_t *R187 = L"R187:"; +static const wchar_t *R195 = L"R195:"; //2016 -static const wchar_t* R188 = L"R188:%s"; +static const wchar_t *R188 = L"R188:%s"; //2017 -static const wchar_t* R189 = L"R189:%s"; -static const wchar_t* R190 = L"R190:%s#%s"; +static const wchar_t *R189 = L"R189:%s"; +static const wchar_t *R190 = L"R190:%s#%s"; //2018 -static const wchar_t* R191 = L"R191:%s"; -static const wchar_t* R201 = L"R201:%s"; +static const wchar_t *R191 = L"R191:%s"; +static const wchar_t *R201 = L"R201:%s"; //2019 -static const wchar_t* R192 = L"R192:%s"; +static const wchar_t *R192 = L"R192:%s"; //2020 -static const wchar_t* R193 = L"R193:%s"; +static const wchar_t *R193 = L"R193:%s"; //2021 -static const wchar_t* R194 = L"R194:%s"; +static const wchar_t *R194 = L"R194:%s"; //2022 -static const wchar_t* R196 = L"R196:"; +static const wchar_t *R196 = L"R196:"; //2023 -static const wchar_t* R197 = L"R197:"; +static const wchar_t *R197 = L"R197:"; //2024 -static const wchar_t* R198 = L"R198:%d"; +static const wchar_t *R198 = L"R198:%d"; +//2025 +static const wchar_t *R203 = L"R203:%s%d"; //3001 static const wchar_t *R108 = L"R108:%s"; //3002 static const wchar_t *R109 = L"R109:%s#%d"; -static const wchar_t* R200 = L"R200:%s#%d"; +static const wchar_t *R200 = L"R200:%s#%d"; //3003 static const wchar_t *R110 = L"R110:%s#%s#%d"; //3004 @@ -555,11 +557,11 @@ static const wchar_t *R121 = L"R121:"; static const wchar_t *R122 = L"R122:"; static const wchar_t *R123 = L"R123:"; static const wchar_t *R124 = L"R124:%s#%s#%d#%s#%d#%d"; -static const wchar_t* R125 = L"R124:%s#%s#%d#%s#%d"; +static const wchar_t *R125 = L"R124:%s#%s#%d#%s#%d"; static const wchar_t *R144 = L"R144:"; static const wchar_t *R145 = L"R145:"; -static const wchar_t* R178 = L"R178:"; -static const wchar_t* R199 = L"R199:"; +static const wchar_t *R178 = L"R178:"; +static const wchar_t *R199 = L"R199:"; //3007 static const wchar_t *R126 = L"R126:%s#%d#%d"; static const wchar_t *R127 = L"R127:"; @@ -592,14 +594,14 @@ static const wchar_t *R139 = L"R139:%s#%s"; //3020 static const wchar_t *R140 = L"R140:%s"; static const wchar_t *R141 = L"R141:%s"; -static const wchar_t* R153 = L"R153:%s"; +static const wchar_t *R153 = L"R153:%s"; static const wchar_t *R142 = L"R142:%s"; //3021 -static const wchar_t* R151 = L"R151:"; +static const wchar_t *R151 = L"R151:"; //3022 -static const wchar_t* R171 = L"R171:%s"; +static const wchar_t *R171 = L"R171:%s"; //3023 -static const wchar_t* R202 = L"R202:%s"; +static const wchar_t *R202 = L"R202:%s"; //4001 //---TODO ошибки из SAGE diff --git a/sapfor/experts/Sapfor_2017/_src/Utils/russian_errors_text.txt b/sapfor/experts/Sapfor_2017/_src/Utils/russian_errors_text.txt index dae2791..967276f 100644 --- a/sapfor/experts/Sapfor_2017/_src/Utils/russian_errors_text.txt +++ b/sapfor/experts/Sapfor_2017/_src/Utils/russian_errors_text.txt @@ -242,6 +242,8 @@ R196 = "Невозможно выполнить преобразование ц R197 = "Преобразование не может быть выполнено - не произошло никаких изменений в коде" //2024 R198 = "Цикл на строке %d был удалён" +//2025 +R203 = "Нельзя удалить приватную переменную '%s' - она используется в вызове функции на строке %d" //3001 R108 = "Добавлена across-зависимость к массиву '%s' в цикле"