On Sun, Apr 10, 2011 at 1:33 PM, Anders Carlsson <[email protected]> wrote: > Author: andersca > Date: Sun Apr 10 15:33:22 2011 > New Revision: 129256 > > URL: http://llvm.org/viewvc/llvm-project?rev=129256&view=rev > Log: > As a first step towards fixing PR9641, add a CK_DynamicToNull cast kind which > represents a dynamic cast where we know that the result is always null. > > For example: > > struct A { > virtual ~A(); > }; > struct B final : A { }; > struct C { }; > > bool f(B* b) { > return dynamic_cast<C*>(b); > }
Adding an extra cast kind seems to complicate things for what should be a very rare case. -Eli > Modified: > cfe/trunk/include/clang/AST/Expr.h > cfe/trunk/include/clang/AST/OperationKinds.h > cfe/trunk/lib/AST/Expr.cpp > cfe/trunk/lib/AST/ExprConstant.cpp > cfe/trunk/lib/CodeGen/CGExpr.cpp > cfe/trunk/lib/CodeGen/CGExprAgg.cpp > cfe/trunk/lib/CodeGen/CGExprConstant.cpp > cfe/trunk/lib/CodeGen/CGExprScalar.cpp > cfe/trunk/lib/Sema/SemaCXXCast.cpp > cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp > > Modified: cfe/trunk/include/clang/AST/Expr.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=129256&r1=129255&r2=129256&view=diff > ============================================================================== > --- cfe/trunk/include/clang/AST/Expr.h (original) > +++ cfe/trunk/include/clang/AST/Expr.h Sun Apr 10 15:33:22 2011 > @@ -2183,6 +2183,7 @@ > // These should not have an inheritance path. > case CK_BitCast: > case CK_Dynamic: > + case CK_DynamicToNull: > case CK_ToUnion: > case CK_ArrayToPointerDecay: > case CK_FunctionToPointerDecay: > > Modified: cfe/trunk/include/clang/AST/OperationKinds.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/OperationKinds.h?rev=129256&r1=129255&r2=129256&view=diff > ============================================================================== > --- cfe/trunk/include/clang/AST/OperationKinds.h (original) > +++ cfe/trunk/include/clang/AST/OperationKinds.h Sun Apr 10 15:33:22 2011 > @@ -82,6 +82,10 @@ > /// CK_Dynamic - A C++ dynamic_cast. > CK_Dynamic, > > + /// CK_DynamicToNull - A C++ dynamic_cast that can be proven to > + /// always yield a null result. > + CK_DynamicToNull, > + > /// CK_ToUnion - The GCC cast-to-union extension. > /// int -> union { int x; float y; } > /// float -> union { int x; float y; } > > Modified: cfe/trunk/lib/AST/Expr.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=129256&r1=129255&r2=129256&view=diff > ============================================================================== > --- cfe/trunk/lib/AST/Expr.cpp (original) > +++ cfe/trunk/lib/AST/Expr.cpp Sun Apr 10 15:33:22 2011 > @@ -987,6 +987,8 @@ > return "UncheckedDerivedToBase"; > case CK_Dynamic: > return "Dynamic"; > + case CK_DynamicToNull: > + return "DynamicToNull"; > case CK_ToUnion: > return "ToUnion"; > case CK_ArrayToPointerDecay: > > Modified: cfe/trunk/lib/AST/ExprConstant.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=129256&r1=129255&r2=129256&view=diff > ============================================================================== > --- cfe/trunk/lib/AST/ExprConstant.cpp (original) > +++ cfe/trunk/lib/AST/ExprConstant.cpp Sun Apr 10 15:33:22 2011 > @@ -1768,6 +1768,7 @@ > case CK_DerivedToBase: > case CK_UncheckedDerivedToBase: > case CK_Dynamic: > + case CK_DynamicToNull: > case CK_ToUnion: > case CK_ArrayToPointerDecay: > case CK_FunctionToPointerDecay: > @@ -2315,6 +2316,7 @@ > case CK_DerivedToBase: > case CK_UncheckedDerivedToBase: > case CK_Dynamic: > + case CK_DynamicToNull: > case CK_ToUnion: > case CK_ArrayToPointerDecay: > case CK_FunctionToPointerDecay: > > Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=129256&r1=129255&r2=129256&view=diff > ============================================================================== > --- cfe/trunk/lib/CodeGen/CGExpr.cpp (original) > +++ cfe/trunk/lib/CodeGen/CGExpr.cpp Sun Apr 10 15:33:22 2011 > @@ -1867,7 +1867,8 @@ > return MakeAddrLValue(V, E->getType()); > } > > - case CK_Dynamic: { > + case CK_Dynamic: > + case CK_DynamicToNull: { > LValue LV = EmitLValue(E->getSubExpr()); > llvm::Value *V = LV.getAddress(); > const CXXDynamicCastExpr *DCE = cast<CXXDynamicCastExpr>(E); > > Modified: cfe/trunk/lib/CodeGen/CGExprAgg.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprAgg.cpp?rev=129256&r1=129255&r2=129256&view=diff > ============================================================================== > --- cfe/trunk/lib/CodeGen/CGExprAgg.cpp (original) > +++ cfe/trunk/lib/CodeGen/CGExprAgg.cpp Sun Apr 10 15:33:22 2011 > @@ -255,7 +255,10 @@ > } > > switch (E->getCastKind()) { > - case CK_Dynamic: { > + case CK_Dynamic: > + case CK_DynamicToNull: { > + > + // FIXME: Actually handle DynamicToNull here. > assert(isa<CXXDynamicCastExpr>(E) && "CK_Dynamic without a > dynamic_cast?"); > LValue LV = CGF.EmitCheckedLValue(E->getSubExpr()); > // FIXME: Do we also need to handle property references here? > > Modified: cfe/trunk/lib/CodeGen/CGExprConstant.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=129256&r1=129255&r2=129256&view=diff > ============================================================================== > --- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original) > +++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Sun Apr 10 15:33:22 2011 > @@ -552,6 +552,7 @@ > case CK_GetObjCProperty: > case CK_ToVoid: > case CK_Dynamic: > + case CK_DynamicToNull: > case CK_ResolveUnknownAnyType: > return 0; > > > Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=129256&r1=129255&r2=129256&view=diff > ============================================================================== > --- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original) > +++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Sun Apr 10 15:33:22 2011 > @@ -1053,7 +1053,8 @@ > CE->path_begin(), CE->path_end(), > ShouldNullCheckClassCastValue(CE)); > } > - case CK_Dynamic: { > + case CK_Dynamic: > + case CK_DynamicToNull: { > Value *V = Visit(const_cast<Expr*>(E)); > const CXXDynamicCastExpr *DCE = cast<CXXDynamicCastExpr>(CE); > return CGF.EmitDynamicCast(V, DCE); > > Modified: cfe/trunk/lib/Sema/SemaCXXCast.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCXXCast.cpp?rev=129256&r1=129255&r2=129256&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/SemaCXXCast.cpp (original) > +++ cfe/trunk/lib/Sema/SemaCXXCast.cpp Sun Apr 10 15:33:22 2011 > @@ -522,6 +522,14 @@ > return; > } > > + // If the source class is marked 'final', and the destination class does > not > + // derive from the source class, then we know that the result is always > null. > + if (SrcRecord->getDecl()->hasAttr<FinalAttr>() && > + !Self.IsDerivedFrom(DestPointee, SrcPointee)) { > + Kind = CK_DynamicToNull; > + return; > + } > + > // C++ 5.2.7p5 > // Upcasts are resolved statically. > if (DestRecord && Self.IsDerivedFrom(SrcPointee, DestPointee)) { > > Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=129256&r1=129255&r2=129256&view=diff > ============================================================================== > --- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original) > +++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Sun Apr 10 15:33:22 2011 > @@ -2178,6 +2178,7 @@ > // Various C++ casts that are not handled yet. > case CK_ResolveUnknownAnyType: > case CK_Dynamic: > + case CK_DynamicToNull: > case CK_ToUnion: > case CK_BaseToDerived: > case CK_NullToMemberPointer: > > > _______________________________________________ > cfe-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits > _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
