diff options
Diffstat (limited to 'lib/AST/ExprConstant.cpp')
-rw-r--r-- | lib/AST/ExprConstant.cpp | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 4fc75a613e..46580697de 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -697,6 +697,7 @@ static bool IsGlobalLValue(APValue::LValueBase B) { case Expr::PredefinedExprClass: case Expr::ObjCStringLiteralClass: case Expr::ObjCEncodeExprClass: + case Expr::CXXTypeidExprClass: return true; case Expr::CallExprClass: return IsStringLiteralCall(cast<CallExpr>(E)); @@ -2329,6 +2330,7 @@ public: // - Literals // * CompoundLiteralExpr in C // * StringLiteral +// * CXXTypeidExpr // * PredefinedExpr // * ObjCStringLiteralExpr // * ObjCEncodeExpr @@ -2356,6 +2358,7 @@ public: bool VisitMemberExpr(const MemberExpr *E); bool VisitStringLiteral(const StringLiteral *E) { return Success(E); } bool VisitObjCEncodeExpr(const ObjCEncodeExpr *E) { return Success(E); } + bool VisitCXXTypeidExpr(const CXXTypeidExpr *E); bool VisitArraySubscriptExpr(const ArraySubscriptExpr *E); bool VisitUnaryDeref(const UnaryOperator *E); @@ -2451,6 +2454,19 @@ LValueExprEvaluator::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) { return Success(E); } +bool LValueExprEvaluator::VisitCXXTypeidExpr(const CXXTypeidExpr *E) { + if (E->isTypeOperand()) + return Success(E); + CXXRecordDecl *RD = E->getExprOperand()->getType()->getAsCXXRecordDecl(); + if (RD && RD->isPolymorphic()) { + Info.Diag(E->getExprLoc(), diag::note_constexpr_typeid_polymorphic) + << E->getExprOperand()->getType() + << E->getExprOperand()->getSourceRange(); + return false; + } + return Success(E); +} + bool LValueExprEvaluator::VisitMemberExpr(const MemberExpr *E) { // Handle static data members. if (const VarDecl *VD = dyn_cast<VarDecl>(E->getMemberDecl())) { |