diff options
author | Filipe Cabecinhas <me@filcab.net> | 2013-08-08 01:08:17 +0000 |
---|---|---|
committer | Filipe Cabecinhas <me@filcab.net> | 2013-08-08 01:08:17 +0000 |
commit | 178a8df66006a507e8553f174904753539b54bb1 (patch) | |
tree | 1b14765787529427cf2f24082b568af46506a9e7 /clang/lib | |
parent | 59c23c0bb5c704f95d980653cfd819c8a5b94b02 (diff) | |
download | bcm5719-llvm-178a8df66006a507e8553f174904753539b54bb1.tar.gz bcm5719-llvm-178a8df66006a507e8553f174904753539b54bb1.zip |
UBSan: Fix alignment checks emitted in downcasts.
Summary:
UBSan was checking for alignment of the derived class on the pointer to
the base class, before converting. With some class hierarchies, this could
generate false positives.
Added test-case.
llvm-svn: 187948
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 12 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGExprScalar.cpp | 11 |
2 files changed, 13 insertions, 10 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 73824afc17e..0e87d8311c1 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -2764,18 +2764,18 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) { LValue LV = EmitLValue(E->getSubExpr()); - // C++11 [expr.static.cast]p2: Behavior is undefined if a downcast is - // performed and the object is not of the derived type. - if (SanitizePerformTypeCheck) - EmitTypeCheck(TCK_DowncastReference, E->getExprLoc(), - LV.getAddress(), E->getType()); - // Perform the base-to-derived conversion llvm::Value *Derived = GetAddressOfDerivedClass(LV.getAddress(), DerivedClassDecl, E->path_begin(), E->path_end(), /*NullCheckValue=*/false); + // C++11 [expr.static.cast]p2: Behavior is undefined if a downcast is + // performed and the object is not of the derived type. + if (SanitizePerformTypeCheck) + EmitTypeCheck(TCK_DowncastReference, E->getExprLoc(), + Derived, E->getType()); + return MakeAddrLValue(Derived, E->getType()); } case CK_LValueBitCast: { diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index b6bda284717..287dc6c0231 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -1234,15 +1234,18 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) { llvm::Value *V = Visit(E); + llvm::Value *Derived = + CGF.GetAddressOfDerivedClass(V, DerivedClassDecl, + CE->path_begin(), CE->path_end(), + ShouldNullCheckClassCastValue(CE)); + // C++11 [expr.static.cast]p11: Behavior is undefined if a downcast is // performed and the object is not of the derived type. if (CGF.SanitizePerformTypeCheck) CGF.EmitTypeCheck(CodeGenFunction::TCK_DowncastPointer, CE->getExprLoc(), - V, DestTy->getPointeeType()); + Derived, DestTy->getPointeeType()); - return CGF.GetAddressOfDerivedClass(V, DerivedClassDecl, - CE->path_begin(), CE->path_end(), - ShouldNullCheckClassCastValue(CE)); + return Derived; } case CK_UncheckedDerivedToBase: case CK_DerivedToBase: { |