[flang-commits] [flang] [flang] Add warnings for non-standard C_F_POINTER() usage (PR #78332)

via flang-commits flang-commits at lists.llvm.org
Tue Jan 16 11:34:07 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-flang-semantics

Author: Peter Klausler (klausler)

<details>
<summary>Changes</summary>

There's a few restrictions in the standard on the Fortran pointer argument (FPTR=) to the intrinsic subroutine C_F_POINTER() that almost no compilers enforce.  Enforce them here with warnings.

---
Full diff: https://github.com/llvm/llvm-project/pull/78332.diff


2 Files Affected:

- (modified) flang/lib/Evaluate/intrinsics.cpp (+19-4) 
- (modified) flang/test/Semantics/c_f_pointer.f90 (+13-1) 


``````````diff
diff --git a/flang/lib/Evaluate/intrinsics.cpp b/flang/lib/Evaluate/intrinsics.cpp
index da6d5970089884..7d2e45dcbe96de 100644
--- a/flang/lib/Evaluate/intrinsics.cpp
+++ b/flang/lib/Evaluate/intrinsics.cpp
@@ -2663,13 +2663,28 @@ IntrinsicProcTable::Implementation::HandleC_F_Pointer(
     }
     if (const auto *expr{arguments[1].value().UnwrapExpr()}) {
       int fptrRank{expr->Rank()};
+      auto at{arguments[1]->sourceLocation()};
       if (auto type{expr->GetType()}) {
         if (type->HasDeferredTypeParameter()) {
-          context.messages().Say(arguments[1]->sourceLocation(),
+          context.messages().Say(at,
               "FPTR= argument to C_F_POINTER() may not have a deferred type parameter"_err_en_US);
+        } else if (type->category() == TypeCategory::Derived) {
+          if (type->IsUnlimitedPolymorphic()) {
+            context.messages().Say(at,
+                "FPTR= argument to C_F_POINTER() should not be unlimited polymorphic"_warn_en_US);
+          } else if (!type->GetDerivedTypeSpec().typeSymbol().attrs().test(
+                         semantics::Attr::BIND_C)) {
+            context.messages().Say(at,
+                "FPTR= argument to C_F_POINTER() should not have a derived type that is not BIND(C)"_warn_en_US);
+          }
+        } else if (!IsInteroperableIntrinsicType(
+                       *type, &context.languageFeatures())) {
+          context.messages().Say(at,
+              "FPTR= argument to C_F_POINTER() should not have the non-interoperable intrinsic type %s"_warn_en_US,
+              type->AsFortran());
         }
         if (ExtractCoarrayRef(*expr)) {
-          context.messages().Say(arguments[1]->sourceLocation(),
+          context.messages().Say(at,
               "FPTR= argument to C_F_POINTER() may not be a coindexed object"_err_en_US);
         }
         characteristics::DummyDataObject fptr{
@@ -2678,8 +2693,8 @@ IntrinsicProcTable::Implementation::HandleC_F_Pointer(
         fptr.attrs.set(characteristics::DummyDataObject::Attr::Pointer);
         dummies.emplace_back("fptr"s, std::move(fptr));
       } else {
-        context.messages().Say(arguments[1]->sourceLocation(),
-            "FPTR= argument to C_F_POINTER() must have a type"_err_en_US);
+        context.messages().Say(
+            at, "FPTR= argument to C_F_POINTER() must have a type"_err_en_US);
       }
       if (arguments[2] && fptrRank == 0) {
         context.messages().Say(arguments[2]->sourceLocation(),
diff --git a/flang/test/Semantics/c_f_pointer.f90 b/flang/test/Semantics/c_f_pointer.f90
index 0c1e8544b02b18..c2529201ee2659 100644
--- a/flang/test/Semantics/c_f_pointer.f90
+++ b/flang/test/Semantics/c_f_pointer.f90
@@ -1,4 +1,4 @@
-! RUN: %python %S/test_errors.py %s %flang_fc1
+! RUN: %python %S/test_errors.py %s %flang_fc1 -pedantic
 ! Enforce 18.2.3.3
 
 program test
@@ -12,6 +12,12 @@ program test
   character(len=:), pointer :: charDeferredF
   integer :: j
   integer, dimension(2, 2) :: rankTwoArray
+  class(*), pointer :: unlimited
+  type :: notBindCType
+    integer :: n
+  end type
+  type(notBindCType), pointer :: notBindC
+  character(2), pointer :: c2ptr
   rankTwoArray = reshape([1, 2, 3, 4], shape(rankTwoArray))
   call c_f_pointer(scalarC, scalarIntF) ! ok
   call c_f_pointer(scalarC, arrayIntF, [1_8]) ! ok
@@ -38,4 +44,10 @@ program test
   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)
+  !WARNING: FPTR= argument to C_F_POINTER() should not be unlimited polymorphic
+  call c_f_pointer(scalarC, unlimited)
+  !WARNING: FPTR= argument to C_F_POINTER() should not have a derived type that is not BIND(C)
+  call c_f_pointer(scalarC, notBindC)
+  !WARNING: FPTR= argument to C_F_POINTER() should not have the non-interoperable intrinsic type CHARACTER(KIND=1,LEN=2_8)
+  call c_f_pointer(scalarC, c2ptr)
 end program

``````````

</details>


https://github.com/llvm/llvm-project/pull/78332


More information about the flang-commits mailing list