Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

Commit 7ba1a4a

Browse files
committed
Improve merging of debug locations (fixes PR 36410)
Patch by Ulrich Weigand! Pulling this in ahead of time to unblock a crash in the swift compiler. rdar://problem/38225089
1 parent 61a7302 commit 7ba1a4a

File tree

2 files changed

+112
-7
lines changed

2 files changed

+112
-7
lines changed

lib/IR/DebugInfoMetadata.cpp

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -80,17 +80,47 @@ DILocation::getMergedLocation(const DILocation *LocA, const DILocation *LocB,
8080
if (!dyn_cast_or_null<CallInst>(ForInst))
8181
return nullptr;
8282

83+
// Find closest common scope for LocA and LocB.
84+
DIScope *CommonScope = nullptr;
85+
SmallPtrSet<DIScope *, 5> ScopesA;
86+
for (DIScope *S = LocA->getScope(); S; S = S->getScope().resolve())
87+
ScopesA.insert(S);
88+
for (DIScope *S = LocB->getScope(); S; S = S->getScope().resolve())
89+
if (ScopesA.count(S)) {
90+
CommonScope = S;
91+
break;
92+
}
93+
94+
// If no common scope exists, make up a new compiler-generated location.
95+
// At this point the inlinedAt field will be meaningless as well.
96+
if (!CommonScope)
97+
return DILocation::get(LocA->getContext(),
98+
0, 0, LocA->getInlinedAtScope());
99+
100+
// If either LocA or LocB is not inlined, the merged location does not
101+
// need to be inlined either.
102+
if (LocA->getInlinedAt() == nullptr || LocB->getInlinedAt() == nullptr)
103+
return DILocation::get(LocA->getContext(), 0, 0, CommonScope);
104+
105+
// Otherwise find the closest common inlined-at location for LocA and LocB.
106+
DILocation *CommonInlinedAt = nullptr;
83107
SmallPtrSet<DILocation *, 5> InlinedLocationsA;
84108
for (DILocation *L = LocA->getInlinedAt(); L; L = L->getInlinedAt())
85109
InlinedLocationsA.insert(L);
86-
const DILocation *Result = LocB;
87-
for (DILocation *L = LocB->getInlinedAt(); L; L = L->getInlinedAt()) {
88-
Result = L;
89-
if (InlinedLocationsA.count(L))
110+
for (DILocation *L = LocB->getInlinedAt(); L; L = L->getInlinedAt())
111+
if (InlinedLocationsA.count(L)) {
112+
CommonInlinedAt = L;
90113
break;
91-
}
92-
return DILocation::get(Result->getContext(), 0, 0, Result->getScope(),
93-
Result->getInlinedAt());
114+
}
115+
116+
// If no common inlined-at location exists, mark as inlined at a
117+
// compiler-generated location in the current function.
118+
if (!CommonInlinedAt)
119+
CommonInlinedAt = DILocation::get(LocA->getContext(),
120+
0, 0, LocA->getInlinedAtScope());
121+
122+
return DILocation::get(LocA->getContext(),
123+
0, 0, CommonScope, CommonInlinedAt);
94124
}
95125

96126
DINode::DIFlags DINode::getFlag(StringRef Flag) {

unittests/IR/MetadataTest.cpp

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -883,6 +883,81 @@ TEST_F(DILocationTest, cloneTemporary) {
883883
EXPECT_TRUE(L2->isTemporary());
884884
}
885885

886+
TEST_F(DILocationTest, getMergedLocation) {
887+
FunctionType *FT = FunctionType::get(Type::getVoidTy(Context), false);
888+
auto *F = Function::Create(FT, GlobalValue::ExternalLinkage);
889+
const CallInst *Call = CallInst::Create(F, None);
890+
891+
// Merging two identical locations should result in the same location.
892+
{
893+
DISubprogram *Prg = getSubprogram();
894+
DILocation *L1 = DILocation::get(Context, 2, 7, Prg);
895+
DILocation *L2 = DILocation::get(Context, 2, 7, Prg);
896+
const DILocation *L = DILocation::getMergedLocation(L1, L2, nullptr);
897+
EXPECT_EQ(2u, L->getLine());
898+
EXPECT_EQ(7u, L->getColumn());
899+
EXPECT_EQ(Prg, L->getScope());
900+
}
901+
// If the two locations are incompatible, there should be a null result.
902+
{
903+
DISubprogram *Prg = getSubprogram();
904+
DILocation *L1 = DILocation::get(Context, 2, 7, Prg);
905+
DILocation *L2 = DILocation::get(Context, 3, 7, Prg);
906+
const DILocation *L = DILocation::getMergedLocation(L1, L2, nullptr);
907+
EXPECT_EQ(nullptr, L);
908+
}
909+
// Unless we are merging locations for a call instruction. If the
910+
// scopes agree, the result should be a compiler-generated location
911+
// in that same scope.
912+
{
913+
DISubprogram *Prg = getSubprogram();
914+
DILocation *L1 = DILocation::get(Context, 2, 7, Prg);
915+
DILocation *L2 = DILocation::get(Context, 3, 7, Prg);
916+
const DILocation *L = DILocation::getMergedLocation(L1, L2, Call);
917+
EXPECT_EQ(0u, L->getLine());
918+
EXPECT_EQ(Prg, L->getScope());
919+
}
920+
// Likewise if the one scope is a sub-scope of the other.
921+
{
922+
DISubprogram *Prg = getSubprogram();
923+
DILexicalBlock *B = DILexicalBlock::get(Context, Prg, getFile(), 5, 7);
924+
DILocation *L1 = DILocation::get(Context, 2, 7, Prg);
925+
DILocation *L2 = DILocation::get(Context, 3, 7, B);
926+
const DILocation *L = DILocation::getMergedLocation(L1, L2, Call);
927+
EXPECT_EQ(0u, L->getLine());
928+
EXPECT_EQ(Prg, L->getScope());
929+
}
930+
// Even if the calls were inlined (possibly into different places),
931+
// if they originate from the same scope, the result should also be
932+
// a compiler-generated location in that same scope.
933+
{
934+
DISubprogram *IPrg = getSubprogram();
935+
DILocation *I1 = DILocation::get(Context, 10, 7, IPrg);
936+
DILocation *I2 = DILocation::get(Context, 11, 7, IPrg);
937+
DISubprogram *Prg = getSubprogram();
938+
DILocation *L1 = DILocation::get(Context, 2, 7, Prg, I1);
939+
DILocation *L2 = DILocation::get(Context, 3, 7, Prg, I2);
940+
const DILocation *L = DILocation::getMergedLocation(L1, L2, Call);
941+
EXPECT_EQ(0u, L->getLine());
942+
EXPECT_EQ(Prg, L->getScope());
943+
EXPECT_NE(nullptr, L->getInlinedAt());
944+
}
945+
// Likewise if the one scope is a sub-scope of the other.
946+
{
947+
DISubprogram *IPrg = getSubprogram();
948+
DILocation *I1 = DILocation::get(Context, 10, 7, IPrg);
949+
DILocation *I2 = DILocation::get(Context, 11, 7, IPrg);
950+
DISubprogram *Prg = getSubprogram();
951+
DILexicalBlock *B = DILexicalBlock::get(Context, Prg, getFile(), 5, 7);
952+
DILocation *L1 = DILocation::get(Context, 2, 7, Prg, I1);
953+
DILocation *L2 = DILocation::get(Context, 3, 7, B, I2);
954+
const DILocation *L = DILocation::getMergedLocation(L1, L2, Call);
955+
EXPECT_EQ(0u, L->getLine());
956+
EXPECT_EQ(Prg, L->getScope());
957+
EXPECT_NE(nullptr, L->getInlinedAt());
958+
}
959+
}
960+
886961
typedef MetadataTest GenericDINodeTest;
887962

888963
TEST_F(GenericDINodeTest, get) {

0 commit comments

Comments
 (0)