aboutsummaryrefslogtreecommitdiff
path: root/flang/lib/Evaluate/intrinsics.cpp
diff options
context:
space:
mode:
authorPeter Klausler <35819229+klausler@users.noreply.github.com>2024-01-25 13:50:40 -0800
committerGitHub <noreply@github.com>2024-01-25 13:50:40 -0800
commitc2e5f4d3a14ae5b5c1c7e335a6336774f456e656 (patch)
treeaf2a6a204b53b95b35270c096bc75aed95aefacf /flang/lib/Evaluate/intrinsics.cpp
parent5aad7894812a53b69e989a61a567f5617df4a057 (diff)
downloadllvm-c2e5f4d3a14ae5b5c1c7e335a6336774f456e656.zip
llvm-c2e5f4d3a14ae5b5c1c7e335a6336774f456e656.tar.gz
llvm-c2e5f4d3a14ae5b5c1c7e335a6336774f456e656.tar.bz2
[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.
Diffstat (limited to 'flang/lib/Evaluate/intrinsics.cpp')
-rw-r--r--flang/lib/Evaluate/intrinsics.cpp23
1 files changed, 19 insertions, 4 deletions
diff --git a/flang/lib/Evaluate/intrinsics.cpp b/flang/lib/Evaluate/intrinsics.cpp
index da6d5970..7d2e45d 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(),