[flang-commits] [flang] c2e5f4d - [flang] Add warnings for non-standard C_F_POINTER() usage (#78332)
via flang-commits
flang-commits at lists.llvm.org
Thu Jan 25 13:50:44 PST 2024
Author: Peter Klausler
Date: 2024-01-25T13:50:40-08:00
New Revision: c2e5f4d3a14ae5b5c1c7e335a6336774f456e656
URL: https://github.com/llvm/llvm-project/commit/c2e5f4d3a14ae5b5c1c7e335a6336774f456e656
DIFF: https://github.com/llvm/llvm-project/commit/c2e5f4d3a14ae5b5c1c7e335a6336774f456e656.diff
LOG: [flang] Add warnings for non-standard C_F_POINTER() usage (#78332)
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.
Added:
Modified:
flang/lib/Evaluate/intrinsics.cpp
flang/test/Semantics/c_f_pointer.f90
Removed:
################################################################################
diff --git a/flang/lib/Evaluate/intrinsics.cpp b/flang/lib/Evaluate/intrinsics.cpp
index da6d5970089884c..7d2e45dcbe96ded 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 0c1e8544b02b18a..c2529201ee26597 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
More information about the flang-commits
mailing list