@@ -2143,40 +2143,9 @@ void CodeGenFunction::EmitCXXDeleteExpr(const CXXDeleteExpr *E) {
21432143 }
21442144}
21452145
2146- static bool isGLValueFromPointerDeref (const Expr *E) {
2147- E = E->IgnoreParens ();
2148-
2149- if (const auto *CE = dyn_cast<CastExpr>(E)) {
2150- if (!CE->getSubExpr ()->isGLValue ())
2151- return false ;
2152- return isGLValueFromPointerDeref (CE->getSubExpr ());
2153- }
2154-
2155- if (const auto *OVE = dyn_cast<OpaqueValueExpr>(E))
2156- return isGLValueFromPointerDeref (OVE->getSourceExpr ());
2157-
2158- if (const auto *BO = dyn_cast<BinaryOperator>(E))
2159- if (BO->getOpcode () == BO_Comma)
2160- return isGLValueFromPointerDeref (BO->getRHS ());
2161-
2162- if (const auto *ACO = dyn_cast<AbstractConditionalOperator>(E))
2163- return isGLValueFromPointerDeref (ACO->getTrueExpr ()) ||
2164- isGLValueFromPointerDeref (ACO->getFalseExpr ());
2165-
2166- // C++11 [expr.sub]p1:
2167- // The expression E1[E2] is identical (by definition) to *((E1)+(E2))
2168- if (isa<ArraySubscriptExpr>(E))
2169- return true ;
2170-
2171- if (const auto *UO = dyn_cast<UnaryOperator>(E))
2172- if (UO->getOpcode () == UO_Deref)
2173- return true ;
2174-
2175- return false ;
2176- }
2177-
21782146static llvm::Value *EmitTypeidFromVTable (CodeGenFunction &CGF, const Expr *E,
2179- llvm::Type *StdTypeInfoPtrTy) {
2147+ llvm::Type *StdTypeInfoPtrTy,
2148+ bool HasNullCheck) {
21802149 // Get the vtable pointer.
21812150 Address ThisPtr = CGF.EmitLValue (E).getAddress ();
21822151
@@ -2189,16 +2158,11 @@ static llvm::Value *EmitTypeidFromVTable(CodeGenFunction &CGF, const Expr *E,
21892158 CGF.EmitTypeCheck (CodeGenFunction::TCK_DynamicOperation, E->getExprLoc (),
21902159 ThisPtr, SrcRecordTy);
21912160
2192- // C++ [expr.typeid]p2:
2193- // If the glvalue expression is obtained by applying the unary * operator to
2194- // a pointer and the pointer is a null pointer value, the typeid expression
2195- // throws the std::bad_typeid exception.
2196- //
2197- // However, this paragraph's intent is not clear. We choose a very generous
2198- // interpretation which implores us to consider comma operators, conditional
2199- // operators, parentheses and other such constructs.
2200- if (CGF.CGM .getCXXABI ().shouldTypeidBeNullChecked (
2201- isGLValueFromPointerDeref (E), SrcRecordTy)) {
2161+ // Whether we need an explicit null pointer check. For example, with the
2162+ // Microsoft ABI, if this is a call to __RTtypeid, the null pointer check and
2163+ // exception throw is inside the __RTtypeid(nullptr) call
2164+ if (HasNullCheck &&
2165+ CGF.CGM .getCXXABI ().shouldTypeidBeNullChecked (SrcRecordTy)) {
22022166 llvm::BasicBlock *BadTypeidBlock =
22032167 CGF.createBasicBlock (" typeid.bad_typeid" );
22042168 llvm::BasicBlock *EndBlock = CGF.createBasicBlock (" typeid.end" );
@@ -2244,7 +2208,8 @@ llvm::Value *CodeGenFunction::EmitCXXTypeidExpr(const CXXTypeidExpr *E) {
22442208 // type) to which the glvalue refers.
22452209 // If the operand is already most derived object, no need to look up vtable.
22462210 if (E->isPotentiallyEvaluated () && !E->isMostDerived (getContext ()))
2247- return EmitTypeidFromVTable (*this , E->getExprOperand (), PtrTy);
2211+ return EmitTypeidFromVTable (*this , E->getExprOperand (), PtrTy,
2212+ E->hasNullCheck ());
22482213
22492214 QualType OperandTy = E->getExprOperand ()->getType ();
22502215 return MaybeASCast (CGM.GetAddrOfRTTIDescriptor (OperandTy));
0 commit comments