| 387 | } |
| 388 | |
| 389 | int ArgFlow::findRelatedField(Value &V, SmallSet<Value *, 8> &VisitedValues, |
| 390 | ArgFlow &ParentResult) { |
| 391 | int RelatedField = -1; |
| 392 | |
| 393 | if (VisitedValues.find(&V) != VisitedValues.end() || isa<Constant>(&V) || |
| 394 | isa<CmpInst>(&V)) { |
| 395 | return RelatedField; |
| 396 | } |
| 397 | |
| 398 | if (auto *I = dyn_cast<Instruction>(&V)) { |
| 399 | if (I->isTerminator()) |
| 400 | return RelatedField; |
| 401 | VisitedValues.insert(&V); |
| 402 | |
| 403 | if (isUnionFieldAccess(I) || isa<CallBase>(I)) { |
| 404 | return RelatedField; |
| 405 | } |
| 406 | |
| 407 | if (auto *GEP = dyn_cast<GetElementPtrInst>(I)) { |
| 408 | for (auto Result : ParentResult.STInfo->FieldResults) { |
| 409 | if (!Result.second) |
| 410 | continue; |
| 411 | unsigned FieldNum = Result.first; |
| 412 | auto FieldResult = *Result.second; |
| 413 | |
| 414 | if (FieldResult.FDInfo->Values.find(GEP) != |
| 415 | FieldResult.FDInfo->Values.end()) { |
| 416 | return FieldNum; |
| 417 | } |
| 418 | } |
| 419 | return RelatedField; |
| 420 | } |
| 421 | |
| 422 | for (auto *O : I->operand_values()) { |
| 423 | if (isa<Constant>(O)) |
| 424 | continue; |
| 425 | |
| 426 | RelatedField = this->findRelatedField(*O, VisitedValues, ParentResult); |
| 427 | if (RelatedField > -1) |
| 428 | return RelatedField; |
| 429 | } |
| 430 | } |
| 431 | |
| 432 | for (auto *U : V.users()) { |
| 433 | RelatedField = findRelatedField(*U, VisitedValues, ParentResult); |
| 434 | if (RelatedField > -1) |
| 435 | return RelatedField; |
| 436 | } |
| 437 | |
| 438 | return RelatedField; |
| 439 | } |
| 440 | |
| 441 | ArgFlow::FieldInfo::FieldInfo(unsigned FieldNum, ArgFlow &Parent) |
| 442 | : FieldNum(FieldNum), Parent(Parent) {} |
nothing calls this directly
no test coverage detected