Skip to content

Commit 03e50c4

Browse files
authored
[flang] Emit warning when Hollerith actual passed to CLASS(*) (#84084)
When a Hollerith actual argument is associated with an unlimited polymorphic dummy argument, it's treated as if it were CHARACTER. Some other compilers treat it as if it had been BOZ, so emit a portability warning. Resolves #83548.
1 parent 4dd186a commit 03e50c4

File tree

4 files changed

+29
-3
lines changed

4 files changed

+29
-3
lines changed

flang/include/flang/Evaluate/constant.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,8 @@ class Constant<Type<TypeCategory::Character, KIND>> : public ConstantBounds {
186186

187187
const Scalar<Result> &values() const { return values_; }
188188
ConstantSubscript LEN() const { return length_; }
189+
bool wasHollerith() const { return wasHollerith_; }
190+
void set_wasHollerith(bool yes = true) { wasHollerith_ = yes; }
189191

190192
std::optional<Scalar<Result>> GetScalarValue() const {
191193
if (Rank() == 0) {
@@ -210,6 +212,7 @@ class Constant<Type<TypeCategory::Character, KIND>> : public ConstantBounds {
210212
private:
211213
Scalar<Result> values_; // one contiguous string
212214
ConstantSubscript length_;
215+
bool wasHollerith_{false};
213216
};
214217

215218
class StructureConstructor;

flang/lib/Semantics/check-call.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,15 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
332332
bool typesCompatible{typesCompatibleWithIgnoreTKR ||
333333
dummy.type.type().IsTkCompatibleWith(actualType.type())};
334334
int dummyRank{dummy.type.Rank()};
335-
if (!typesCompatible && dummyRank == 0 && allowActualArgumentConversions) {
335+
if (typesCompatible) {
336+
if (const auto *constantChar{
337+
evaluate::UnwrapConstantValue<evaluate::Ascii>(actual)};
338+
constantChar && constantChar->wasHollerith() &&
339+
dummy.type.type().IsUnlimitedPolymorphic()) {
340+
messages.Say(
341+
"passing Hollerith to unlimited polymorphic as if it were CHARACTER"_port_en_US);
342+
}
343+
} else if (dummyRank == 0 && allowActualArgumentConversions) {
336344
// Extension: pass Hollerith literal to scalar as if it had been BOZ
337345
if (auto converted{evaluate::HollerithToBOZ(
338346
foldingContext, actual, dummy.type.type())}) {

flang/lib/Semantics/expression.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -875,8 +875,11 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::CharLiteralConstant &x) {
875875
MaybeExpr ExpressionAnalyzer::Analyze(
876876
const parser::HollerithLiteralConstant &x) {
877877
int kind{GetDefaultKind(TypeCategory::Character)};
878-
auto value{x.v};
879-
return AnalyzeString(std::move(value), kind);
878+
auto result{AnalyzeString(std::string{x.v}, kind)};
879+
if (auto *constant{UnwrapConstantValue<Ascii>(result)}) {
880+
constant->set_wasHollerith(true);
881+
}
882+
return result;
880883
}
881884

882885
// .TRUE. and .FALSE. of various kinds

flang/test/Semantics/call41.f90

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
! RUN: %python %S/test_errors.py %s %flang_fc1 -Werror
2+
module m
3+
contains
4+
subroutine unlimited(x)
5+
class(*), intent(in) :: x
6+
end
7+
subroutine test
8+
!PORTABILITY: passing Hollerith to unlimited polymorphic as if it were CHARACTER
9+
call unlimited(6HHERMAN)
10+
call unlimited('abc') ! ok
11+
end
12+
end

0 commit comments

Comments
 (0)