Skip to content

Commit 5a9d684

Browse files
authored
[flang] Split interoperability warnings, disable some by default (#111922)
Type interoperability warnings current issue for intrinsic types when their type, kind, or length do not meet the requirements for C interoperability. This turns out to be too noisy for the case of one-byte characters with lengths other than one when creating C pointers from C_LOC or C_F_POINTER -- it is not uncommon for programs to use pointers to longer character objects. So split the interoperability warning so that the case of a known bad character length for an otherwise interoperable type is controlled by its own UsageWarning enumerator, and leave that usage warning off by default. This will better fit expectations in the default case while still showing a warning under -pedantic.
1 parent 8588014 commit 5a9d684

File tree

5 files changed

+45
-17
lines changed

5 files changed

+45
-17
lines changed

flang/include/flang/Common/Fortran-features.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,9 @@ ENUM_CLASS(UsageWarning, Portability, PointerToUndefinable,
6363
F202XAllocatableBreakingChange, OptionalMustBePresent, CommonBlockPadding,
6464
LogicalVsCBool, BindCCharLength, ProcDummyArgShapes, ExternalNameConflict,
6565
FoldingException, FoldingAvoidsRuntimeCrash, FoldingValueChecks,
66-
FoldingFailure, FoldingLimit, Interoperability, Bounds, Preprocessing,
67-
Scanning, OpenAccUsage, ProcPointerCompatibility, VoidMold,
68-
KnownBadImplicitInterface, EmptyCase, CaseOverflow, CUDAUsage,
66+
FoldingFailure, FoldingLimit, Interoperability, CharacterInteroperability,
67+
Bounds, Preprocessing, Scanning, OpenAccUsage, ProcPointerCompatibility,
68+
VoidMold, KnownBadImplicitInterface, EmptyCase, CaseOverflow, CUDAUsage,
6969
IgnoreTKRUsage, ExternalInterfaceMismatch, DefinedOperatorArgs, Final,
7070
ZeroDoStep, UnusedForallIndex, OpenMPUsage, ModuleFile, DataLength,
7171
IgnoredDirective, HomonymousSpecific, HomonymousResult,

flang/lib/Common/Fortran-features.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ LanguageFeatureControl::LanguageFeatureControl() {
4848
warnUsage_.set(UsageWarning::FoldingFailure);
4949
warnUsage_.set(UsageWarning::FoldingLimit);
5050
warnUsage_.set(UsageWarning::Interoperability);
51+
// CharacterInteroperability warnings about length are off by default
5152
warnUsage_.set(UsageWarning::Bounds);
5253
warnUsage_.set(UsageWarning::Preprocessing);
5354
warnUsage_.set(UsageWarning::Scanning);

flang/lib/Evaluate/intrinsics.cpp

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2861,12 +2861,22 @@ IntrinsicProcTable::Implementation::HandleC_F_Pointer(
28612861
}
28622862
} else if (!IsInteroperableIntrinsicType(
28632863
*type, &context.languageFeatures())
2864-
.value_or(true) &&
2865-
context.languageFeatures().ShouldWarn(
2866-
common::UsageWarning::Interoperability)) {
2867-
context.messages().Say(common::UsageWarning::Interoperability, at,
2868-
"FPTR= argument to C_F_POINTER() should not have the non-interoperable intrinsic type %s"_warn_en_US,
2869-
type->AsFortran());
2864+
.value_or(true)) {
2865+
if (type->category() == TypeCategory::Character &&
2866+
type->kind() == 1) {
2867+
if (context.languageFeatures().ShouldWarn(
2868+
common::UsageWarning::CharacterInteroperability)) {
2869+
context.messages().Say(
2870+
common::UsageWarning::CharacterInteroperability, at,
2871+
"FPTR= argument to C_F_POINTER() should not have the non-interoperable character length %s"_warn_en_US,
2872+
type->AsFortran());
2873+
}
2874+
} else if (context.languageFeatures().ShouldWarn(
2875+
common::UsageWarning::Interoperability)) {
2876+
context.messages().Say(common::UsageWarning::Interoperability, at,
2877+
"FPTR= argument to C_F_POINTER() should not have the non-interoperable intrinsic type or kind %s"_warn_en_US,
2878+
type->AsFortran());
2879+
}
28702880
}
28712881
if (ExtractCoarrayRef(*expr)) {
28722882
context.messages().Say(at,
@@ -2963,12 +2973,23 @@ std::optional<SpecificCall> IntrinsicProcTable::Implementation::HandleC_Loc(
29632973
context.messages().Say(arguments[0]->sourceLocation(),
29642974
"C_LOC() argument may not be zero-length character"_err_en_US);
29652975
} else if (typeAndShape->type().category() != TypeCategory::Derived &&
2966-
!IsInteroperableIntrinsicType(typeAndShape->type()).value_or(true) &&
2967-
context.languageFeatures().ShouldWarn(
2968-
common::UsageWarning::Interoperability)) {
2969-
context.messages().Say(common::UsageWarning::Interoperability,
2970-
arguments[0]->sourceLocation(),
2971-
"C_LOC() argument has non-interoperable intrinsic type, kind, or length"_warn_en_US);
2976+
!IsInteroperableIntrinsicType(typeAndShape->type()).value_or(true)) {
2977+
if (typeAndShape->type().category() == TypeCategory::Character &&
2978+
typeAndShape->type().kind() == 1) {
2979+
// Default character kind, but length is not known to be 1
2980+
if (context.languageFeatures().ShouldWarn(
2981+
common::UsageWarning::CharacterInteroperability)) {
2982+
context.messages().Say(
2983+
common::UsageWarning::CharacterInteroperability,
2984+
arguments[0]->sourceLocation(),
2985+
"C_LOC() argument has non-interoperable character length"_warn_en_US);
2986+
}
2987+
} else if (context.languageFeatures().ShouldWarn(
2988+
common::UsageWarning::Interoperability)) {
2989+
context.messages().Say(common::UsageWarning::Interoperability,
2990+
arguments[0]->sourceLocation(),
2991+
"C_LOC() argument has non-interoperable intrinsic type or kind"_warn_en_US);
2992+
}
29722993
}
29732994

29742995
characteristics::DummyDataObject ddo{std::move(*typeAndShape)};

flang/test/Semantics/c_f_pointer.f90

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ program test
1818
end type
1919
type(notBindCType), pointer :: notBindC
2020
character(2), pointer :: c2ptr
21+
character(1,4), pointer :: unicodePtr
2122
rankTwoArray = reshape([1, 2, 3, 4], shape(rankTwoArray))
2223
call c_f_pointer(scalarC, scalarIntF) ! ok
2324
call c_f_pointer(scalarC, arrayIntF, [1_8]) ! ok
@@ -48,6 +49,8 @@ program test
4849
call c_f_pointer(scalarC, unlimited)
4950
!WARNING: FPTR= argument to C_F_POINTER() should not have a derived type that is not BIND(C)
5051
call c_f_pointer(scalarC, notBindC)
51-
!WARNING: FPTR= argument to C_F_POINTER() should not have the non-interoperable intrinsic type CHARACTER(KIND=1,LEN=2_8)
52+
!WARNING: FPTR= argument to C_F_POINTER() should not have the non-interoperable character length CHARACTER(KIND=1,LEN=2_8)
5253
call c_f_pointer(scalarC, c2ptr)
54+
!WARNING: FPTR= argument to C_F_POINTER() should not have the non-interoperable intrinsic type or kind CHARACTER(KIND=4,LEN=1_8)
55+
call c_f_pointer(scalarC, unicodePtr)
5356
end program

flang/test/Semantics/c_loc01.f90

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ subroutine test(assumedType, poly, nclen, n)
2121
type(hasLen(*)), target :: nclen
2222
integer, intent(in) :: n
2323
character(2), target :: ch
24+
character(1,4), target :: unicode
2425
real :: arr1(purefun1(c_loc(targ))) ! ok
2526
real :: arr2(purefun2(c_funloc(subr))) ! ok
2627
character(:), allocatable, target :: deferred
@@ -40,8 +41,10 @@ subroutine test(assumedType, poly, nclen, n)
4041
cp = c_loc(nclen)
4142
!ERROR: C_LOC() argument may not be zero-length character
4243
cp = c_loc(ch(2:1))
43-
!WARNING: C_LOC() argument has non-interoperable intrinsic type, kind, or length
44+
!WARNING: C_LOC() argument has non-interoperable character length
4445
cp = c_loc(ch)
46+
!WARNING: C_LOC() argument has non-interoperable intrinsic type or kind
47+
cp = c_loc(unicode)
4548
cp = c_loc(ch(1:1)) ! ok
4649
cp = c_loc(deferred) ! ok
4750
cp = c_loc(p2ch) ! ok

0 commit comments

Comments
 (0)