[flang] Correctly detect overlapping integer cases
authorTim Keith <tkeith@nvidia.com>
Mon, 14 Sep 2020 16:10:45 +0000 (09:10 -0700)
committerTim Keith <tkeith@nvidia.com>
Mon, 14 Sep 2020 16:10:49 +0000 (09:10 -0700)
Integer case values were being compared as unsigned by operator<
on evaluate::value::Integer. Change that to signed so that overlap
can be detected correctly.

Explicit CompareUnsigned and BLT are still available if unsigned
comparison is needed.

Fixes https://bugs.llvm.org/show_bug.cgi?id=47309

Differential Revision: https://reviews.llvm.org/D87595

flang/include/flang/Evaluate/integer.h
flang/test/Semantics/case01.f90

index 6b91cb2..20b6731 100644 (file)
@@ -176,22 +176,22 @@ public:
   constexpr Integer &operator=(const Integer &) = default;
 
   constexpr bool operator<(const Integer &that) const {
-    return CompareUnsigned(that) == Ordering::Less;
+    return CompareSigned(that) == Ordering::Less;
   }
   constexpr bool operator<=(const Integer &that) const {
-    return CompareUnsigned(that) != Ordering::Greater;
+    return CompareSigned(that) != Ordering::Greater;
   }
   constexpr bool operator==(const Integer &that) const {
-    return CompareUnsigned(that) == Ordering::Equal;
+    return CompareSigned(that) == Ordering::Equal;
   }
   constexpr bool operator!=(const Integer &that) const {
     return !(*this == that);
   }
   constexpr bool operator>=(const Integer &that) const {
-    return CompareUnsigned(that) != Ordering::Less;
+    return CompareSigned(that) != Ordering::Less;
   }
   constexpr bool operator>(const Integer &that) const {
-    return CompareUnsigned(that) == Ordering::Greater;
+    return CompareSigned(that) == Ordering::Greater;
   }
 
   // Left-justified mask (e.g., MASKL(1) has only its sign bit set)
index e1965db..6342233 100644 (file)
@@ -163,3 +163,17 @@ program selectCaseProg
    end select
 
 end program
+
+program test_overlap
+  integer :: i
+  !OK: these cases do not overlap
+  select case(i)
+    case(0:)
+    case(:-1)
+  end select
+  select case(i)
+    case(-1:)
+    !ERROR: CASE (:0_4) conflicts with previous cases
+    case(:0)
+  end select
+end