[flang-commits] [flang] 4966023 - [Flang] Checks for constraint C7110-C7115.

Sameeran joshi via flang-commits flang-commits at lists.llvm.org
Fri Jul 31 10:58:13 PDT 2020


Author: sameeran joshi
Date: 2020-07-31T23:27:57+05:30
New Revision: 49660234db94faf54c2d0ffa150841b9b52671c9

URL: https://github.com/llvm/llvm-project/commit/49660234db94faf54c2d0ffa150841b9b52671c9
DIFF: https://github.com/llvm/llvm-project/commit/49660234db94faf54c2d0ffa150841b9b52671c9.diff

LOG: [Flang] Checks for constraint C7110-C7115.

Added more tests.
	 Annotate sources and tests.
	 Improve error message.

Reviewed By: PeteSteinfeld

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

Added: 
    flang/test/Semantics/array-constr-values.f90

Modified: 
    flang/lib/Semantics/expression.cpp

Removed: 
    


################################################################################
diff  --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp
index e78c2d20edcf..3ec2af5d70fa 100644
--- a/flang/lib/Semantics/expression.cpp
+++ b/flang/lib/Semantics/expression.cpp
@@ -1202,6 +1202,7 @@ class ArrayConstructorContext {
   bool explicitType_{type_.has_value()};
   std::optional<std::int64_t> constantLength_;
   ArrayConstructorValues<SomeType> values_;
+  bool messageDisplayedOnce{false};
 };
 
 void ArrayConstructorContext::Push(MaybeExpr &&x) {
@@ -1252,17 +1253,21 @@ void ArrayConstructorContext::Push(MaybeExpr &&x) {
           }
         }
       } else {
-        exprAnalyzer_.Say(
-            "Values in array constructor must have the same declared type "
-            "when no explicit type appears"_err_en_US);
+        if (!messageDisplayedOnce) {
+          exprAnalyzer_.Say(
+              "Values in array constructor must have the same declared type "
+              "when no explicit type appears"_err_en_US); // C7110
+          messageDisplayedOnce = true;
+        }
       }
     } else {
       if (auto cast{ConvertToType(*type_, std::move(*x))}) {
         values_.Push(std::move(*cast));
       } else {
         exprAnalyzer_.Say(
-            "Value in array constructor could not be converted to the type "
-            "of the array"_err_en_US);
+            "Value in array constructor of type '%s' could not "
+            "be converted to the type of the array '%s'"_err_en_US,
+            x->GetType()->AsFortran(), type_->AsFortran()); // C7111, C7112
       }
     }
   }
@@ -1304,7 +1309,7 @@ void ArrayConstructorContext::Add(const parser::AcValue &x) {
                 if (exprType->IsUnlimitedPolymorphic()) {
                   exprAnalyzer_.Say(
                       "Cannot have an unlimited polymorphic value in an "
-                      "array constructor"_err_en_US);
+                      "array constructor"_err_en_US); // C7113
                 }
               }
               Push(std::move(*v));
@@ -1346,7 +1351,7 @@ void ArrayConstructorContext::Add(const parser::AcValue &x) {
             } else {
               exprAnalyzer_.SayAt(name,
                   "Implied DO index is active in surrounding implied DO loop "
-                  "and may not have the same name"_err_en_US);
+                  "and may not have the same name"_err_en_US); // C7115
             }
           },
       },
@@ -1386,7 +1391,7 @@ MaybeExpr ExpressionAnalyzer::Analyze(
                           "ABSTRACT derived type '%s' may not be used in a "
                           "structure constructor"_err_en_US,
                           typeName),
-        typeSymbol);
+        typeSymbol); // C7114
   }
 
   // This iterator traverses all of the components in the derived type and its

diff  --git a/flang/test/Semantics/array-constr-values.f90 b/flang/test/Semantics/array-constr-values.f90
new file mode 100644
index 000000000000..30739f8c095b
--- /dev/null
+++ b/flang/test/Semantics/array-constr-values.f90
@@ -0,0 +1,60 @@
+! RUN: %S/test_errors.sh %s %t %f18
+! Confirm enforcement of constraints and restrictions in 7.8
+! C7110, C7111, C7112, C7113, C7114, C7115
+
+subroutine arrayconstructorvalues()
+  integer :: intarray(5)
+  integer(KIND=8) :: k8 = 20
+
+  TYPE EMPLOYEE
+    INTEGER AGE
+    CHARACTER (LEN = 30) NAME
+  END TYPE EMPLOYEE
+  TYPE EMPLOYEER
+    CHARACTER (LEN = 30) NAME
+  END TYPE EMPLOYEER
+
+  TYPE(EMPLOYEE) :: emparray(3)
+  class(*), pointer :: unlim_polymorphic
+  TYPE, ABSTRACT :: base_type
+    INTEGER :: CARPRIZE
+  END TYPE
+  ! Different declared type
+  !ERROR: Values in array constructor must have the same declared type when no explicit type appears
+  intarray = (/ 1, 2, 3, 4., 5/)  ! C7110
+  ! Different kind type parameter
+  !ERROR: Values in array constructor must have the same declared type when no explicit type appears
+  intarray = (/ 1,2,3,4, k8 /)    ! C7110
+
+  ! C7111
+  !ERROR: Value in array constructor of type 'LOGICAL(4)' could not be converted to the type of the array 'INTEGER(4)'
+  intarray = [integer:: .true., 2, 3, 4, 5]
+  !ERROR: Value in array constructor of type 'CHARACTER(1)' could not be converted to the type of the array 'INTEGER(4)'
+  intarray = [integer:: "RAM stores information", 2, 3, 4, 5]
+  !ERROR: Value in array constructor of type 'employee' could not be converted to the type of the array 'INTEGER(4)'
+  intarray = [integer:: EMPLOYEE (19, "Jack"), 2, 3, 4, 5]
+
+  ! C7112
+  !ERROR: Value in array constructor of type 'INTEGER(4)' could not be converted to the type of the array 'employee'
+  emparray = (/ EMPLOYEE:: EMPLOYEE(19, "Ganesh"), EMPLOYEE(22, "Omkar"), 19 /)
+  !ERROR: Value in array constructor of type 'employeer' could not be converted to the type of the array 'employee'
+  emparray = (/ EMPLOYEE:: EMPLOYEE(19, "Ganesh"), EMPLOYEE(22, "Ram"),EMPLOYEER("ShriniwasPvtLtd") /)
+
+  ! C7113
+  !ERROR: Cannot have an unlimited polymorphic value in an array constructor
+  !ERROR: Values in array constructor must have the same declared type when no explicit type appears
+  intarray = (/ unlim_polymorphic, 2, 3, 4, 5/)
+
+  ! C7114
+  !ERROR: No intrinsic or user-defined ASSIGNMENT(=) matches operand types INTEGER(4) and TYPE(base_type)
+  !ERROR: ABSTRACT derived type 'base_type' may not be used in a structure constructor
+  !ERROR: Values in array constructor must have the same declared type when no explicit type appears
+  intarray = (/ base_type(10), 2, 3, 4, 5 /)
+end subroutine arrayconstructorvalues
+subroutine checkC7115()
+  real, dimension(10), parameter :: good1 = [(99.9, i = 1, 10)]
+  real, dimension(100), parameter :: good2 = [((88.8, i = 1, 10), j = 1, 10)]
+  !ERROR: Implied DO index is active in surrounding implied DO loop and may not have the same name
+  !ERROR: 'i' is already declared in this scoping unit
+  real, dimension(100), parameter :: bad = [((88.8, i = 1, 10), i = 1, 10)]
+end subroutine checkC7115


        


More information about the flang-commits mailing list