mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-27 07:45:35 +00:00
Prevent DILocation::getMergedLocation() from creating invalid metadata.
The function's new implementation from r340583 had a bug in it that could cause an invalid scope to be generated when merging two DILocations with no common ancestor scope. This patch detects this situation and picks the scope of the first location. This is not perfect, because the scope is misleading, but on the other hand, this will be a line 0 location. rdar://problem/43687474 Differential Revision: https://reviews.llvm.org/D51238 llvm-svn: 340672
This commit is contained in:
parent
b9999617a5
commit
ac9b6078f3
@ -102,6 +102,11 @@ const DILocation *DILocation::getMergedLocation(const DILocation *LocA,
|
||||
L = L->getInlinedAt();
|
||||
}
|
||||
}
|
||||
|
||||
// If the two locations are irreconsilable, just pick one. This is misleading,
|
||||
// but on the other hand, it's a "line 0" location.
|
||||
if (!S || !isa<DILocalScope>(S))
|
||||
S = LocA->getScope();
|
||||
return DILocation::get(Result->getContext(), 0, 0, S, L);
|
||||
}
|
||||
|
||||
|
@ -860,6 +860,84 @@ TEST_F(DILocationTest, Overflow) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(DILocationTest, Merge) {
|
||||
DISubprogram *N = getSubprogram();
|
||||
DIScope *S = DILexicalBlock::get(Context, N, getFile(), 3, 4);
|
||||
|
||||
{
|
||||
// Identical.
|
||||
auto *A = DILocation::get(Context, 2, 7, N);
|
||||
auto *B = DILocation::get(Context, 2, 7, N);
|
||||
auto *M = DILocation::getMergedLocation(A, B);
|
||||
EXPECT_EQ(2u, M->getLine());
|
||||
EXPECT_EQ(7u, M->getColumn());
|
||||
EXPECT_EQ(N, M->getScope());
|
||||
}
|
||||
|
||||
{
|
||||
// Identical, different scopes.
|
||||
auto *A = DILocation::get(Context, 2, 7, N);
|
||||
auto *B = DILocation::get(Context, 2, 7, S);
|
||||
auto *M = DILocation::getMergedLocation(A, B);
|
||||
EXPECT_EQ(0u, M->getLine()); // FIXME: Should this be 2?
|
||||
EXPECT_EQ(0u, M->getColumn()); // FIXME: Should this be 7?
|
||||
EXPECT_EQ(N, M->getScope());
|
||||
}
|
||||
|
||||
{
|
||||
// Different lines, same scopes.
|
||||
auto *A = DILocation::get(Context, 1, 6, N);
|
||||
auto *B = DILocation::get(Context, 2, 7, N);
|
||||
auto *M = DILocation::getMergedLocation(A, B);
|
||||
EXPECT_EQ(0u, M->getLine());
|
||||
EXPECT_EQ(0u, M->getColumn());
|
||||
EXPECT_EQ(N, M->getScope());
|
||||
}
|
||||
|
||||
{
|
||||
// Twisty locations, all different, same function.
|
||||
auto *A = DILocation::get(Context, 1, 6, N);
|
||||
auto *B = DILocation::get(Context, 2, 7, S);
|
||||
auto *M = DILocation::getMergedLocation(A, B);
|
||||
EXPECT_EQ(0u, M->getLine());
|
||||
EXPECT_EQ(0u, M->getColumn());
|
||||
EXPECT_EQ(N, M->getScope());
|
||||
}
|
||||
|
||||
{
|
||||
// Different function, same inlined-at.
|
||||
auto *F = getFile();
|
||||
auto *SP1 = DISubprogram::getDistinct(Context, F, "a", "a", F, 0, nullptr,
|
||||
false, false, 0, nullptr, 0, 0, 0,
|
||||
DINode::FlagZero, false, nullptr);
|
||||
auto *SP2 = DISubprogram::getDistinct(Context, F, "b", "b", F, 0, nullptr,
|
||||
false, false, 0, nullptr, 0, 0, 0,
|
||||
DINode::FlagZero, false, nullptr);
|
||||
|
||||
auto *I = DILocation::get(Context, 2, 7, N);
|
||||
auto *A = DILocation::get(Context, 1, 6, SP1, I);
|
||||
auto *B = DILocation::get(Context, 2, 7, SP2, I);
|
||||
auto *M = DILocation::getMergedLocation(A, B);
|
||||
EXPECT_EQ(0u, M->getLine());
|
||||
EXPECT_EQ(0u, M->getColumn());
|
||||
EXPECT_TRUE(isa<DILocalScope>(M->getScope()));
|
||||
EXPECT_EQ(I, M->getInlinedAt());
|
||||
}
|
||||
|
||||
{
|
||||
// Completely different.
|
||||
auto *I = DILocation::get(Context, 2, 7, N);
|
||||
auto *A = DILocation::get(Context, 1, 6, S, I);
|
||||
auto *B = DILocation::get(Context, 2, 7, getSubprogram());
|
||||
auto *M = DILocation::getMergedLocation(A, B);
|
||||
EXPECT_EQ(0u, M->getLine());
|
||||
EXPECT_EQ(0u, M->getColumn());
|
||||
EXPECT_TRUE(isa<DILocalScope>(M->getScope()));
|
||||
EXPECT_EQ(S, M->getScope());
|
||||
EXPECT_EQ(nullptr, M->getInlinedAt());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(DILocationTest, getDistinct) {
|
||||
MDNode *N = getSubprogram();
|
||||
DILocation *L0 = DILocation::getDistinct(Context, 2, 7, N);
|
||||
|
Loading…
x
Reference in New Issue
Block a user