summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdrian Prantl <aprantl@apple.com>2018-08-24 23:30:57 +0000
committerAdrian Prantl <aprantl@apple.com>2018-08-24 23:30:57 +0000
commit4ddd0596350d102693839349ba4d741a5bbae427 (patch)
tree38a3bed540300c1b19c8ef5da0a49132df2a41b5
parent2b1dc39d1885b1dc014e76977488bbc6eae57cb6 (diff)
downloadbcm5719-llvm-4ddd0596350d102693839349ba4d741a5bbae427.tar.gz
bcm5719-llvm-4ddd0596350d102693839349ba4d741a5bbae427.zip
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
-rw-r--r--llvm/lib/IR/DebugInfoMetadata.cpp5
-rw-r--r--llvm/unittests/IR/MetadataTest.cpp78
2 files changed, 83 insertions, 0 deletions
diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp
index 0ceded07679..7a6160244ec 100644
--- a/llvm/lib/IR/DebugInfoMetadata.cpp
+++ b/llvm/lib/IR/DebugInfoMetadata.cpp
@@ -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);
}
diff --git a/llvm/unittests/IR/MetadataTest.cpp b/llvm/unittests/IR/MetadataTest.cpp
index 9bb54c4deb0..48c6cfa9ac8 100644
--- a/llvm/unittests/IR/MetadataTest.cpp
+++ b/llvm/unittests/IR/MetadataTest.cpp
@@ -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);
OpenPOWER on IntegriCloud