[flang] Diagnostic for shape argument in c_f_pointer
authorQihan Cai <qcai8733@uni.sydney.edu.au>
Sat, 26 Nov 2022 10:46:29 +0000 (21:46 +1100)
committerQihan Cai <qcai8733@uni.sydney.edu.au>
Mon, 5 Dec 2022 03:09:04 +0000 (14:09 +1100)
Fix #59177, add check for dimensionality for shape argument against rank of FPTR argument in c_f_pointer

Reviewed By: peixin

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

flang/lib/Evaluate/intrinsics.cpp
flang/test/Semantics/c_f_pointer.f90

index a944217..308e3e9 100644 (file)
@@ -2616,6 +2616,20 @@ IntrinsicProcTable::Implementation::HandleC_F_Pointer(
       } else if (!arguments[2] && fptrRank > 0) {
         context.messages().Say(
             "SHAPE= argument to C_F_POINTER() must appear when FPTR= is an array"_err_en_US);
+      } else if (arguments[2]) {
+        if (const auto *argExpr{arguments[2].value().UnwrapExpr()}) {
+          if (argExpr->Rank() > 1) {
+            context.messages().Say(arguments[2]->sourceLocation(),
+                "SHAPE= argument to C_F_POINTER() must be a rank-one array."_err_en_US);
+          } else if (argExpr->Rank() == 1) {
+            if (auto constShape{GetConstantShape(context, *argExpr)}) {
+              if (constShape->At(ConstantSubscripts{1}).ToInt64() != fptrRank) {
+                context.messages().Say(arguments[2]->sourceLocation(),
+                    "SHAPE= argument to C_F_POINTER() must have size equal to the rank of FPTR="_err_en_US);
+              }
+            }
+          }
+        }
       }
     }
   }
index 2d78033..2613a4d 100644 (file)
@@ -8,9 +8,11 @@ program test
     integer, pointer :: p
   end type
   type(with_pointer) :: coindexed[*]
-  integer, pointer :: scalarIntF, arrayIntF(:)
+  integer, pointer :: scalarIntF, arrayIntF(:), multiDimIntF(:,:)
   character(len=:), pointer :: charDeferredF
   integer :: j
+  integer, dimension(2, 2) :: rankTwoArray
+  rankTwoArray = reshape([1, 2, 3, 4], shape(rankTwoArray))
   call c_f_pointer(scalarC, scalarIntF) ! ok
   call c_f_pointer(scalarC, arrayIntF, [1_8]) ! ok
   call c_f_pointer(shape=[1_8], cptr=scalarC, fptr=arrayIntF) ! ok
@@ -31,4 +33,8 @@ program test
   call c_f_pointer(scalarC, coindexed[0]%p)
   !ERROR: FPTR= argument to C_F_POINTER() must have a type
   call c_f_pointer(scalarC, null())
+  !ERROR: SHAPE= argument to C_F_POINTER() must have size equal to the rank of FPTR=
+  call c_f_pointer(scalarC, multiDimIntF, shape=[1_8])
+  !ERROR: SHAPE= argument to C_F_POINTER() must be a rank-one array.
+  call c_f_pointer(scalarC, multiDimIntF, shape=rankTwoArray)
 end program