diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2017-12-28 21:23:03 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2017-12-28 21:23:03 +0000 | 
| commit | 55e6d896ad333f07bb3b1ba487df214fc268a4ab (patch) | |
| tree | 9ac2087dfbe8507c56dd39d17cad42836448829f /lib/CodeGen/CGExprCXX.cpp | |
| parent | 1de93ee5610e8a97e753c881c574f8d994e71373 (diff) | |
Diffstat (limited to 'lib/CodeGen/CGExprCXX.cpp')
| -rw-r--r-- | lib/CodeGen/CGExprCXX.cpp | 26 | 
1 files changed, 21 insertions, 5 deletions
| diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp index 0749b0ac46a7..c32f1e5415da 100644 --- a/lib/CodeGen/CGExprCXX.cpp +++ b/lib/CodeGen/CGExprCXX.cpp @@ -2056,6 +2056,15 @@ static llvm::Value *EmitTypeidFromVTable(CodeGenFunction &CGF, const Expr *E,    // Get the vtable pointer.    Address ThisPtr = CGF.EmitLValue(E).getAddress(); +  QualType SrcRecordTy = E->getType(); + +  // C++ [class.cdtor]p4: +  //   If the operand of typeid refers to the object under construction or +  //   destruction and the static type of the operand is neither the constructor +  //   or destructor’s class nor one of its bases, the behavior is undefined. +  CGF.EmitTypeCheck(CodeGenFunction::TCK_DynamicOperation, E->getExprLoc(), +                    ThisPtr.getPointer(), SrcRecordTy); +    // C++ [expr.typeid]p2:    //   If the glvalue expression is obtained by applying the unary * operator to    //   a pointer and the pointer is a null pointer value, the typeid expression @@ -2064,7 +2073,6 @@ static llvm::Value *EmitTypeidFromVTable(CodeGenFunction &CGF, const Expr *E,    // However, this paragraph's intent is not clear.  We choose a very generous    // interpretation which implores us to consider comma operators, conditional    // operators, parentheses and other such constructs. -  QualType SrcRecordTy = E->getType();    if (CGF.CGM.getCXXABI().shouldTypeidBeNullChecked(            isGLValueFromPointerDeref(E), SrcRecordTy)) {      llvm::BasicBlock *BadTypeidBlock = @@ -2127,10 +2135,6 @@ llvm::Value *CodeGenFunction::EmitDynamicCast(Address ThisAddr,    CGM.EmitExplicitCastExprType(DCE, this);    QualType DestTy = DCE->getTypeAsWritten(); -  if (DCE->isAlwaysNull()) -    if (llvm::Value *T = EmitDynamicCastToNull(*this, DestTy)) -      return T; -    QualType SrcTy = DCE->getSubExpr()->getType();    // C++ [expr.dynamic.cast]p7: @@ -2151,6 +2155,18 @@ llvm::Value *CodeGenFunction::EmitDynamicCast(Address ThisAddr,      DestRecordTy = DestTy->castAs<ReferenceType>()->getPointeeType();    } +  // C++ [class.cdtor]p5: +  //   If the operand of the dynamic_cast refers to the object under +  //   construction or destruction and the static type of the operand is not a +  //   pointer to or object of the constructor or destructor’s own class or one +  //   of its bases, the dynamic_cast results in undefined behavior. +  EmitTypeCheck(TCK_DynamicOperation, DCE->getExprLoc(), ThisAddr.getPointer(), +                SrcRecordTy); + +  if (DCE->isAlwaysNull()) +    if (llvm::Value *T = EmitDynamicCastToNull(*this, DestTy)) +      return T; +    assert(SrcRecordTy->isRecordType() && "source type must be a record type!");    // C++ [expr.dynamic.cast]p4:  | 
