diff options
author | Daniel Dunbar <daniel@zuster.org> | 2008-09-22 23:53:24 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2008-09-22 23:53:24 +0000 |
commit | c6fdac260bc5890d78647615082e97263fd8a677 (patch) | |
tree | 1de20bcbc2a8fc058d8ff10ef4df8cad8267d1c0 | |
parent | a0e18765845f98455b4e73d318ff837bc00b781d (diff) | |
download | bcm5719-llvm-c6fdac260bc5890d78647615082e97263fd8a677.tar.gz bcm5719-llvm-c6fdac260bc5890d78647615082e97263fd8a677.zip |
Bug fix, result of isIntegerConstantExpr could be of incorrect width
for type.
- PR2817
llvm-svn: 56482
-rw-r--r-- | clang/lib/AST/Expr.cpp | 55 | ||||
-rw-r--r-- | clang/test/CodeGen/2008-09-22-bad-switch-type.c | 34 |
2 files changed, 63 insertions, 26 deletions
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 8d49c8ef0ed..9c3d623c163 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -867,22 +867,25 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx, } case BinaryOperatorClass: { const BinaryOperator *Exp = cast<BinaryOperator>(this); + llvm::APSInt LHS, RHS; + + // Initialize result to have correct signedness and width. + Result = llvm::APSInt(static_cast<uint32_t>(Ctx.getTypeSize(getType())), + !getType()->isSignedIntegerType()); // The LHS of a constant expr is always evaluated and needed. - if (!Exp->getLHS()->isIntegerConstantExpr(Result, Ctx, Loc, isEvaluated)) + if (!Exp->getLHS()->isIntegerConstantExpr(LHS, Ctx, Loc, isEvaluated)) return false; - llvm::APSInt RHS(Result); - // The short-circuiting &&/|| operators don't necessarily evaluate their // RHS. Make sure to pass isEvaluated down correctly. if (Exp->isLogicalOp()) { bool RHSEval; if (Exp->getOpcode() == BinaryOperator::LAnd) - RHSEval = Result != 0; + RHSEval = LHS != 0; else { assert(Exp->getOpcode() == BinaryOperator::LOr &&"Unexpected logical"); - RHSEval = Result == 0; + RHSEval = LHS == 0; } if (!Exp->getRHS()->isIntegerConstantExpr(RHS, Ctx, Loc, @@ -898,7 +901,7 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx, if (Loc) *Loc = getLocStart(); return false; case BinaryOperator::Mul: - Result *= RHS; + Result = LHS * RHS; break; case BinaryOperator::Div: if (RHS == 0) { @@ -906,7 +909,7 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx, if (Loc) *Loc = getLocStart(); return false; } - Result /= RHS; + Result = LHS / RHS; break; case BinaryOperator::Rem: if (RHS == 0) { @@ -914,32 +917,32 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx, if (Loc) *Loc = getLocStart(); return false; } - Result %= RHS; + Result = LHS % RHS; break; - case BinaryOperator::Add: Result += RHS; break; - case BinaryOperator::Sub: Result -= RHS; break; + case BinaryOperator::Add: Result = LHS + RHS; break; + case BinaryOperator::Sub: Result = LHS - RHS; break; case BinaryOperator::Shl: - Result <<= - static_cast<uint32_t>(RHS.getLimitedValue(Result.getBitWidth()-1)); - break; + Result = LHS << + static_cast<uint32_t>(RHS.getLimitedValue(LHS.getBitWidth()-1)); + break; case BinaryOperator::Shr: - Result >>= - static_cast<uint32_t>(RHS.getLimitedValue(Result.getBitWidth()-1)); + Result = LHS >> + static_cast<uint32_t>(RHS.getLimitedValue(LHS.getBitWidth()-1)); break; - case BinaryOperator::LT: Result = Result < RHS; break; - case BinaryOperator::GT: Result = Result > RHS; break; - case BinaryOperator::LE: Result = Result <= RHS; break; - case BinaryOperator::GE: Result = Result >= RHS; break; - case BinaryOperator::EQ: Result = Result == RHS; break; - case BinaryOperator::NE: Result = Result != RHS; break; - case BinaryOperator::And: Result &= RHS; break; - case BinaryOperator::Xor: Result ^= RHS; break; - case BinaryOperator::Or: Result |= RHS; break; + case BinaryOperator::LT: Result = LHS < RHS; break; + case BinaryOperator::GT: Result = LHS > RHS; break; + case BinaryOperator::LE: Result = LHS <= RHS; break; + case BinaryOperator::GE: Result = LHS >= RHS; break; + case BinaryOperator::EQ: Result = LHS == RHS; break; + case BinaryOperator::NE: Result = LHS != RHS; break; + case BinaryOperator::And: Result = LHS & RHS; break; + case BinaryOperator::Xor: Result = LHS ^ RHS; break; + case BinaryOperator::Or: Result = LHS | RHS; break; case BinaryOperator::LAnd: - Result = Result != 0 && RHS != 0; + Result = LHS != 0 && RHS != 0; break; case BinaryOperator::LOr: - Result = Result != 0 || RHS != 0; + Result = LHS != 0 || RHS != 0; break; case BinaryOperator::Comma: diff --git a/clang/test/CodeGen/2008-09-22-bad-switch-type.c b/clang/test/CodeGen/2008-09-22-bad-switch-type.c new file mode 100644 index 00000000000..62a420eed3d --- /dev/null +++ b/clang/test/CodeGen/2008-09-22-bad-switch-type.c @@ -0,0 +1,34 @@ +// RUN: clang -emit-llvm -o %t %s +// PR2817 + +void f0(void) { + switch (0) { + case (unsigned long long) 0 < 0: + break; + } + + switch (0) { + case (unsigned long long) 0 > 0: + break; + } + + switch (0) { + case (unsigned long long) 0 <= 0: + break; + } + + switch (0) { + case (unsigned long long) 0 >= 0: + break; + } + + switch (0) { + case (unsigned long long) 0 == 0: + break; + } + + switch (0) { + case (unsigned long long) 0 != 0: + break; + } +} |