diff options
Diffstat (limited to 'lib/Sema/SemaExprCXX.cpp')
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 67ad45d74b..e3ca4355e6 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -287,7 +287,7 @@ Sema::OwningExprResult Sema::BuildCXXTypeId(QualType TypeInfoType, if (T->getAs<RecordType>() && RequireCompleteType(TypeidLoc, T, diag::err_incomplete_typeid)) return ExprError(); - + return Owned(new (Context) CXXTypeidExpr(TypeInfoType.withConst(), Operand, SourceRange(TypeidLoc, RParenLoc))); @@ -314,8 +314,10 @@ Sema::OwningExprResult Sema::BuildCXXTypeId(QualType TypeInfoType, // When typeid is applied to an expression other than an lvalue of a // polymorphic class type [...] [the] expression is an unevaluated // operand. [...] - if (RecordD->isPolymorphic() && E->isLvalue(Context) == Expr::LV_Valid) + if (RecordD->isPolymorphic() && E->isLvalue(Context) == Expr::LV_Valid) { isUnevaluatedOperand = false; + MaybeMarkVirtualMembersReferenced(TypeidLoc, RecordD); + } } // C++ [expr.typeid]p4: @@ -445,6 +447,14 @@ bool Sema::CheckCXXThrowOperand(SourceLocation ThrowLoc, Expr *&E) { if (Res.isInvalid()) return true; E = Res.takeAs<Expr>(); + + if (const RecordType *RecordTy = Ty->getAs<RecordType>()) { + // If we're throwing a polymorphic class, we need to make sure + // there is a vtable. + MaybeMarkVirtualMembersReferenced(ThrowLoc, + cast<CXXRecordDecl>(RecordTy->getDecl())); + } + return false; } |