diff options
Diffstat (limited to 'lib/AST/ExprConstant.cpp')
| -rw-r--r-- | lib/AST/ExprConstant.cpp | 49 | 
1 files changed, 33 insertions, 16 deletions
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 3d7f2dca7a2f..d1ec7aea1d2a 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -1406,7 +1406,7 @@ static bool CheckConstantExpression(EvalInfo &Info, SourceLocation DiagLoc,    return true;  } -const ValueDecl *GetLValueBaseDecl(const LValue &LVal) { +static const ValueDecl *GetLValueBaseDecl(const LValue &LVal) {    return LVal.Base.dyn_cast<const ValueDecl*>();  } @@ -2173,7 +2173,7 @@ struct CompleteObject {      assert(Value && "missing value for complete object");    } -  LLVM_EXPLICIT operator bool() const { return Value; } +  explicit operator bool() const { return Value; }  };  /// Find the designated sub-object of an rvalue. @@ -2502,8 +2502,9 @@ static bool AreElementsOfSameArray(QualType ObjType,  }  /// Find the complete object to which an LValue refers. -CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E, AccessKinds AK, -                                  const LValue &LVal, QualType LValType) { +static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E, +                                         AccessKinds AK, const LValue &LVal, +                                         QualType LValType) {    if (!LVal.Base) {      Info.Diag(E, diag::note_constexpr_access_null) << AK;      return CompleteObject(); @@ -3726,8 +3727,9 @@ static bool HandleFunctionCall(SourceLocation CallLoc,    // Skip this for non-union classes with no fields; in that case, the defaulted    // copy/move does not actually read the object.    const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Callee); -  if (MD && MD->isDefaulted() && MD->isTrivial() && -      (MD->getParent()->isUnion() || hasFields(MD->getParent()))) { +  if (MD && MD->isDefaulted() && +      (MD->getParent()->isUnion() || +       (MD->isTrivial() && hasFields(MD->getParent())))) {      assert(This &&             (MD->isCopyAssignmentOperator() || MD->isMoveAssignmentOperator()));      LValue RHS; @@ -3791,11 +3793,9 @@ static bool HandleConstructorCall(SourceLocation CallLoc, const LValue &This,    // Skip this for empty non-union classes; we should not perform an    // lvalue-to-rvalue conversion on them because their copy constructor does not    // actually read them. -  if (Definition->isDefaulted() && -      ((Definition->isCopyConstructor() && Definition->isTrivial()) || -       (Definition->isMoveConstructor() && Definition->isTrivial())) && +  if (Definition->isDefaulted() && Definition->isCopyOrMoveConstructor() &&        (Definition->getParent()->isUnion() || -       hasFields(Definition->getParent()))) { +       (Definition->isTrivial() && hasFields(Definition->getParent())))) {      LValue RHS;      RHS.setFrom(Info.Ctx, ArgValues[0]);      return handleLValueToRValueConversion(Info, Args[0], Args[0]->getType(), @@ -6834,7 +6834,7 @@ void DataRecursiveIntBinOpEvaluator::process(EvalResult &Result) {  }  bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { -  if (E->isAssignmentOp()) +  if (!Info.keepEvaluatingAfterFailure() && E->isAssignmentOp())      return Error(E);    if (DataRecursiveIntBinOpEvaluator::shouldEnqueue(E)) @@ -6846,7 +6846,11 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {    if (LHSTy->isAnyComplexType() || RHSTy->isAnyComplexType()) {      ComplexValue LHS, RHS;      bool LHSOK; -    if (E->getLHS()->getType()->isRealFloatingType()) { +    if (E->isAssignmentOp()) { +      LValue LV; +      EvaluateLValue(E->getLHS(), LV, Info); +      LHSOK = false; +    } else if (LHSTy->isRealFloatingType()) {        LHSOK = EvaluateFloat(E->getLHS(), LHS.FloatReal, Info);        if (LHSOK) {          LHS.makeComplexFloat(); @@ -7586,10 +7590,23 @@ static bool TryEvaluateBuiltinNaN(const ASTContext &Context,    else if (S->getString().getAsInteger(0, fill))      return false; -  if (SNaN) -    Result = llvm::APFloat::getSNaN(Sem, false, &fill); -  else -    Result = llvm::APFloat::getQNaN(Sem, false, &fill); +  if (Context.getTargetInfo().isNan2008()) { +    if (SNaN) +      Result = llvm::APFloat::getSNaN(Sem, false, &fill); +    else +      Result = llvm::APFloat::getQNaN(Sem, false, &fill); +  } else { +    // Prior to IEEE 754-2008, architectures were allowed to choose whether +    // the first bit of their significand was set for qNaN or sNaN. MIPS chose +    // a different encoding to what became a standard in 2008, and for pre- +    // 2008 revisions, MIPS interpreted sNaN-2008 as qNan and qNaN-2008 as +    // sNaN. This is now known as "legacy NaN" encoding. +    if (SNaN) +      Result = llvm::APFloat::getQNaN(Sem, false, &fill); +    else +      Result = llvm::APFloat::getSNaN(Sem, false, &fill); +  } +    return true;  }  | 
