diff options
Diffstat (limited to 'lib/AST/ExprConstant.cpp')
-rw-r--r-- | lib/AST/ExprConstant.cpp | 61 |
1 files changed, 37 insertions, 24 deletions
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 06c41a2..6e0b5fc 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -953,7 +953,7 @@ static void NoteLValueLocation(EvalInfo &Info, APValue::LValueBase Base) { if (VD) Info.Note(VD->getLocation(), diag::note_declared_at); else - Info.Note(Base.dyn_cast<const Expr*>()->getExprLoc(), + Info.Note(Base.get<const Expr*>()->getExprLoc(), diag::note_constexpr_temporary_here); } @@ -987,6 +987,14 @@ static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc, LVal.getLValueCallIndex() == 0) && "have call index for global lvalue"); + // Check if this is a thread-local variable. + if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>()) { + if (const VarDecl *Var = dyn_cast<const VarDecl>(VD)) { + if (Var->isThreadSpecified()) + return false; + } + } + // Allow address constant expressions to be past-the-end pointers. This is // an extension: the standard requires them to point to an object. if (!IsReferenceType) @@ -2586,7 +2594,7 @@ public: const FieldDecl *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); if (!FD) return Error(E); assert(!FD->getType()->isReferenceType() && "prvalue reference?"); - assert(BaseTy->getAs<RecordType>()->getDecl()->getCanonicalDecl() == + assert(BaseTy->castAs<RecordType>()->getDecl()->getCanonicalDecl() == FD->getParent()->getCanonicalDecl() && "record / field mismatch"); SubobjectDesignator Designator(BaseTy); @@ -2665,7 +2673,7 @@ public: if (E->isArrow()) { if (!EvaluatePointer(E->getBase(), Result, this->Info)) return false; - BaseTy = E->getBase()->getType()->getAs<PointerType>()->getPointeeType(); + BaseTy = E->getBase()->getType()->castAs<PointerType>()->getPointeeType(); } else if (E->getBase()->isRValue()) { assert(E->getBase()->getType()->isRecordType()); if (!EvaluateTemporary(E->getBase(), Result, this->Info)) @@ -2878,19 +2886,13 @@ LValueExprEvaluator::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) { } bool LValueExprEvaluator::VisitCXXTypeidExpr(const CXXTypeidExpr *E) { - if (E->isTypeOperand()) + if (!E->isPotentiallyEvaluated()) return Success(E); - CXXRecordDecl *RD = E->getExprOperand()->getType()->getAsCXXRecordDecl(); - // FIXME: The standard says "a typeid expression whose operand is of a - // polymorphic class type" is not a constant expression, but it probably - // means "a typeid expression whose operand is potentially evaluated". - if (RD && RD->isPolymorphic()) { - Info.Diag(E, diag::note_constexpr_typeid_polymorphic) - << E->getExprOperand()->getType() - << E->getExprOperand()->getSourceRange(); - return false; - } - return Success(E); + + Info.Diag(E, diag::note_constexpr_typeid_polymorphic) + << E->getExprOperand()->getType() + << E->getExprOperand()->getSourceRange(); + return false; } bool LValueExprEvaluator::VisitCXXUuidofExpr(const CXXUuidofExpr *E) { @@ -3036,7 +3038,7 @@ bool PointerExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { if (E->getOpcode() == BO_Sub) AdditionalOffset = -AdditionalOffset; - QualType Pointee = PExp->getType()->getAs<PointerType>()->getPointeeType(); + QualType Pointee = PExp->getType()->castAs<PointerType>()->getPointeeType(); return HandleLValueArrayAdjustment(Info, E, Result, Pointee, AdditionalOffset); } @@ -4288,6 +4290,16 @@ bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) { return Error(E); } + case Builtin::BI__builtin_bswap16: + case Builtin::BI__builtin_bswap32: + case Builtin::BI__builtin_bswap64: { + APSInt Val; + if (!EvaluateInteger(E->getArg(0), Val, Info)) + return false; + + return Success(Val.byteSwap(), E); + } + case Builtin::BI__builtin_classify_type: return Success(EvaluateBuiltinClassifyType(E), E); @@ -4902,7 +4914,7 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { if (!LHSValue.Offset.isZero() || !RHSValue.Offset.isZero()) return false; const Expr *LHSExpr = LHSValue.Base.dyn_cast<const Expr*>(); - const Expr *RHSExpr = LHSValue.Base.dyn_cast<const Expr*>(); + const Expr *RHSExpr = RHSValue.Base.dyn_cast<const Expr*>(); if (!LHSExpr || !RHSExpr) return false; const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr); @@ -5176,7 +5188,7 @@ bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr( QualType Ty = E->getTypeOfArgument(); if (Ty->isVectorType()) { - unsigned n = Ty->getAs<VectorType>()->getNumElements(); + unsigned n = Ty->castAs<VectorType>()->getNumElements(); // The vec_step built-in functions that take a 3-component // vector return 4. (OpenCL 1.1 spec 6.11.12) @@ -5349,6 +5361,7 @@ bool IntExprEvaluator::VisitCastExpr(const CastExpr *E) { case CK_IntegralRealToComplex: case CK_IntegralComplexCast: case CK_IntegralComplexToFloatingComplex: + case CK_BuiltinFnToFnPtr: llvm_unreachable("invalid cast kind for integral value"); case CK_BitCast: @@ -5753,7 +5766,7 @@ static bool EvaluateComplex(const Expr *E, ComplexValue &Result, } bool ComplexExprEvaluator::ZeroInitialization(const Expr *E) { - QualType ElemTy = E->getType()->getAs<ComplexType>()->getElementType(); + QualType ElemTy = E->getType()->castAs<ComplexType>()->getElementType(); if (ElemTy->isRealFloatingType()) { Result.makeComplexFloat(); APFloat Zero = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(ElemTy)); @@ -5835,6 +5848,7 @@ bool ComplexExprEvaluator::VisitCastExpr(const CastExpr *E) { case CK_ARCReclaimReturnedObject: case CK_ARCExtendBlockObject: case CK_CopyAndAutoreleaseBlockObject: + case CK_BuiltinFnToFnPtr: llvm_unreachable("invalid cast kind for complex value"); case CK_LValueToRValue: @@ -5911,9 +5925,9 @@ bool ComplexExprEvaluator::VisitCastExpr(const CastExpr *E) { if (!Visit(E->getSubExpr())) return false; - QualType To = E->getType()->getAs<ComplexType>()->getElementType(); + QualType To = E->getType()->castAs<ComplexType>()->getElementType(); QualType From - = E->getSubExpr()->getType()->getAs<ComplexType>()->getElementType(); + = E->getSubExpr()->getType()->castAs<ComplexType>()->getElementType(); Result.makeComplexFloat(); return HandleIntToFloatCast(Info, E, From, Result.IntReal, To, Result.FloatReal) && @@ -6177,11 +6191,9 @@ static bool Evaluate(APValue &Result, EvalInfo &Info, const Expr *E) { return false; Result = Info.CurrentCall->Temporaries[E]; } else if (E->getType()->isVoidType()) { - if (Info.getLangOpts().CPlusPlus0x) + if (!Info.getLangOpts().CPlusPlus0x) Info.CCEDiag(E, diag::note_constexpr_nonliteral) << E->getType(); - else - Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr); if (!EvaluateVoid(E, Info)) return false; } else if (Info.getLangOpts().CPlusPlus0x) { @@ -6470,6 +6482,7 @@ static ICEDiag CheckICE(const Expr* E, ASTContext &Ctx) { case Expr::OpaqueValueExprClass: case Expr::PackExpansionExprClass: case Expr::SubstNonTypeTemplateParmPackExprClass: + case Expr::FunctionParmPackExprClass: case Expr::AsTypeExprClass: case Expr::ObjCIndirectCopyRestoreExprClass: case Expr::MaterializeTemporaryExprClass: |