Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions flang/include/flang/Semantics/type.h
Original file line number Diff line number Diff line change
Expand Up @@ -459,8 +459,5 @@ inline const DerivedTypeSpec *DeclTypeSpec::AsDerived() const {
return const_cast<DeclTypeSpec *>(this)->AsDerived();
}

std::optional<bool> IsInteroperableIntrinsicType(
const DeclTypeSpec &, const common::LanguageFeatureControl &);

} // namespace Fortran::semantics
#endif // FORTRAN_SEMANTICS_TYPE_H_
4 changes: 2 additions & 2 deletions flang/lib/Evaluate/type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -820,8 +820,8 @@ std::optional<bool> IsInteroperableIntrinsicType(const DynamicType &type,
return true;
case TypeCategory::Real:
case TypeCategory::Complex:
return (features && features->IsEnabled(common::LanguageFeature::CUDA)) ||
type.kind() >= 4; // no short or half floats
return type.kind() >= 4 /* not a short or half float */ || !features ||
features->IsEnabled(common::LanguageFeature::CUDA);
case TypeCategory::Logical:
return type.kind() == 1; // C_BOOL
case TypeCategory::Character:
Expand Down
21 changes: 13 additions & 8 deletions flang/lib/Semantics/check-declarations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3003,17 +3003,17 @@ parser::Messages CheckHelper::WhyNotInteroperableDerivedType(
} else {
msgs.Annex(std::move(bad));
}
} else if (!IsInteroperableIntrinsicType(
*type, context_.languageFeatures())
} else if (auto dyType{evaluate::DynamicType::From(*type)}; dyType &&
!evaluate::IsInteroperableIntrinsicType(
*dyType, &context_.languageFeatures())
.value_or(false)) {
auto maybeDyType{evaluate::DynamicType::From(*type)};
if (type->category() == DeclTypeSpec::Logical) {
if (context_.ShouldWarn(common::UsageWarning::LogicalVsCBool)) {
msgs.Say(component.name(),
"A LOGICAL component of an interoperable type should have the interoperable KIND=C_BOOL"_port_en_US);
}
} else if (type->category() == DeclTypeSpec::Character &&
maybeDyType && maybeDyType->kind() == 1) {
} else if (type->category() == DeclTypeSpec::Character && dyType &&
dyType->kind() == 1) {
if (context_.ShouldWarn(common::UsageWarning::BindCCharLength)) {
msgs.Say(component.name(),
"A CHARACTER component of an interoperable type should have length 1"_port_en_US);
Expand Down Expand Up @@ -3106,10 +3106,15 @@ parser::Messages CheckHelper::WhyNotInteroperableObject(const Symbol &symbol) {
type->category() == DeclTypeSpec::Character &&
type->characterTypeSpec().length().isDeferred()) {
// ok; F'2023 18.3.7 p2(6)
} else if (derived ||
IsInteroperableIntrinsicType(*type, context_.languageFeatures())
.value_or(false)) {
} else if (derived) { // type has been checked
} else if (auto dyType{evaluate::DynamicType::From(*type)}; dyType &&
evaluate::IsInteroperableIntrinsicType(*dyType,
InModuleFile() ? nullptr : &context_.languageFeatures())
.value_or(false)) {
// F'2023 18.3.7 p2(4,5)
// N.B. Language features are not passed to IsInteroperableIntrinsicType
// when processing a module file, since the module file might have been
// compiled with CUDA while the client is not.
} else if (type->category() == DeclTypeSpec::Logical) {
if (context_.ShouldWarn(common::UsageWarning::LogicalVsCBool) &&
!InModuleFile()) {
Expand Down
4 changes: 2 additions & 2 deletions flang/lib/Semantics/expression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1956,7 +1956,7 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::ArrayConstructor &array) {

// Check if implicit conversion of expr to the symbol type is legal (if needed),
// and make it explicit if requested.
static MaybeExpr implicitConvertTo(const semantics::Symbol &sym,
static MaybeExpr ImplicitConvertTo(const semantics::Symbol &sym,
Expr<SomeType> &&expr, bool keepConvertImplicit) {
if (!keepConvertImplicit) {
return ConvertToType(sym, std::move(expr));
Expand Down Expand Up @@ -2196,7 +2196,7 @@ MaybeExpr ExpressionAnalyzer::Analyze(
// convert would cause a segfault. Lowering will deal with
// conditionally converting and preserving the lower bounds in this
// case.
if (MaybeExpr converted{implicitConvertTo(
if (MaybeExpr converted{ImplicitConvertTo(
*symbol, std::move(*value), IsAllocatable(*symbol))}) {
if (auto componentShape{GetShape(GetFoldingContext(), *symbol)}) {
if (auto valueShape{GetShape(GetFoldingContext(), *converted)}) {
Expand Down
9 changes: 0 additions & 9 deletions flang/lib/Semantics/type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -893,13 +893,4 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &o, const DeclTypeSpec &x) {
return o << x.AsFortran();
}

std::optional<bool> IsInteroperableIntrinsicType(
const DeclTypeSpec &type, const common::LanguageFeatureControl &features) {
if (auto dyType{evaluate::DynamicType::From(type)}) {
return IsInteroperableIntrinsicType(*dyType, &features);
} else {
return std::nullopt;
}
}

} // namespace Fortran::semantics
4 changes: 4 additions & 0 deletions flang/test/Semantics/Inputs/modfile66.cuf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module usereal2
!REAL(2) is interoperable under CUDA
real(2), bind(c) :: x
end
3 changes: 3 additions & 0 deletions flang/test/Semantics/modfile66.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
! RUN: %flang_fc1 -fsyntax-only %S/Inputs/modfile66.cuf && %flang_fc1 -fsyntax-only %s
use usereal2 ! valid since x is not used
end