diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 42 | ||||
-rw-r--r-- | clang/lib/Sema/SemaStmt.cpp | 7 |
2 files changed, 28 insertions, 21 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 35cec0f3442..5c5adb6a45e 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -537,6 +537,7 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { // These need to be handled specially because the operands aren't // necessarily integral bool bres; + bool isEvaluated = true; if (HandleConversionToBool(E->getLHS(), bres, Info)) { // We were able to evaluate the LHS, see if we can get away with not @@ -548,16 +549,18 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { // We can't evaluate. return false; } + + // We did not evaluate the LHS + isEvaluated = false; } - // FIXME: If we evaluate the RHS, we need to check if the LHS has - // any side effects. - if (bres == (E->getOpcode() == BinaryOperator::LOr) || !bres == (E->getOpcode() == BinaryOperator::LAnd)) { Result.zextOrTrunc(getIntTypeSizeInBits(E->getType())); Result.setIsUnsigned(E->getType()->isUnsignedIntegerType()); Result = bres; + Info.isEvaluated = isEvaluated; + return true; } @@ -1153,30 +1156,31 @@ APValue ComplexFloatExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) /// any crazy technique (that has nothing to do with language standards) that /// we want to. If this function returns true, it returns the folded constant /// in Result. -bool Expr::Evaluate(APValue &Result, ASTContext &Ctx) const { +bool Expr::Evaluate(APValue &Result, ASTContext &Ctx, bool *isEvaluated) const { EvalInfo Info(Ctx); if (getType()->isIntegerType()) { llvm::APSInt sInt(32); - if (EvaluateInteger(this, sInt, Info)) { - Result = APValue(sInt); - return true; - } + if (!EvaluateInteger(this, sInt, Info)) + return false; + + Result = APValue(sInt); } else if (getType()->isPointerType()) { - if (EvaluatePointer(this, Result, Info)) { - return true; - } + if (!EvaluatePointer(this, Result, Info)) + return false; } else if (getType()->isRealFloatingType()) { llvm::APFloat f(0.0); - if (EvaluateFloat(this, f, Info)) { - Result = APValue(f); - return true; - } + if (!EvaluateFloat(this, f, Info)) + return false; + + Result = APValue(f); } else if (getType()->isComplexType()) { - if (EvaluateComplexFloat(this, Result, Info)) - return true; + if (!EvaluateComplexFloat(this, Result, Info)) + return false; } - - return false; + + if (isEvaluated) + *isEvaluated = Info.isEvaluated; + return true; } /// isEvaluatable - Call Evaluate to see if this expression can be constant diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 6839310e0ec..15d955cb7b4 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -131,8 +131,10 @@ Sema::ActOnCaseStmt(SourceLocation CaseLoc, ExprTy *lhsval, // However, GCC allows any evaluatable integer expression. // FIXME: Should we warn if this is evaluatable but not an I-C-E? APValue Result; + bool isEvaluated; - if (!LHSVal->Evaluate(Result, Context) || !Result.isInt()) { + if (!LHSVal->Evaluate(Result, Context, &isEvaluated) || !Result.isInt() || + !isEvaluated) { // FIXME: Evaluate doesn't return the SourceLocation that it failed to // evaluate. ExpLoc = LHSVal->getExprLoc(); @@ -142,7 +144,8 @@ Sema::ActOnCaseStmt(SourceLocation CaseLoc, ExprTy *lhsval, } // GCC extension: The expression shall be an integer constant. - if (RHSVal && !RHSVal->Evaluate(Result, Context) || !Result.isInt()) { + if (RHSVal && !RHSVal->Evaluate(Result, Context, &isEvaluated) || + !Result.isInt() || !isEvaluated) { ExpLoc = RHSVal->getExprLoc(); Diag(ExpLoc, diag::err_case_label_not_integer_constant_expr) << RHSVal->getSourceRange(); |