@@ -2143,40 +2143,9 @@ void CodeGenFunction::EmitCXXDeleteExpr(const CXXDeleteExpr *E) {
2143
2143
}
2144
2144
}
2145
2145
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
-
2178
2146
static llvm::Value *EmitTypeidFromVTable (CodeGenFunction &CGF, const Expr *E,
2179
- llvm::Type *StdTypeInfoPtrTy) {
2147
+ llvm::Type *StdTypeInfoPtrTy,
2148
+ bool HasNullCheck) {
2180
2149
// Get the vtable pointer.
2181
2150
Address ThisPtr = CGF.EmitLValue (E).getAddress ();
2182
2151
@@ -2189,16 +2158,11 @@ static llvm::Value *EmitTypeidFromVTable(CodeGenFunction &CGF, const Expr *E,
2189
2158
CGF.EmitTypeCheck (CodeGenFunction::TCK_DynamicOperation, E->getExprLoc (),
2190
2159
ThisPtr, SrcRecordTy);
2191
2160
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)) {
2202
2166
llvm::BasicBlock *BadTypeidBlock =
2203
2167
CGF.createBasicBlock (" typeid.bad_typeid" );
2204
2168
llvm::BasicBlock *EndBlock = CGF.createBasicBlock (" typeid.end" );
@@ -2244,7 +2208,8 @@ llvm::Value *CodeGenFunction::EmitCXXTypeidExpr(const CXXTypeidExpr *E) {
2244
2208
// type) to which the glvalue refers.
2245
2209
// If the operand is already most derived object, no need to look up vtable.
2246
2210
if (E->isPotentiallyEvaluated () && !E->isMostDerived (getContext ()))
2247
- return EmitTypeidFromVTable (*this , E->getExprOperand (), PtrTy);
2211
+ return EmitTypeidFromVTable (*this , E->getExprOperand (), PtrTy,
2212
+ E->hasNullCheck ());
2248
2213
2249
2214
QualType OperandTy = E->getExprOperand ()->getType ();
2250
2215
return MaybeASCast (CGM.GetAddrOfRTTIDescriptor (OperandTy));
0 commit comments