diff options
Diffstat (limited to 'lib/AST/ExprConstant.cpp')
| -rw-r--r-- | lib/AST/ExprConstant.cpp | 53 | 
1 files changed, 28 insertions, 25 deletions
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index a20e1cc6f56b4..13831dc1f52cd 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -848,16 +848,8 @@ 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)) { -    // FIXME: This is an ugly hack around the fact that enums don't set their -    // signedness consistently; see PR3173. -    APSInt SI = ECD->getInitVal(); -    SI.setIsUnsigned(!E->getType()->isSignedIntegerType()); -    // FIXME: This is an ugly hack around the fact that enums don't -    // set their width (!?!) consistently; see PR3173. -    SI.extOrTrunc(Info.Ctx.getIntWidth(E->getType())); -    return Success(SI, E); -  } +  if (const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D)) +    return Success(ECD->getInitVal(), E);    // In C++, const, non-volatile integers initialized with ICEs are ICEs.    // In C, they can also be folded, although they are not ICEs. @@ -866,15 +858,24 @@ bool IntExprEvaluator::CheckReferencedDecl(const Expr* E, const Decl* D) {      if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {        const VarDecl *Def = 0;        if (const Expr *Init = VD->getDefinition(Def)) { -        if (APValue *V = VD->getEvaluatedValue()) -          return Success(V->getInt(), E); -           +        if (APValue *V = VD->getEvaluatedValue()) { +          if (V->isInt()) +            return Success(V->getInt(), E); +          return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E); +        } + +        if (VD->isEvaluatingValue()) +          return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E); + +        VD->setEvaluatingValue(); +          if (Visit(const_cast<Expr*>(Init))) {            // Cache the evaluated value in the variable declaration. -          VD->setEvaluatedValue(Info.Ctx, Result); +          VD->setEvaluatedValue(Result);            return true;          } +        VD->setEvaluatedValue(APValue());          return false;        }      } @@ -1506,6 +1507,7 @@ public:    bool VisitFloatingLiteral(const FloatingLiteral *E);    bool VisitCastExpr(CastExpr *E);    bool VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E); +  bool VisitConditionalOperator(ConditionalOperator *E);    bool VisitChooseExpr(const ChooseExpr *E)      { return Visit(E->getChosenSubExpr(Info.Ctx)); } @@ -1513,8 +1515,7 @@ public:      { return Visit(E->getSubExpr()); }    // FIXME: Missing: __real__/__imag__, array subscript of vector, -  //                 member of vector, ImplicitValueInitExpr, -  //                 conditional ?: +  //                 member of vector, ImplicitValueInitExpr  };  } // end anonymous namespace @@ -1547,16 +1548,10 @@ bool FloatExprEvaluator::VisitCallExpr(const CallExpr *E) {        if (!S->isWide()) {          const llvm::fltSemantics &Sem =            Info.Ctx.getFloatTypeSemantics(E->getType()); -        llvm::SmallString<16> s; -        s.append(S->getStrData(), S->getStrData() + S->getByteLength()); -        s += '\0'; -        long l; -        char *endp; -        l = strtol(&s[0], &endp, 0); -        if (endp != s.end()-1) +        unsigned Type = 0; +        if (!S->getString().empty() && S->getString().getAsInteger(0, Type))            return false; -        unsigned type = (unsigned int)l;; -        Result = llvm::APFloat::getNaN(Sem, false, type); +        Result = llvm::APFloat::getNaN(Sem, false, Type);          return true;        }      } @@ -1673,6 +1668,14 @@ bool FloatExprEvaluator::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {    return true;  } +bool FloatExprEvaluator::VisitConditionalOperator(ConditionalOperator *E) { +  bool Cond; +  if (!HandleConversionToBool(E->getCond(), Cond, Info)) +    return false; + +  return Visit(Cond ? E->getTrueExpr() : E->getFalseExpr()); +} +  //===----------------------------------------------------------------------===//  // Complex Evaluation (for float and integer)  //===----------------------------------------------------------------------===//  | 
