From 0fee330f5754ca4b248e5bb7363e834668aff06d Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Mon, 11 Apr 2011 01:43:55 +0000 Subject: [PATCH] Add CXXDynamicCastExpr::isAlwaysNull() which will be replacing the cast kind I added. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@129263 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/ExprCXX.h | 2 ++ lib/AST/ExprCXX.cpp | 30 ++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index e926267f5c..9bb1a50be9 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -253,6 +253,8 @@ public: static CXXDynamicCastExpr *CreateEmpty(ASTContext &Context, unsigned pathSize); + bool isAlwaysNull() const; + static bool classof(const Stmt *T) { return T->getStmtClass() == CXXDynamicCastExprClass; } diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp index 526c484677..692c2c3760 100644 --- a/lib/AST/ExprCXX.cpp +++ b/lib/AST/ExprCXX.cpp @@ -482,6 +482,36 @@ CXXDynamicCastExpr *CXXDynamicCastExpr::CreateEmpty(ASTContext &C, return new (Buffer) CXXDynamicCastExpr(EmptyShell(), PathSize); } +/// isAlwaysNull - Return whether the result of the dynamic_cast is proven +/// to always be null. For example: +/// +/// struct A { }; +/// struct B final : A { }; +/// struct C { }; +/// +/// C *f(B* b) { return dynamic_cast(b); } +bool CXXDynamicCastExpr::isAlwaysNull() const +{ + QualType SrcType = getSubExpr()->getType(); + QualType DestType = getType(); + + if (const PointerType *SrcPTy = SrcType->getAs()) { + SrcType = SrcPTy->getPointeeType(); + DestType = DestType->castAs()->getPointeeType(); + } + + const CXXRecordDecl *SrcRD = + cast(SrcType->castAs()->getDecl()); + + if (!SrcRD->hasAttr()) + return false; + + const CXXRecordDecl *DestRD = + cast(DestType->castAs()->getDecl()); + + return !DestRD->isDerivedFrom(SrcRD); +} + CXXReinterpretCastExpr * CXXReinterpretCastExpr::Create(ASTContext &C, QualType T, ExprValueKind VK, CastKind K, Expr *Op, -- 2.40.0