[flang] Fix integer CASE constant typing
authorpeter klausler <pklausler@nvidia.com>
Mon, 31 Aug 2020 19:33:12 +0000 (12:33 -0700)
committerpeter klausler <pklausler@nvidia.com>
Tue, 1 Sep 2020 17:59:35 +0000 (10:59 -0700)
Don't use just 128-bit integer as the type for integer
CASE statement constants.  Use the actual type of the
literal constants that appeared.

Differential Review: https://reviews.llvm.org/D86875

flang/lib/Semantics/check-case.cpp
flang/test/Semantics/case01.f90

index 3f1586d..5aee11e 100644 (file)
@@ -9,6 +9,7 @@
 #include "check-case.h"
 #include "flang/Common/idioms.h"
 #include "flang/Common/reference.h"
+#include "flang/Common/template.h"
 #include "flang/Evaluate/fold.h"
 #include "flang/Evaluate/type.h"
 #include "flang/Parser/parse-tree.h"
@@ -201,6 +202,22 @@ private:
   bool hasErrors_{false};
 };
 
+template <TypeCategory CAT> struct TypeVisitor {
+  using Result = bool;
+  using Types = evaluate::CategoryTypes<CAT>;
+  template <typename T> Result Test() {
+    if (T::kind == exprType.kind()) {
+      CaseValues<T>(context, exprType).Check(caseList);
+      return true;
+    } else {
+      return false;
+    }
+  }
+  SemanticsContext &context;
+  const evaluate::DynamicType &exprType;
+  const std::list<parser::CaseConstruct::Case> &caseList;
+};
+
 void CaseChecker::Enter(const parser::CaseConstruct &construct) {
   const auto &selectCaseStmt{
       std::get<parser::Statement<parser::SelectCaseStmt>>(construct.t)};
@@ -216,32 +233,17 @@ void CaseChecker::Enter(const parser::CaseConstruct &construct) {
         std::get<std::list<parser::CaseConstruct::Case>>(construct.t)};
     switch (exprType->category()) {
     case TypeCategory::Integer:
-      CaseValues<evaluate::Type<TypeCategory::Integer, 16>>{context_, *exprType}
-          .Check(caseList);
+      common::SearchTypes(
+          TypeVisitor<TypeCategory::Integer>{context_, *exprType, caseList});
       return;
     case TypeCategory::Logical:
       CaseValues<evaluate::Type<TypeCategory::Logical, 1>>{context_, *exprType}
           .Check(caseList);
       return;
     case TypeCategory::Character:
-      switch (exprType->kind()) {
-        SWITCH_COVERS_ALL_CASES
-      case 1:
-        CaseValues<evaluate::Type<TypeCategory::Character, 1>>{
-            context_, *exprType}
-            .Check(caseList);
-        return;
-      case 2:
-        CaseValues<evaluate::Type<TypeCategory::Character, 2>>{
-            context_, *exprType}
-            .Check(caseList);
-        return;
-      case 4:
-        CaseValues<evaluate::Type<TypeCategory::Character, 4>>{
-            context_, *exprType}
-            .Check(caseList);
-        return;
-      }
+      common::SearchTypes(
+          TypeVisitor<TypeCategory::Character>{context_, *exprType, caseList});
+      return;
     default:
       break;
     }
index fc85ee7..e1965db 100644 (file)
@@ -135,11 +135,11 @@ program selectCaseProg
      case (40)
      case (90)
      case (91:99)
-     !ERROR: CASE (81_16:90_16) conflicts with previous cases
+     !ERROR: CASE (81_4:90_4) conflicts with previous cases
      case (81:90)
-     !ERROR: CASE (:80_16) conflicts with previous cases
+     !ERROR: CASE (:80_4) conflicts with previous cases
      case (:80)
-     !ERROR: CASE (200_16) conflicts with previous cases
+     !ERROR: CASE (200_4) conflicts with previous cases
      case (200)
      case default
   end select