diff --git a/include/swift/AST/Expr.h b/include/swift/AST/Expr.h index b6cce94d322ac..46607d1243208 100644 --- a/include/swift/AST/Expr.h +++ b/include/swift/AST/Expr.h @@ -893,7 +893,7 @@ class IntegerLiteralExpr : public NumberLiteralExpr { {} APInt getValue() const; - static APInt getValue(StringRef Text, unsigned BitWidth); + static APInt getValue(StringRef Text, unsigned BitWidth, bool Negative); static bool classof(const Expr *E) { return E->getKind() == ExprKind::IntegerLiteral; @@ -910,7 +910,8 @@ class FloatLiteralExpr : public NumberLiteralExpr { {} APFloat getValue() const; - static APFloat getValue(StringRef Text, const llvm::fltSemantics &Semantics); + static APFloat getValue(StringRef Text, const llvm::fltSemantics &Semantics, + bool Negative); static bool classof(const Expr *E) { return E->getKind() == ExprKind::FloatLiteral; diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index d7797f17e5752..8567dc4f6f17d 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -1005,8 +1005,8 @@ static APInt getIntegerLiteralValue(bool IsNegative, StringRef Text, return Value; } -APInt IntegerLiteralExpr::getValue(StringRef Text, unsigned BitWidth) { - return getIntegerLiteralValue(/*IsNegative=*/false, Text, BitWidth); +APInt IntegerLiteralExpr::getValue(StringRef Text, unsigned BitWidth, bool Negative) { + return getIntegerLiteralValue(Negative, Text, BitWidth); } APInt IntegerLiteralExpr::getValue() const { @@ -1035,8 +1035,9 @@ static APFloat getFloatLiteralValue(bool IsNegative, StringRef Text, } APFloat FloatLiteralExpr::getValue(StringRef Text, - const llvm::fltSemantics &Semantics) { - return getFloatLiteralValue(/*IsNegative*/false, Text, Semantics); + const llvm::fltSemantics &Semantics, + bool Negative) { + return getFloatLiteralValue(Negative, Text, Semantics); } llvm::APFloat FloatLiteralExpr::getValue() const { diff --git a/lib/IRGen/GenEnum.cpp b/lib/IRGen/GenEnum.cpp index df9902a39ad87..8ec8d27ec388b 100644 --- a/lib/IRGen/GenEnum.cpp +++ b/lib/IRGen/GenEnum.cpp @@ -1027,10 +1027,8 @@ namespace { auto intType = getDiscriminatorType(); APInt intValue = IntegerLiteralExpr::getValue(intExpr->getDigitsText(), - intType->getBitWidth()); - - if (intExpr->isNegative()) - intValue = -intValue; + intType->getBitWidth(), + intExpr->isNegative()); return intValue.getZExtValue(); } diff --git a/lib/Sema/TypeCheckSwitchStmt.cpp b/lib/Sema/TypeCheckSwitchStmt.cpp index 1a7dff5de24a2..a95a942b40429 100644 --- a/lib/Sema/TypeCheckSwitchStmt.cpp +++ b/lib/Sema/TypeCheckSwitchStmt.cpp @@ -980,7 +980,7 @@ namespace { auto *ILE = cast(EL); auto cacheVal = IntLiteralCache.insert( - {ILE->getValue(ILE->getDigitsText(), 128), ILE}); + {ILE->getValue(ILE->getDigitsText(), 128, ILE->isNegative()), ILE}); PrevPattern = (cacheVal.first != IntLiteralCache.end()) ? cacheVal.first->getSecond() : nullptr; @@ -993,7 +993,7 @@ namespace { auto cacheVal = FloatLiteralCache.insert( {FLE->getValue(FLE->getDigitsText(), - APFloat::IEEEquad()), FLE}); + APFloat::IEEEquad(), FLE->isNegative()), FLE}); PrevPattern = (cacheVal.first != FloatLiteralCache.end()) ? cacheVal.first->getSecond() : nullptr; diff --git a/test/Sema/exhaustive_switch.swift b/test/Sema/exhaustive_switch.swift index 74eed8b77ee69..83bc8c8d90fff 100644 --- a/test/Sema/exhaustive_switch.swift +++ b/test/Sema/exhaustive_switch.swift @@ -559,8 +559,7 @@ func infinitelySized() -> Bool { } } -// Literal Duplicate checks -func checkLiterals() { +func diagnoseDuplicateLiterals() { let str = "def" let int = 2 let dbl = 2.5 @@ -614,6 +613,9 @@ func checkLiterals() { // No Diagnostics switch int { + case -2: break + case -1: break + case 0: break case 1: break case 2: break case 3: break @@ -621,6 +623,8 @@ func checkLiterals() { } switch int { + case -2: break // expected-note {{first occurrence of identical literal pattern is here}} + case -2: break // expected-warning {{literal value is already handled by previous pattern; consider removing it}} case 1: break case 2: break // expected-note {{first occurrence of identical literal pattern is here}} case 2: break // expected-warning {{literal value is already handled by previous pattern; consider removing it}} @@ -629,6 +633,7 @@ func checkLiterals() { } switch int { + case -2, -2: break // expected-note {{first occurrence of identical literal pattern is here}} expected-warning {{literal value is already handled by previous pattern; consider removing it}} case 1, 2: break // expected-note 3 {{first occurrence of identical literal pattern is here}} case 2, 3: break // expected-warning {{literal value is already handled by previous pattern; consider removing it}} case 1, 2: break // expected-warning 2 {{literal value is already handled by previous pattern; consider removing it}} @@ -655,10 +660,12 @@ func checkLiterals() { switch int { case 10: break case 0b10: break // expected-note {{first occurrence of identical literal pattern is here}} + case -0b10: break // expected-note {{first occurrence of identical literal pattern is here}} case 3000: break case 0x12: break // expected-note {{first occurrence of identical literal pattern is here}} case 400: break case 2: break // expected-warning {{literal value is already handled by previous pattern; consider removing it}} + case -2: break // expected-warning {{literal value is already handled by previous pattern; consider removing it}} case 18: break // expected-warning {{literal value is already handled by previous pattern; consider removing it}} default: break } @@ -681,6 +688,9 @@ func checkLiterals() { // No Diagnostics switch dbl { + case -3.5: break + case -2.5: break + case -1.5: break case 1.5: break case 2.5: break case 3.5: break @@ -688,6 +698,10 @@ func checkLiterals() { } switch dbl { + case -3.5: break + case -2.5: break // expected-note {{first occurrence of identical literal pattern is here}} + case -2.5: break // expected-warning {{literal value is already handled by previous pattern; consider removing it}} + case -1.5: break case 1.5: break case 2.5: break // expected-note {{first occurrence of identical literal pattern is here}} case 2.5: break // expected-warning {{literal value is already handled by previous pattern; consider removing it}}