diff options
Diffstat (limited to 'lib/AST/ExprConstant.cpp')
| -rw-r--r-- | lib/AST/ExprConstant.cpp | 68 | 
1 files changed, 51 insertions, 17 deletions
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 06c5645afb3f..786155af281d 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -224,11 +224,10 @@ static APSInt HandleFloatToIntCast(QualType DestType, QualType SrcType,    bool DestSigned = DestType->isSignedIntegerOrEnumerationType();    // FIXME: Warning for overflow. -  uint64_t Space[4]; +  APSInt Result(DestWidth, !DestSigned);    bool ignored; -  (void)Value.convertToInteger(Space, DestWidth, DestSigned, -                               llvm::APFloat::rmTowardZero, &ignored); -  return APSInt(llvm::APInt(DestWidth, 4, Space), !DestSigned); +  (void)Value.convertToInteger(Result, llvm::APFloat::rmTowardZero, &ignored); +  return Result;  }  static APFloat HandleFloatToFloatCast(QualType DestType, QualType SrcType, @@ -282,6 +281,17 @@ public:        return true;      return false;    } +  bool VisitObjCIvarRefExpr(const ObjCIvarRefExpr *E) { +    if (Info.Ctx.getCanonicalType(E->getType()).isVolatileQualified()) +      return true; +    return false; +  } +  bool VisitBlockDeclRefExpr (const BlockDeclRefExpr *E) { +    if (Info.Ctx.getCanonicalType(E->getType()).isVolatileQualified()) +      return true; +    return false; +  } +    // We don't want to evaluate BlockExprs multiple times, as they generate    // a ton of code.    bool VisitBlockExpr(const BlockExpr *E) { return true; } @@ -395,6 +405,8 @@ public:      { return StmtVisitorTy::Visit(E->getChosenSubExpr(Info.Ctx)); }    RetTy VisitGenericSelectionExpr(const GenericSelectionExpr *E)      { return StmtVisitorTy::Visit(E->getResultExpr()); } +  RetTy VisitSubstNonTypeTemplateParmExpr(const SubstNonTypeTemplateParmExpr *E) +    { return StmtVisitorTy::Visit(E->getReplacement()); }    RetTy VisitBinaryConditionalOperator(const BinaryConditionalOperator *E) {      OpaqueValueEvaluation opaque(Info, E->getOpaqueValue(), E->getCommon()); @@ -525,15 +537,7 @@ bool LValueExprEvaluator::VisitMemberExpr(const MemberExpr *E) {    if (FD->getType()->isReferenceType())      return false; -  // FIXME: This is linear time. -  unsigned i = 0; -  for (RecordDecl::field_iterator Field = RD->field_begin(), -                               FieldEnd = RD->field_end(); -       Field != FieldEnd; (void)++Field, ++i) { -    if (*Field == FD) -      break; -  } - +  unsigned i = FD->getFieldIndex();    Result.Offset += Info.Ctx.toCharUnitsFromBits(RL.getFieldOffset(i));    return true;  } @@ -945,7 +949,7 @@ public:      : ExprEvaluatorBaseTy(info), Result(result) {}    bool Success(const llvm::APSInt &SI, const Expr *E) { -    assert(E->getType()->isIntegralOrEnumerationType() &&  +    assert(E->getType()->isIntegralOrEnumerationType() &&             "Invalid evaluation result.");      assert(SI.isSigned() == E->getType()->isSignedIntegerOrEnumerationType() &&             "Invalid evaluation result."); @@ -1095,8 +1099,25 @@ static bool EvaluateInteger(const Expr* E, APSInt &Result, EvalInfo &Info) {  bool IntExprEvaluator::CheckReferencedDecl(const Expr* E, const Decl* D) {    // Enums are integer constant exprs. -  if (const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D)) -    return Success(ECD->getInitVal(), E); +  if (const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D)) { +    // Check for signedness/width mismatches between E type and ECD value. +    bool SameSign = (ECD->getInitVal().isSigned() +                     == E->getType()->isSignedIntegerOrEnumerationType()); +    bool SameWidth = (ECD->getInitVal().getBitWidth() +                      == Info.Ctx.getIntWidth(E->getType())); +    if (SameSign && SameWidth) +      return Success(ECD->getInitVal(), E); +    else { +      // Get rid of mismatch (otherwise Success assertions will fail) +      // by computing a new value matching the type of E. +      llvm::APSInt Val = ECD->getInitVal(); +      if (!SameSign) +        Val.setIsSigned(!ECD->getInitVal().isSigned()); +      if (!SameWidth) +        Val = Val.extOrTrunc(Info.Ctx.getIntWidth(E->getType())); +      return Success(Val, E); +    } +  }    // In C++, const, non-volatile integers initialized with ICEs are ICEs.    // In C, they can also be folded, although they are not ICEs. @@ -1797,6 +1818,9 @@ bool IntExprEvaluator::VisitCastExpr(const CastExpr *E) {    case CK_GetObjCProperty:    case CK_LValueBitCast:    case CK_UserDefinedConversion: +  case CK_ObjCProduceObject: +  case CK_ObjCConsumeObject: +  case CK_ObjCReclaimReturnedObject:      return false;    case CK_LValueToRValue: @@ -2301,6 +2325,9 @@ bool ComplexExprEvaluator::VisitCastExpr(const CastExpr *E) {    case CK_FloatingComplexToBoolean:    case CK_IntegralComplexToReal:    case CK_IntegralComplexToBoolean: +  case CK_ObjCProduceObject: +  case CK_ObjCConsumeObject: +  case CK_ObjCReclaimReturnedObject:      llvm_unreachable("invalid cast kind for complex value");    case CK_LValueToRValue: @@ -2771,6 +2798,8 @@ static ICEDiag CheckICE(const Expr* E, ASTContext &Ctx) {    case Expr::PackExpansionExprClass:    case Expr::SubstNonTypeTemplateParmPackExprClass:    case Expr::AsTypeExprClass: +  case Expr::ObjCIndirectCopyRestoreExprClass: +  case Expr::MaterializeTemporaryExprClass:      return ICEDiag(2, E->getLocStart());    case Expr::SizeOfPackExprClass: @@ -2778,6 +2807,10 @@ static ICEDiag CheckICE(const Expr* E, ASTContext &Ctx) {      // GCC considers the GNU __null value to be an integral constant expression.      return NoDiag(); +  case Expr::SubstNonTypeTemplateParmExprClass: +    return +      CheckICE(cast<SubstNonTypeTemplateParmExpr>(E)->getReplacement(), Ctx); +    case Expr::ParenExprClass:      return CheckICE(cast<ParenExpr>(E)->getSubExpr(), Ctx);    case Expr::GenericSelectionExprClass: @@ -2995,7 +3028,8 @@ static ICEDiag CheckICE(const Expr* E, ASTContext &Ctx) {    case Expr::CXXFunctionalCastExprClass:    case Expr::CXXStaticCastExprClass:    case Expr::CXXReinterpretCastExprClass: -  case Expr::CXXConstCastExprClass: { +  case Expr::CXXConstCastExprClass:  +  case Expr::ObjCBridgedCastExprClass: {      const Expr *SubExpr = cast<CastExpr>(E)->getSubExpr();      if (SubExpr->getType()->isIntegralOrEnumerationType())        return CheckICE(SubExpr, Ctx);  | 
