@@ -2056,6 +2056,15 @@ static llvm::Value *EmitTypeidFromVTable(CodeGenFunction &CGF, const Expr *E,
2056
2056
// Get the vtable pointer.
2057
2057
Address ThisPtr = CGF.EmitLValue (E).getAddress ();
2058
2058
2059
+ QualType SrcRecordTy = E->getType ();
2060
+
2061
+ // C++ [class.cdtor]p4:
2062
+ // If the operand of typeid refers to the object under construction or
2063
+ // destruction and the static type of the operand is neither the constructor
2064
+ // or destructor’s class nor one of its bases, the behavior is undefined.
2065
+ CGF.EmitTypeCheck (CodeGenFunction::TCK_DynamicOperation, E->getExprLoc (),
2066
+ ThisPtr.getPointer (), SrcRecordTy);
2067
+
2059
2068
// C++ [expr.typeid]p2:
2060
2069
// If the glvalue expression is obtained by applying the unary * operator to
2061
2070
// 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,
2064
2073
// However, this paragraph's intent is not clear. We choose a very generous
2065
2074
// interpretation which implores us to consider comma operators, conditional
2066
2075
// operators, parentheses and other such constructs.
2067
- QualType SrcRecordTy = E->getType ();
2068
2076
if (CGF.CGM .getCXXABI ().shouldTypeidBeNullChecked (
2069
2077
isGLValueFromPointerDeref (E), SrcRecordTy)) {
2070
2078
llvm::BasicBlock *BadTypeidBlock =
@@ -2127,10 +2135,6 @@ llvm::Value *CodeGenFunction::EmitDynamicCast(Address ThisAddr,
2127
2135
CGM.EmitExplicitCastExprType (DCE, this );
2128
2136
QualType DestTy = DCE->getTypeAsWritten ();
2129
2137
2130
- if (DCE->isAlwaysNull ())
2131
- if (llvm::Value *T = EmitDynamicCastToNull (*this , DestTy))
2132
- return T;
2133
-
2134
2138
QualType SrcTy = DCE->getSubExpr ()->getType ();
2135
2139
2136
2140
// C++ [expr.dynamic.cast]p7:
@@ -2151,6 +2155,18 @@ llvm::Value *CodeGenFunction::EmitDynamicCast(Address ThisAddr,
2151
2155
DestRecordTy = DestTy->castAs <ReferenceType>()->getPointeeType ();
2152
2156
}
2153
2157
2158
+ // C++ [class.cdtor]p5:
2159
+ // If the operand of the dynamic_cast refers to the object under
2160
+ // construction or destruction and the static type of the operand is not a
2161
+ // pointer to or object of the constructor or destructor’s own class or one
2162
+ // of its bases, the dynamic_cast results in undefined behavior.
2163
+ EmitTypeCheck (TCK_DynamicOperation, DCE->getExprLoc (), ThisAddr.getPointer (),
2164
+ SrcRecordTy);
2165
+
2166
+ if (DCE->isAlwaysNull ())
2167
+ if (llvm::Value *T = EmitDynamicCastToNull (*this , DestTy))
2168
+ return T;
2169
+
2154
2170
assert (SrcRecordTy->isRecordType () && " source type must be a record type!" );
2155
2171
2156
2172
// C++ [expr.dynamic.cast]p4:
0 commit comments