[cfe-commits] r115355 - in /cfe/trunk: lib/Sema/SemaStmt.cpp test/SemaCXX/gnu-case-ranges.cpp
Gabor Greif
ggreif at gmail.com
Fri Oct 1 15:05:14 PDT 2010
Author: ggreif
Date: Fri Oct 1 17:05:14 2010
New Revision: 115355
URL: http://llvm.org/viewvc/llvm-project?rev=115355&view=rev
Log:
Factor out enumerator APSInt adjustment into
a helper function (AdjustAPSInt) and use that
for adjusting the high bounds of case ranges
before APSInt comparisons. Fixes
http://llvm.org/bugs/show_bug.cgi?id=8135
Some minor refacorings while I am here.
Added:
cfe/trunk/test/SemaCXX/gnu-case-ranges.cpp
Modified:
cfe/trunk/lib/Sema/SemaStmt.cpp
Modified: cfe/trunk/lib/Sema/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=115355&r1=115354&r2=115355&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaStmt.cpp (original)
+++ cfe/trunk/lib/Sema/SemaStmt.cpp Fri Oct 1 17:05:14 2010
@@ -459,6 +459,14 @@
return Owned(SS);
}
+static void AdjustAPSInt(llvm::APSInt &Val, unsigned BitWidth, bool IsSigned) {
+ if (Val.getBitWidth() < BitWidth)
+ Val.extend(BitWidth);
+ else if (Val.getBitWidth() > BitWidth)
+ Val.trunc(BitWidth);
+ Val.setIsSigned(IsSigned);
+}
+
StmtResult
Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,
Stmt *BodyStmt) {
@@ -560,7 +568,7 @@
// Convert the value to the same width/sign as the condition.
ConvertIntegerToTypeWarnOnOverflow(LoVal, CondWidth, CondIsSigned,
- CS->getLHS()->getLocStart(),
+ Lo->getLocStart(),
diag::warn_case_value_overflow);
// If the LHS is not the same type as the condition, insert an implicit
@@ -639,7 +647,7 @@
// Convert the value to the same width/sign as the condition.
ConvertIntegerToTypeWarnOnOverflow(HiVal, CondWidth, CondIsSigned,
- CR->getRHS()->getLocStart(),
+ Hi->getLocStart(),
diag::warn_case_value_overflow);
// If the LHS is not the same type as the condition, insert an implicit
@@ -651,7 +659,7 @@
if (LoVal > HiVal) {
Diag(CR->getLHS()->getLocStart(), diag::warn_case_empty_range)
<< SourceRange(CR->getLHS()->getLocStart(),
- CR->getRHS()->getLocEnd());
+ Hi->getLocEnd());
CaseRanges.erase(CaseRanges.begin()+i);
--i, --e;
continue;
@@ -740,14 +748,10 @@
// Gather all enum values, set their type and sort them,
// allowing easier comparison with CaseVals.
for (EnumDecl::enumerator_iterator EDI = ED->enumerator_begin();
- EDI != ED->enumerator_end(); EDI++) {
- llvm::APSInt Val = (*EDI)->getInitVal();
- if(Val.getBitWidth() < CondWidth)
- Val.extend(CondWidth);
- else if (Val.getBitWidth() > CondWidth)
- Val.trunc(CondWidth);
- Val.setIsSigned(CondIsSigned);
- EnumVals.push_back(std::make_pair(Val, (*EDI)));
+ EDI != ED->enumerator_end(); ++EDI) {
+ llvm::APSInt Val = EDI->getInitVal();
+ AdjustAPSInt(Val, CondWidth, CondIsSigned);
+ EnumVals.push_back(std::make_pair(Val, *EDI));
}
std::stable_sort(EnumVals.begin(), EnumVals.end(), CmpEnumVals);
EnumValsTy::iterator EIend =
@@ -779,6 +783,7 @@
}
llvm::APSInt Hi = RI->second->getRHS()->EvaluateAsInt(Context);
+ AdjustAPSInt(Hi, CondWidth, CondIsSigned);
while (EI != EIend && EI->first < Hi)
EI++;
if (EI == EIend || EI->first != Hi)
@@ -806,6 +811,7 @@
// Drop unneeded case ranges
for (; RI != CaseRanges.end(); RI++) {
llvm::APSInt Hi = RI->second->getRHS()->EvaluateAsInt(Context);
+ AdjustAPSInt(Hi, CondWidth, CondIsSigned);
if (EI->first <= Hi)
break;
}
Added: cfe/trunk/test/SemaCXX/gnu-case-ranges.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/gnu-case-ranges.cpp?rev=115355&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/gnu-case-ranges.cpp (added)
+++ cfe/trunk/test/SemaCXX/gnu-case-ranges.cpp Fri Oct 1 17:05:14 2010
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -o /dev/null -verify %s
+
+enum E {
+ one,
+ two,
+ three,
+ four
+};
+
+
+int test(enum E e)
+{
+ switch (e)
+ {
+ case one:
+ return 7;
+ case two ... two + 1:
+ return 42;
+ case four:
+ return 25;
+ default:
+ return 0;
+ }
+}
More information about the cfe-commits
mailing list