aboutsummaryrefslogtreecommitdiff
path: root/include/clang/Analysis
diff options
context:
space:
mode:
authorKristof Umann <dkszelethus@gmail.com>2019-07-03 11:14:42 +0000
committerKristof Umann <dkszelethus@gmail.com>2019-07-03 11:14:42 +0000
commit663ca222973b595768d1f8472df02afa87c9b460 (patch)
tree9f31806faf6ba66fdc1fe243a431d7b451964c6a /include/clang/Analysis
parentee915ad903e0d476c07d0398b42b2970a4dc4b19 (diff)
[Dominators] PR42041: Skip nullpointer successors
https://bugs.llvm.org/show_bug.cgi?id=42041 In Clang's CFG, we use nullpointers to represent unreachable nodes, for example, in the included testfile, block B0 is unreachable from block B1, resulting in a nullpointer dereference somewhere in llvm::DominatorTreeBase<clang::CFGBlock, false>::recalculate. This patch fixes this issue by specializing llvm::DomTreeBuilder::SemiNCAInfo::ChildrenGetter::Get for clang::CFG to not contain nullpointer successors. Differential Revision: https://reviews.llvm.org/D62507 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@365026 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang/Analysis')
-rw-r--r--include/clang/Analysis/Analyses/Dominators.h44
1 files changed, 41 insertions, 3 deletions
diff --git a/include/clang/Analysis/Analyses/Dominators.h b/include/clang/Analysis/Analyses/Dominators.h
index 0015b0d7fd..97db381e43 100644
--- a/include/clang/Analysis/Analyses/Dominators.h
+++ b/include/clang/Analysis/Analyses/Dominators.h
@@ -155,13 +155,51 @@ private:
} // namespace clang
+namespace llvm {
+
+/// Clang's CFG contains nullpointers for unreachable succesors, e.g. when an
+/// if statement's condition is always false, it's 'then' branch is represented
+/// with a nullptr. This however will result in a nullpointer derefernece for
+/// dominator tree calculation.
+///
+/// To circumvent this, let's just crudely specialize the children getters
+/// used in LLVM's dominator tree builder.
+namespace DomTreeBuilder {
+
+using ClangCFGDomChildrenGetter =
+SemiNCAInfo<DomTreeBase<clang::CFGBlock>>::ChildrenGetter</*Inverse=*/false>;
+
+template <>
+template <>
+inline ClangCFGDomChildrenGetter::ResultTy ClangCFGDomChildrenGetter::Get(
+ clang::CFGBlock *N, std::integral_constant<bool, /*Inverse=*/false>) {
+ auto RChildren = reverse(children<NodePtr>(N));
+ ResultTy Ret(RChildren.begin(), RChildren.end());
+ Ret.erase(std::remove(Ret.begin(), Ret.end(), nullptr), Ret.end());
+ return Ret;
+}
+
+using ClangCFGDomReverseChildrenGetter =
+SemiNCAInfo<DomTreeBase<clang::CFGBlock>>::ChildrenGetter</*Inverse=*/true>;
+
+template <>
+template <>
+inline ClangCFGDomReverseChildrenGetter::ResultTy
+ClangCFGDomReverseChildrenGetter::Get(
+ clang::CFGBlock *N, std::integral_constant<bool, /*Inverse=*/true>) {
+ auto IChildren = inverse_children<NodePtr>(N);
+ ResultTy Ret(IChildren.begin(), IChildren.end());
+ Ret.erase(std::remove(Ret.begin(), Ret.end(), nullptr), Ret.end());
+ return Ret;
+}
+
+} // end of namespace DomTreeBuilder
+
//===-------------------------------------
/// DominatorTree GraphTraits specialization so the DominatorTree can be
/// iterable by generic graph iterators.
///
-namespace llvm {
-
-template <> struct GraphTraits< ::clang::DomTreeNode* > {
+template <> struct GraphTraits<clang::DomTreeNode *> {
using NodeRef = ::clang::DomTreeNode *;
using ChildIteratorType = ::clang::DomTreeNode::iterator;