diff --git a/clang-tools-extra/clang-tidy/altera/IdDependentBackwardBranchCheck.cpp b/clang-tools-extra/clang-tidy/altera/IdDependentBackwardBranchCheck.cpp --- a/clang-tools-extra/clang-tidy/altera/IdDependentBackwardBranchCheck.cpp +++ b/clang-tools-extra/clang-tidy/altera/IdDependentBackwardBranchCheck.cpp @@ -114,7 +114,7 @@ const VarDecl *Variable) { // Record that this variable is thread-dependent. IdDepVarsMap[Variable] = - IdDependencyRecord(Variable, Variable->getBeginLoc(), + IdDependencyRecord(Variable, Statement->getBeginLoc(), Twine("assignment of ID-dependent variable ") + Variable->getNameAsString()); } @@ -142,8 +142,8 @@ // If variable isn't ID-dependent, but RefVar is. if (IdDepVarsMap.find(RefVar) != IdDepVarsMap.end()) { StringStream << "variable " << RefVar->getNameAsString(); - IdDepVarsMap[PotentialVar] = IdDependencyRecord( - PotentialVar, PotentialVar->getBeginLoc(), Message); + IdDepVarsMap[PotentialVar] = + IdDependencyRecord(PotentialVar, RefExpr->getBeginLoc(), Message); return; // Optional, as we only match only one of `RefExpr` or `MemExpr` } } @@ -152,8 +152,8 @@ // If variable isn't ID-dependent, but RefField is. if (IdDepFieldsMap.find(RefField) != IdDepFieldsMap.end()) { StringStream << "member " << RefField->getNameAsString(); - IdDepVarsMap[PotentialVar] = IdDependencyRecord( - PotentialVar, PotentialVar->getBeginLoc(), Message); + IdDepVarsMap[PotentialVar] = + IdDependencyRecord(PotentialVar, MemExpr->getBeginLoc(), Message); return; } } @@ -174,8 +174,8 @@ // If field isn't ID-dependent, but RefVar is. if (IdDepVarsMap.find(RefVar) != IdDepVarsMap.end()) { StringStream << "variable " << RefVar->getNameAsString(); - IdDepFieldsMap[PotentialField] = IdDependencyRecord( - PotentialField, PotentialField->getBeginLoc(), Message); + IdDepFieldsMap[PotentialField] = + IdDependencyRecord(PotentialField, RefExpr->getBeginLoc(), Message); return; // Optional, as we only match only one of `RefExpr` or `MemExpr` } } @@ -183,8 +183,8 @@ const auto *RefField = dyn_cast(MemExpr->getMemberDecl()); if (IdDepFieldsMap.find(RefField) != IdDepFieldsMap.end()) { StringStream << "member " << RefField->getNameAsString(); - IdDepFieldsMap[PotentialField] = IdDependencyRecord( - PotentialField, PotentialField->getBeginLoc(), Message); + IdDepFieldsMap[PotentialField] = + IdDependencyRecord(PotentialField, MemExpr->getBeginLoc(), Message); return; } } diff --git a/clang-tools-extra/test/clang-tidy/checkers/altera/id-dependent-backward-branch.cpp b/clang-tools-extra/test/clang-tidy/checkers/altera/id-dependent-backward-branch.cpp --- a/clang-tools-extra/test/clang-tidy/checkers/altera/id-dependent-backward-branch.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/altera/id-dependent-backward-branch.cpp @@ -34,6 +34,15 @@ // CHECK-NOTES: :[[@LINE-1]]:12: warning: backward branch (do loop) is ID-dependent due to variable reference to 'ThreadID' and may cause performance degradation [altera-id-dependent-backward-branch] // CHECK-NOTES: :[[@LINE-12]]:3: note: assignment of ID-dependent variable ThreadID + int ThreadIDAssigned = 0; + ThreadIDAssigned = get_local_id(0) * 2; + + for (int i = 0; i < ThreadIDAssigned; i++) { + // CHECK-NOTES: :[[@LINE-1]]:19: warning: backward branch (for loop) is ID-dependent due to variable reference to 'ThreadIDAssigned' and may cause performance degradation [altera-id-dependent-backward-branch] + // CHECK-NOTES: :[[@LINE-4]]:3: note: assignment of ID-dependent variable ThreadIDAssigned + accumulator++; + } + struct { int IDDepField; } Example; Example.IDDepField = get_local_id(0); @@ -56,11 +65,49 @@ // CHECK-NOTES: :[[@LINE-18]]:3: note: assignment of ID-dependent field IDDepField // ==== Inferred Assignments ==== - int ThreadID2 = ThreadID * 2; + int ThreadIDVarFromVar = ThreadID * 2; + for (int i = 0; i < ThreadIDVarFromVar; i++) { + // CHECK-NOTES: :[[@LINE-1]]:19: warning: backward branch (for loop) is ID-dependent due to variable reference to 'ThreadIDVarFromVar' and may cause performance degradation [altera-id-dependent-backward-branch] + // CHECK-NOTES: :[[@LINE-3]]:28: note: inferred assignment of ID-dependent value from ID-dependent variable ThreadID + accumulator++; + } + + int ThreadIDVarAssignFromVar; + ThreadIDVarAssignFromVar = ThreadID * 2; + for (int i = 0; i < ThreadIDVarAssignFromVar; i++) { + // CHECK-NOTES: :[[@LINE-1]]:19: warning: backward branch (for loop) is ID-dependent due to variable reference to 'ThreadIDVarAssignFromVar' and may cause performance degradation [altera-id-dependent-backward-branch] + // CHECK-NOTES: :[[@LINE-3]]:30: note: inferred assignment of ID-dependent value from ID-dependent variable ThreadID + accumulator++; + } + + int ThreadIDVarFromMember = Example.IDDepField * 2; + for (int i = 0; i < ThreadIDVarFromMember; i++) { + // CHECK-NOTES: :[[@LINE-1]]:19: warning: backward branch (for loop) is ID-dependent due to variable reference to 'ThreadIDVarFromMember' and may cause performance degradation [altera-id-dependent-backward-branch] + // CHECK-NOTES: :[[@LINE-3]]:31: note: inferred assignment of ID-dependent value from ID-dependent member IDDepField + accumulator++; + } + + int ThreadIDVarAssignFromMember; + ThreadIDVarAssignFromMember = Example.IDDepField * 2; + for (int i = 0; i < ThreadIDVarAssignFromMember; i++) { + // CHECK-NOTES: :[[@LINE-1]]:19: warning: backward branch (for loop) is ID-dependent due to variable reference to 'ThreadIDVarAssignFromMember' and may cause performance degradation [altera-id-dependent-backward-branch] + // CHECK-NOTES: :[[@LINE-3]]:33: note: inferred assignment of ID-dependent value from ID-dependent member IDDepField + accumulator++; + } + + struct { int IDDepFieldFromVar; } ExampleFromVar; + ExampleFromVar.IDDepFieldFromVar = ThreadID * 2; + for (int i = 0; i < ExampleFromVar.IDDepFieldFromVar; i++) { + // CHECK-NOTES: :[[@LINE-1]]:19: warning: backward branch (for loop) is ID-dependent due to member reference to 'IDDepFieldFromVar' and may cause performance degradation [altera-id-dependent-backward-branch] + // CHECK-NOTES: :[[@LINE-3]]:38: note: inferred assignment of ID-dependent member from ID-dependent variable ThreadID + accumulator++; + } - for (int i = 0; i < ThreadID2; i++) { - // CHECK-NOTES: :[[@LINE-1]]:19: warning: backward branch (for loop) is ID-dependent due to variable reference to 'ThreadID2' and may cause performance degradation [altera-id-dependent-backward-branch] - // CHECK-NOTES: :[[@LINE-4]]:3: note: inferred assignment of ID-dependent value from ID-dependent variable ThreadID + struct { int IDDepFieldFromMember; } ExampleFromMember; + ExampleFromMember.IDDepFieldFromMember = Example.IDDepField * 2; + for (int i = 0; i < ExampleFromMember.IDDepFieldFromMember; i++) { + // CHECK-NOTES: :[[@LINE-1]]:19: warning: backward branch (for loop) is ID-dependent due to member reference to 'IDDepFieldFromMember' and may cause performance degradation [altera-id-dependent-backward-branch] + // CHECK-NOTES: :[[@LINE-3]]:44: note: inferred assignment of ID-dependent member from ID-dependent member IDDepField accumulator++; } @@ -107,6 +154,13 @@ accumulator++; } while (j < NotThreadID); + int NotThreadIDAssigned = 0; + NotThreadIDAssigned = foo(0) * 2; + + for (int i = 0; i < NotThreadIDAssigned; i++) { + accumulator++; + } + struct { int NotIDDepField; } Example; Example.NotIDDepField = foo(0); @@ -123,9 +177,37 @@ } while (j < Example.NotIDDepField); // ==== Inferred Assignments ==== - int NotThreadID2 = NotThreadID * 2; + int NotThreadIDVarFromVar = NotThreadID * 2; + for (int i = 0; i < NotThreadIDVarFromVar; i++) { + accumulator++; + } + + int NotThreadIDVarAssignFromVar; + NotThreadIDVarAssignFromVar = NotThreadID * 2; + for (int i = 0; i < NotThreadIDVarAssignFromVar; i++) { + accumulator++; + } + + int NotThreadIDVarFromMember = Example.NotIDDepField * 2; + for (int i = 0; i < NotThreadIDVarFromMember; i++) { + accumulator++; + } + + int NotThreadIDVarAssignFromMember; + NotThreadIDVarAssignFromMember = Example.NotIDDepField * 2; + for (int i = 0; i < NotThreadIDVarAssignFromMember; i++) { + accumulator++; + } + + struct { int NotIDDepFieldFromVar; } ExampleFromVar; + ExampleFromVar.NotIDDepFieldFromVar = NotThreadID * 2; + for (int i = 0; i < ExampleFromVar.NotIDDepFieldFromVar; i++) { + accumulator++; + } - for (int i = 0; i < NotThreadID2; i++) { + struct { int NotIDDepFieldFromMember; } ExampleFromMember; + ExampleFromMember.NotIDDepFieldFromMember = Example.NotIDDepField * 2; + for (int i = 0; i < ExampleFromMember.NotIDDepFieldFromMember; i++) { accumulator++; }