summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST
diff options
context:
space:
mode:
authorAbramo Bagnara <abramo.bagnara@gmail.com>2011-07-02 13:13:53 +0000
committerAbramo Bagnara <abramo.bagnara@gmail.com>2011-07-02 13:13:53 +0000
commit9ae292d8106c2eb45b60e52f5aa056691cda3b11 (patch)
tree261453529aa207a667b0e92bce66493aadfbeb8d /clang/lib/AST
parentdda99eef54ed52c4f5faa5b3a058b111e02b34f8 (diff)
downloadbcm5719-llvm-9ae292d8106c2eb45b60e52f5aa056691cda3b11.tar.gz
bcm5719-llvm-9ae292d8106c2eb45b60e52f5aa056691cda3b11.zip
Rewritten fix in r134139 to conform evaluation result to original evaluation context.
llvm-svn: 134320
Diffstat (limited to 'clang/lib/AST')
-rw-r--r--clang/lib/AST/ExprConstant.cpp32
1 files changed, 21 insertions, 11 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 1be23fc9903..df33f7afc3f 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -955,21 +955,17 @@ public:
IntExprEvaluator(EvalInfo &info, APValue &result)
: ExprEvaluatorBaseTy(info), Result(result) {}
- bool Success(const llvm::APSInt &SI, QualType Ty) {
- assert(Ty->isIntegralOrEnumerationType() &&
+ bool Success(const llvm::APSInt &SI, const Expr *E) {
+ assert(E->getType()->isIntegralOrEnumerationType() &&
"Invalid evaluation result.");
- assert(SI.isSigned() == Ty->isSignedIntegerOrEnumerationType() &&
+ assert(SI.isSigned() == E->getType()->isSignedIntegerOrEnumerationType() &&
"Invalid evaluation result.");
- assert(SI.getBitWidth() == Info.Ctx.getIntWidth(Ty) &&
+ assert(SI.getBitWidth() == Info.Ctx.getIntWidth(E->getType()) &&
"Invalid evaluation result.");
Result = APValue(SI);
return true;
}
- bool Success(const llvm::APSInt &SI, const Expr *E) {
- return Success(SI, E->getType());
- }
-
bool Success(const llvm::APInt &I, const Expr *E) {
assert(E->getType()->isIntegralOrEnumerationType() &&
"Invalid evaluation result.");
@@ -1111,9 +1107,23 @@ 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)) {
- // Note: provide the type of ECD (rather than that of E),
- // so that signedness/width will match the ECD init value.
- return Success(ECD->getInitVal(), ECD->getType());
+ // 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.
OpenPOWER on IntegriCloud