[flang-commits] [clang] [flang] [flang] Enumeration Type: (PR 5/5) Enable (PR #231641)
via flang-commits
flang-commits at lists.llvm.org
Tue Oct 20 11:51:33 PDT 2026
https://github.com/kwyatt-ext updated https://github.com/llvm/llvm-project/pull/231641
>From c6d8974827d13a23081f384d744afb8aa697b205 Mon Sep 17 00:00:00 2001
From: Kevin Wyatt <kwyatt at hpe.com>
Date: Tue, 13 Oct 2026 12:48:08 -0500
Subject: [PATCH 1/3] - Removed gating to feature. - Modified tests to function
with remove gate. - Updated documents to reflect addition of feature.
---
clang/include/clang/Options/FlangOptions.td | 1 -
clang/lib/Driver/ToolChains/Flang.cpp | 20 +++-------
flang/docs/FortranStandardsSupport.md | 2 +-
flang/docs/ReleaseNotes.md | 12 ++++++
flang/lib/Evaluate/intrinsics.cpp | 10 +----
flang/lib/Frontend/CompilerInvocation.cpp | 6 ---
flang/lib/Semantics/resolve-names.cpp | 22 -----------
flang/lib/Support/Fortran-features.cpp | 4 --
.../enumeration-type-forall-stat-todo.f90 | 2 +-
.../Lower/enumeration-type-next-previous.f90 | 4 +-
flang/test/Lower/enumeration-type.f90 | 6 +--
.../enumeration-type-component-offset.f90 | 2 +-
.../enumeration-type-component-usage.f90 | 2 +-
.../enumeration-type-declarations.f90 | 10 +----
.../enumeration-type-explicit-value.f90 | 2 +-
.../enumeration-type-forward-ref.f90 | 3 +-
...enumeration-type-intrinsics-array-fold.f90 | 2 +-
.../enumeration-type-intrinsics-gating.f90 | 37 ++++++++++++-------
.../enumeration-type-intrinsics-keyword.f90 | 2 +-
.../enumeration-type-intrinsics-nonenum.f90 | 2 +-
.../enumeration-type-intrinsics-valid.f90 | 2 +-
.../Semantics/enumeration-type-intrinsics.f90 | 2 +-
.../enumeration-type-io-pdt-order.f90 | 3 +-
flang/test/Semantics/enumeration-type-io.f90 | 3 +-
.../test/Semantics/enumeration-type-misc.f90 | 5 +--
.../enumeration-type-mod-readback.F90 | 10 ++---
flang/test/Semantics/enumeration-type-mod.f90 | 2 +-
.../Semantics/enumeration-type-relational.f90 | 5 +--
28 files changed, 69 insertions(+), 114 deletions(-)
diff --git a/clang/include/clang/Options/FlangOptions.td b/clang/include/clang/Options/FlangOptions.td
index 2844ee854a120d..afc5ce85945003 100644
--- a/clang/include/clang/Options/FlangOptions.td
+++ b/clang/include/clang/Options/FlangOptions.td
@@ -193,7 +193,6 @@ defm unsigned : OptInFC1FFlag<"unsigned", "Enables UNSIGNED type">;
defm out_of_bounds_subscripts : OptOutFC1FFlag<"out-of-bounds-subscripts",
"Accept a constant subscript that is out of bounds, with a warning (default)",
"Reject a constant subscript that is out of bounds with an error">;
-defm enumeration_type : OptInFC1FFlag<"enumeration-type", "Enables F2023 ENUMERATION TYPE (experimental; FIR lowering is incomplete)">;
defm openacc_default_none_scalars_strict : OptOutFC1FFlag<"openacc-default-none-scalars-strict",
"Require explicit data clauses for all variables (including scalars) under OpenACC DEFAULT(NONE)",
"Allow scalars without explicit data clauses under OpenACC DEFAULT(NONE) (default, pre-OpenACC-3.2 behavior)">;
diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp
index a13c69a5b2a50a..f2eb0173bedb1b 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -228,20 +228,12 @@ void Flang::addDebugOptions(const llvm::opt::ArgList &Args, const JobAction &JA,
const auto &TC = getToolChain();
const Driver &D = TC.getDriver();
Args.addAllArgs(CmdArgs,
- {options::OPT_module_dir,
- options::OPT_fdebug_module_writer,
- options::OPT_fintrinsic_modules_path,
- options::OPT_pedantic,
- options::OPT_std_EQ,
- options::OPT_W_Joined,
- options::OPT_fconvert_EQ,
- options::OPT_fpass_plugin_EQ,
- options::OPT_funderscoring,
- options::OPT_fno_underscoring,
- options::OPT_funsigned,
- options::OPT_fno_unsigned,
- options::OPT_fenumeration_type,
- options::OPT_fno_enumeration_type,
+ {options::OPT_module_dir, options::OPT_fdebug_module_writer,
+ options::OPT_fintrinsic_modules_path, options::OPT_pedantic,
+ options::OPT_std_EQ, options::OPT_W_Joined,
+ options::OPT_fconvert_EQ, options::OPT_fpass_plugin_EQ,
+ options::OPT_funderscoring, options::OPT_fno_underscoring,
+ options::OPT_funsigned, options::OPT_fno_unsigned,
options::OPT_fout_of_bounds_subscripts,
options::OPT_fno_out_of_bounds_subscripts,
options::OPT_fopenacc_default_none_scalars_strict,
diff --git a/flang/docs/FortranStandardsSupport.md b/flang/docs/FortranStandardsSupport.md
index dd8bda23cb495f..ed53afeab8762d 100644
--- a/flang/docs/FortranStandardsSupport.md
+++ b/flang/docs/FortranStandardsSupport.md
@@ -53,7 +53,7 @@ status of all important Fortran 2023 features. The table entries are based on th
| Using integer arrays to specify rank and bound of an array | N | |
| Using an integer constant to specify rank | Y | |
| Reduction specifier for do concurrent | P | |
-| Enumerations | N | |
+| Enumerations | P | New non-interoperable ENUMERATION TYPE supported, interoperable enum types not supported |
## Fortran 2018
All features except those listed in the following table are supported. Almost all of the unsupported features are related to
diff --git a/flang/docs/ReleaseNotes.md b/flang/docs/ReleaseNotes.md
index 609ca499da3965..447f19ebd3f5b4 100644
--- a/flang/docs/ReleaseNotes.md
+++ b/flang/docs/ReleaseNotes.md
@@ -168,6 +168,18 @@ page](https://llvm.org/releases/).
F2023 15.5.2.10 p1). Declare the target `SIMPLE` if it satisfies the
`SIMPLE` constraints, or give the pointer or dummy an explicit `PURE`
interface.
+- Added support for the Fortran 2023 non-interoperable `ENUMERATION TYPE`
+ (F2023 7.6.2). An enumeration type is a distinct type whose values are
+ ordered, named enumerators. Supported features:
+ - declaration with `ENUMERATION TYPE` / `ENUMERATOR`, including
+ `ENUMERATION TYPE, PUBLIC/PRIVATE` and use through modules (module files
+ record enumeration types);
+ - enumeration constructors and use as named constants;
+ - relational operators (`==`, `/=`, `<`, `<=`, `>`, `>=`) between values of
+ the same enumeration type, and `SELECT CASE` on enumeration values;
+ - the `INT` intrinsic applied to an enumeration value, and the `HUGE`,
+ `NEXT` and `PREVIOUS` intrinsics;
+ - formatted I/O using the `I`, `B`, `O` and `Z` edit descriptors.
## Build System Changes
diff --git a/flang/lib/Evaluate/intrinsics.cpp b/flang/lib/Evaluate/intrinsics.cpp
index 84a211251b6eaf..5839c0e672c0be 100644
--- a/flang/lib/Evaluate/intrinsics.cpp
+++ b/flang/lib/Evaluate/intrinsics.cpp
@@ -4159,15 +4159,7 @@ std::optional<SpecificCall> IntrinsicProcTable::Implementation::Probe(
}
}
- // NEXT/PREVIOUS are enumeration-type-only intrinsics. They are only
- // recognized as intrinsic names when the enumeration-type feature is
- // enabled, so that pre-F2023 programs may still use those names for
- // external procedures. This gating is symmetric with the one in
- // resolve-names.cpp and should be removed once the feature is fully
- // implemented.
- if ((call.name == "next" || call.name == "previous") &&
- context.languageFeatures().IsEnabled(
- common::LanguageFeature::EnumerationType)) {
+ if (call.name == "next" || call.name == "previous") {
const semantics::DerivedTypeSpec *derived{nullptr};
if (const ActualArgument *arg{FindFirstDummyArgument(arguments, "a")}) {
derived = GetEnumerationTypeSpec(arg->GetType());
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index d4c6b44e114772..51333fdd95e1fb 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -939,12 +939,6 @@ static bool parseFrontendArgs(FrontendOptions &opts, llvm::opt::ArgList &args,
args.hasFlag(clang::options::OPT_fout_of_bounds_subscripts,
clang::options::OPT_fno_out_of_bounds_subscripts, true));
- // -f{no-}enumeration-type (experimental; FIR lowering is incomplete)
- opts.features.Enable(Fortran::common::LanguageFeature::EnumerationType,
- args.hasFlag(clang::options::OPT_fenumeration_type,
- clang::options::OPT_fno_enumeration_type,
- false));
-
// -frelaxed-c-loc-checks
if (args.hasArg(clang::options::OPT_relaxed_c_loc)) {
opts.features.Enable(Fortran::common::LanguageFeature::RelaxedCLocChecks);
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 06bc617ca7506b..d5d5356288b5a0 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -172,18 +172,6 @@ class BaseVisitor {
}
bool IsIntrinsic(
const SourceName &name, std::optional<Symbol::Flag> flag) const {
- // TEMPORARY (enumeration-type feature gating): NEXT and PREVIOUS are only
- // recognized as intrinsic names when the enumeration-type feature is
- // enabled, so that pre-F2023 programs may still use those names for
- // implicit external procedures. This gating is removed once the
- // enumeration-type feature is fully implemented.
- if (!context_->languageFeatures().IsEnabled(
- common::LanguageFeature::EnumerationType)) {
- const std::string nameStr{name.ToString()};
- if (nameStr == "next" || nameStr == "previous") {
- return false;
- }
- }
if (!flag) {
return context_->intrinsics().IsIntrinsic(name.ToString());
} else if (flag == Symbol::Flag::Function) {
@@ -6580,16 +6568,6 @@ void DeclarationVisitor::Post(const parser::EnumDef &) {
// F2023 R766 EnumerationTypeDef — scope is pushed in Post(EnumerationTypeStmt)
// and popped in Post(EndEnumerationTypeStmt).
bool DeclarationVisitor::Pre(const parser::EnumerationTypeDef &x) {
- const auto &source{
- std::get<parser::Statement<parser::EnumerationTypeStmt>>(x.t).source};
- // ENUMERATION TYPE is an experimental feature: semantics are partially
- // implemented. FIR lowering is not implemented.
- if (!context().IsEnabled(common::LanguageFeature::EnumerationType)) {
- Say(source, "F2023 ENUMERATION TYPEs are not yet implemented"_err_en_US);
- return false;
- }
- Say(source,
- "ENUMERATION TYPE support is incomplete and should be enabled only for testing"_warn_en_US);
BeginAttrs();
return true;
}
diff --git a/flang/lib/Support/Fortran-features.cpp b/flang/lib/Support/Fortran-features.cpp
index 9e0069781a117a..d0ff69deffb26b 100644
--- a/flang/lib/Support/Fortran-features.cpp
+++ b/flang/lib/Support/Fortran-features.cpp
@@ -145,10 +145,6 @@ LanguageFeatureControl::LanguageFeatureControl() {
disable_.set(LanguageFeature::DefaultSave);
disable_.set(LanguageFeature::SaveMainProgram);
disable_.set(LanguageFeature::RelaxedCLocChecks);
- // F2023 ENUMERATION TYPE: experimental. Semantics are implemented, but
- // FIR lowering is not, so the feature is off by default and must be
- // explicitly enabled (for testing) with -fenumeration-type.
- disable_.set(LanguageFeature::EnumerationType);
// These features, if enabled, conflict with valid standard usage,
// so there are disabled here by default.
disable_.set(LanguageFeature::BackslashEscapes);
diff --git a/flang/test/Lower/HLFIR/enumeration-type-forall-stat-todo.f90 b/flang/test/Lower/HLFIR/enumeration-type-forall-stat-todo.f90
index 5bc1bb6276a702..568868b27081e0 100644
--- a/flang/test/Lower/HLFIR/enumeration-type-forall-stat-todo.f90
+++ b/flang/test/Lower/HLFIR/enumeration-type-forall-stat-todo.f90
@@ -1,5 +1,5 @@
! Test that NEXT/PREVIOUS with STAT= inside FORALL hits the TODO diagnostic.
-! RUN: %not_todo_cmd %flang_fc1 -fenumeration-type -emit-hlfir -o - %s 2>&1 | FileCheck %s
+! RUN: %not_todo_cmd %flang_fc1 -emit-hlfir -o - %s 2>&1 | FileCheck %s
! CHECK: not yet implemented: NEXT/PREVIOUS with STAT= inside FORALL
module enum_forall_mod
diff --git a/flang/test/Lower/enumeration-type-next-previous.f90 b/flang/test/Lower/enumeration-type-next-previous.f90
index 0c2d76466f812c..84aebbb9666eef 100644
--- a/flang/test/Lower/enumeration-type-next-previous.f90
+++ b/flang/test/Lower/enumeration-type-next-previous.f90
@@ -1,6 +1,6 @@
! Test lowering of the NEXT and PREVIOUS intrinsics for enumeration types.
-! RUN: %flang_fc1 -fenumeration-type -emit-hlfir %s -o - | FileCheck %s
-! RUN: %flang_fc1 -fenumeration-type -emit-fir %s -o /dev/null
+! RUN: %flang_fc1 -emit-hlfir %s -o - | FileCheck %s
+! RUN: %flang_fc1 -emit-fir %s -o /dev/null
module enum_np_mod
enumeration type :: color
diff --git a/flang/test/Lower/enumeration-type.f90 b/flang/test/Lower/enumeration-type.f90
index 9b6ddfd595c740..dea023cb85acfc 100644
--- a/flang/test/Lower/enumeration-type.f90
+++ b/flang/test/Lower/enumeration-type.f90
@@ -1,9 +1,9 @@
! Test lowering of enumeration types to HLFIR.
! An enumeration type lowers to a record type with a single i32 component,
! __ordinal, holding the 1-based ordinal of the enumerator.
-! RUN: %flang_fc1 -fenumeration-type -emit-hlfir %s -o - | FileCheck %s
-! RUN: %flang_fc1 -fenumeration-type -emit-fir %s -o /dev/null
-! RUN: %flang_fc1 -fenumeration-type -emit-fir -mmlir -strict-fir-volatile-verifier %s -o /dev/null
+! RUN: %flang_fc1 -emit-hlfir %s -o - | FileCheck %s
+! RUN: %flang_fc1 -emit-fir %s -o /dev/null
+! RUN: %flang_fc1 -emit-fir -mmlir -strict-fir-volatile-verifier %s -o /dev/null
module enum_mod
enumeration type :: color
diff --git a/flang/test/Semantics/enumeration-type-component-offset.f90 b/flang/test/Semantics/enumeration-type-component-offset.f90
index 8cec31cfe4d7af..90f98a69b59bec 100644
--- a/flang/test/Semantics/enumeration-type-component-offset.f90
+++ b/flang/test/Semantics/enumeration-type-component-offset.f90
@@ -1,4 +1,4 @@
-! RUN: %flang_fc1 -fdebug-dump-symbols -fenumeration-type %s 2>&1 | FileCheck %s
+! RUN: %flang_fc1 -fdebug-dump-symbols %s 2>&1 | FileCheck %s
! Regression test: a derived type with an enumeration-type component must be
! correctly sized once the enclosing type is instantiated (which happens as
! soon as a variable of it is declared).
diff --git a/flang/test/Semantics/enumeration-type-component-usage.f90 b/flang/test/Semantics/enumeration-type-component-usage.f90
index 55d2595f336001..afb28ab1308753 100644
--- a/flang/test/Semantics/enumeration-type-component-usage.f90
+++ b/flang/test/Semantics/enumeration-type-component-usage.f90
@@ -1,4 +1,4 @@
-! RUN: %flang_fc1 -fsyntax-only -fenumeration-type %s
+! RUN: %flang_fc1 -fsyntax-only %s
! An enumeration type used as a derived-type component: default component
! initialization, whole-structure assignment, component assignment, use of the
! component in a relational, and arrays of the containing type must all compile.
diff --git a/flang/test/Semantics/enumeration-type-declarations.f90 b/flang/test/Semantics/enumeration-type-declarations.f90
index 4f1e5dbc506873..23e0f14f63d6e4 100644
--- a/flang/test/Semantics/enumeration-type-declarations.f90
+++ b/flang/test/Semantics/enumeration-type-declarations.f90
@@ -1,11 +1,10 @@
-! RUN: %python %S/test_errors.py %s %flang_fc1 -fenumeration-type
+! RUN: %python %S/test_errors.py %s %flang_fc1
! Test declaration, constructor, and expression semantics for enumeration types
! C7114: access specifier only allowed in module
subroutine test_access_specifier_outside_module()
!ERROR: PRIVATE attribute may only appear in the specification part of a module
!ERROR: Access specifier on ENUMERATION TYPE may only appear in the specification part of a module
- !WARNING: ENUMERATION TYPE support is incomplete and should be enabled only for testing
enumeration type, private :: color
enumerator :: red, green, blue
end enumeration type
@@ -13,7 +12,6 @@ subroutine test_access_specifier_outside_module()
! Valid: basic declarations and usage
subroutine test_basic_declarations()
- !WARNING: ENUMERATION TYPE support is incomplete and should be enabled only for testing
enumeration type :: color
enumerator :: red, green, blue
end enumeration type
@@ -32,7 +30,6 @@ subroutine test_basic_declarations()
! Valid: constructor syntax — color(n) where n is a positive integer <= count
subroutine test_constructor_valid()
- !WARNING: ENUMERATION TYPE support is incomplete and should be enabled only for testing
enumeration type :: color
enumerator :: red, green, blue
end enumeration type
@@ -47,7 +44,6 @@ subroutine test_constructor_valid()
! Constructor errors
subroutine test_constructor_errors()
- !WARNING: ENUMERATION TYPE support is incomplete and should be enabled only for testing
enumeration type :: color
enumerator :: red, green, blue
end enumeration type
@@ -78,7 +74,6 @@ subroutine test_constructor_errors()
! Component reference on enumeration type is not allowed
subroutine test_component_reference()
- !WARNING: ENUMERATION TYPE support is incomplete and should be enabled only for testing
enumeration type :: color
enumerator :: red, green, blue
end enumeration type
@@ -93,7 +88,6 @@ subroutine test_component_reference()
! Module providing an enumeration type by USE association
module enum_constructor_mod
- !WARNING: ENUMERATION TYPE support is incomplete and should be enabled only for testing
enumeration type :: color
enumerator :: red, green, blue
end enumeration type
@@ -132,7 +126,6 @@ subroutine test_constructor_errors_use()
! A duplicate enumerator name within an enumeration type is diagnosed as a
! clean semantic error.
subroutine test_duplicate_enumerator()
- !WARNING: ENUMERATION TYPE support is incomplete and should be enabled only for testing
enumeration type :: color
!ERROR: 'red' is already declared in this scoping unit
enumerator :: red, green, red
@@ -143,7 +136,6 @@ subroutine test_duplicate_enumerator()
! numeric: assignment and arithmetic mixing an enumeration value with an
! integer (or two enumeration values) must be rejected.
subroutine test_assignment_and_arithmetic()
- !WARNING: ENUMERATION TYPE support is incomplete and should be enabled only for testing
enumeration type :: color
enumerator :: red, green, blue
end enumeration type
diff --git a/flang/test/Semantics/enumeration-type-explicit-value.f90 b/flang/test/Semantics/enumeration-type-explicit-value.f90
index 839e5fed024c05..a14a7378ddcb0c 100644
--- a/flang/test/Semantics/enumeration-type-explicit-value.f90
+++ b/flang/test/Semantics/enumeration-type-explicit-value.f90
@@ -1,4 +1,4 @@
-! RUN: not %flang_fc1 -fsyntax-only -fenumeration-type %s 2>&1 | FileCheck %s
+! RUN: not %flang_fc1 -fsyntax-only %s 2>&1 | FileCheck %s
! F2023 enumeration types do not permit explicit enumerator values (unlike the
! ENUM, BIND(C) construct). 'enumerator :: red = 1' must be rejected.
diff --git a/flang/test/Semantics/enumeration-type-forward-ref.f90 b/flang/test/Semantics/enumeration-type-forward-ref.f90
index cd0523459298e4..4047089633753a 100644
--- a/flang/test/Semantics/enumeration-type-forward-ref.f90
+++ b/flang/test/Semantics/enumeration-type-forward-ref.f90
@@ -1,4 +1,4 @@
-! RUN: %python %S/test_errors.py %s %flang_fc1 -fenumeration-type
+! RUN: %python %S/test_errors.py %s %flang_fc1
! Forward reference to an enumeration type.
!
! F2023 C7116: the enumeration-type-name in an enumeration-type-spec shall be
@@ -10,7 +10,6 @@ program p
!ERROR: Enumeration type 'color' must be defined before it is referenced
implicit type(color) (c) ! forward reference: 'color' defined below
- !WARNING: ENUMERATION TYPE support is incomplete and should be enabled only for testing
enumeration type :: color
enumerator :: red, green, blue
end enumeration type
diff --git a/flang/test/Semantics/enumeration-type-intrinsics-array-fold.f90 b/flang/test/Semantics/enumeration-type-intrinsics-array-fold.f90
index d7af7199aa4ba9..28b26b66604790 100644
--- a/flang/test/Semantics/enumeration-type-intrinsics-array-fold.f90
+++ b/flang/test/Semantics/enumeration-type-intrinsics-array-fold.f90
@@ -1,4 +1,4 @@
-! RUN: %flang_fc1 -fdebug-dump-symbols -fenumeration-type %s 2>&1 | FileCheck %s
+! RUN: %flang_fc1 -fdebug-dump-symbols %s 2>&1 | FileCheck %s
! Regression test: the enumeration-type intrinsics INT/NEXT/PREVIOUS are
! elemental, so a constant array argument must fold elementwise in a constant
! context. Previously the enum fold path extracted only a scalar ordinal, so an
diff --git a/flang/test/Semantics/enumeration-type-intrinsics-gating.f90 b/flang/test/Semantics/enumeration-type-intrinsics-gating.f90
index 3ccab11d02ef45..5deea2c234730b 100644
--- a/flang/test/Semantics/enumeration-type-intrinsics-gating.f90
+++ b/flang/test/Semantics/enumeration-type-intrinsics-gating.f90
@@ -1,26 +1,35 @@
! RUN: %python %S/test_errors.py %s %flang_fc1
-! Without -fenumeration-type, NEXT and PREVIOUS are not reserved intrinsic
-! names, so a pre-F2023 program may use them as implicit external procedures.
-! This exercises the enumeration-type feature gating in resolve-names.cpp and
-! verifies the reference no longer triggers an internal compiler error.
-! NOTE: This gating is TEMPORARY and is removed once the enumeration-type
-! feature is fully implemented.
+! NEXT and PREVIOUS are F2023 intrinsic functions. A pre-F2023 program that
+! uses either name for its own procedure must declare it EXTERNAL.
program p
integer :: i
real :: r
+ !ERROR: Argument of NEXT() must be of enumeration type
i = next(5)
+ !ERROR: Argument of PREVIOUS() must be of enumeration type
r = previous(3)
end program
-subroutine test_intrinsic_next_declaration()
- ! Explicitly declaring NEXT intrinsic here (with the enumeration-type
- ! feature disabled) must produce only the single expected diagnostic below.
- ! Before the DeclareIntrinsic fix, the name was still incorrectly flagged
- ! as an intrinsic function under the hood, risking a second, bogus
- ! diagnostic when it was later referenced as a call below.
- !ERROR: 'next' is not a known intrinsic procedure
- intrinsic :: next
+subroutine test_external()
+ external :: next, previous
+ integer :: next
+ real :: previous
integer :: i
+ real :: r
+ i = next(5)
+ r = previous(3)
+end subroutine
+
+subroutine test_intrinsic_declaration()
+ intrinsic :: next, previous
+ integer :: i
+ !ERROR: Argument of NEXT() must be of enumeration type
i = next(5)
end subroutine
+
+! The intrinsics are functions, so a CALL still refers to an external subroutine.
+subroutine test_call()
+ call next(1)
+ call previous(1)
+end subroutine
diff --git a/flang/test/Semantics/enumeration-type-intrinsics-keyword.f90 b/flang/test/Semantics/enumeration-type-intrinsics-keyword.f90
index 85e70baf9ca0ee..e929b7f74522c2 100644
--- a/flang/test/Semantics/enumeration-type-intrinsics-keyword.f90
+++ b/flang/test/Semantics/enumeration-type-intrinsics-keyword.f90
@@ -1,4 +1,4 @@
-! RUN: %flang_fc1 -fsyntax-only -fenumeration-type %s
+! RUN: %flang_fc1 -fsyntax-only %s
! Verify keyword-order argument binding for enumeration-type intrinsics.
! INT(KIND=..., A=...) must recognize the enumeration argument even when it is
! not the first positional actual. This is a regression test: previously the
diff --git a/flang/test/Semantics/enumeration-type-intrinsics-nonenum.f90 b/flang/test/Semantics/enumeration-type-intrinsics-nonenum.f90
index 37a04c6f0fffb6..087d0d4db5715e 100644
--- a/flang/test/Semantics/enumeration-type-intrinsics-nonenum.f90
+++ b/flang/test/Semantics/enumeration-type-intrinsics-nonenum.f90
@@ -1,4 +1,4 @@
-! RUN: not %flang_fc1 -fsyntax-only -fenumeration-type %s 2>&1 | FileCheck %s
+! RUN: not %flang_fc1 -fsyntax-only %s 2>&1 | FileCheck %s
! With the enumeration-type feature enabled, NEXT and PREVIOUS require an
! argument of enumeration type. A non-enumeration argument must produce a
! proper diagnostic rather than an internal compiler error.
diff --git a/flang/test/Semantics/enumeration-type-intrinsics-valid.f90 b/flang/test/Semantics/enumeration-type-intrinsics-valid.f90
index 04da086c11bc41..e8f9e18a46628e 100644
--- a/flang/test/Semantics/enumeration-type-intrinsics-valid.f90
+++ b/flang/test/Semantics/enumeration-type-intrinsics-valid.f90
@@ -1,4 +1,4 @@
-! RUN: %flang_fc1 -fsyntax-only -fenumeration-type -pedantic %s
+! RUN: %flang_fc1 -fsyntax-only -pedantic %s
! NEXT/PREVIOUS calls that must compile cleanly (F2023 16.9.151, 16.9.164).
module enum_intrinsics_valid_mod
diff --git a/flang/test/Semantics/enumeration-type-intrinsics.f90 b/flang/test/Semantics/enumeration-type-intrinsics.f90
index 43f1a5329d2a0c..d68cb090032adc 100644
--- a/flang/test/Semantics/enumeration-type-intrinsics.f90
+++ b/flang/test/Semantics/enumeration-type-intrinsics.f90
@@ -1,4 +1,4 @@
-! RUN: not %flang_fc1 -fsyntax-only -fenumeration-type -pedantic %s 2>&1 | FileCheck %s
+! RUN: not %flang_fc1 -fsyntax-only -pedantic %s 2>&1 | FileCheck %s
! Test intrinsics HUGE, NEXT, PREVIOUS, INT for enumeration types (F2023 7.6.2).
module enum_intrinsics_mod
diff --git a/flang/test/Semantics/enumeration-type-io-pdt-order.f90 b/flang/test/Semantics/enumeration-type-io-pdt-order.f90
index 36bbf6802d335f..159a820406e9d7 100644
--- a/flang/test/Semantics/enumeration-type-io-pdt-order.f90
+++ b/flang/test/Semantics/enumeration-type-io-pdt-order.f90
@@ -1,11 +1,10 @@
-! RUN: %python %S/test_errors.py %s %flang_fc1 -fenumeration-type
+! RUN: %python %S/test_errors.py %s %flang_fc1
!
! This test verifies that the transversal order for enumeration type components
! does not impact the correct recognition/reporting of unformatted output
! errors.
module enum_pdt_order_mod
- !WARNING: ENUMERATION TYPE support is incomplete and should be enabled only for testing
enumeration type :: color
enumerator :: red, green, blue
end enumeration type
diff --git a/flang/test/Semantics/enumeration-type-io.f90 b/flang/test/Semantics/enumeration-type-io.f90
index 6196e5e8e814ec..b2bd53787de590 100644
--- a/flang/test/Semantics/enumeration-type-io.f90
+++ b/flang/test/Semantics/enumeration-type-io.f90
@@ -1,8 +1,7 @@
-! RUN: %python %S/test_errors.py %s %flang_fc1 -fenumeration-type
+! RUN: %python %S/test_errors.py %s %flang_fc1
! Test I/O constraints for enumeration types (F2023 7.6.2)
module enum_io_mod
- !WARNING: ENUMERATION TYPE support is incomplete and should be enabled only for testing
enumeration type :: color
enumerator :: red, green, blue
end enumeration type
diff --git a/flang/test/Semantics/enumeration-type-misc.f90 b/flang/test/Semantics/enumeration-type-misc.f90
index 3c99682e8a690c..c43f80eaa24bca 100644
--- a/flang/test/Semantics/enumeration-type-misc.f90
+++ b/flang/test/Semantics/enumeration-type-misc.f90
@@ -1,19 +1,16 @@
-! RUN: %python %S/test_errors.py %s %flang_fc1 -fenumeration-type
+! RUN: %python %S/test_errors.py %s %flang_fc1
! Miscellaneous enumeration-type use cases: a single-enumerator type, MERGE over
! enumeration values, and enumeration-type argument association.
module enum_misc_mod
- !WARNING: ENUMERATION TYPE support is incomplete and should be enabled only for testing
enumeration type :: color
enumerator :: red, green, blue
end enumeration type
- !WARNING: ENUMERATION TYPE support is incomplete and should be enabled only for testing
enumeration type :: direction
enumerator :: north, south
end enumeration type
- !WARNING: ENUMERATION TYPE support is incomplete and should be enabled only for testing
enumeration type :: single
enumerator :: only
end enumeration type
diff --git a/flang/test/Semantics/enumeration-type-mod-readback.F90 b/flang/test/Semantics/enumeration-type-mod-readback.F90
index 92cd1cf6935ec5..3823931ff4a075 100644
--- a/flang/test/Semantics/enumeration-type-mod-readback.F90
+++ b/flang/test/Semantics/enumeration-type-mod-readback.F90
@@ -1,9 +1,9 @@
!RUN: rm -rf %t && mkdir -p %t
-!RUN: %flang_fc1 -fenumeration-type -fsyntax-only -DSTEP=1 -J%t %s
-!RUN: %flang_fc1 -fenumeration-type -fsyntax-only -DSTEP=2 -J%t %s
-!RUN: not %flang_fc1 -fenumeration-type -fsyntax-only -DSTEP=3 -J%t %s 2>&1 | FileCheck --check-prefix=CHECK-PRIVTYPE %s
-!RUN: not %flang_fc1 -fenumeration-type -fsyntax-only -DSTEP=4 -J%t %s 2>&1 | FileCheck --check-prefix=CHECK-LEAK %s
-!RUN: %flang_fc1 -fenumeration-type -fsyntax-only -DSTEP=5 -J%t %s
+!RUN: %flang_fc1 -fsyntax-only -DSTEP=1 -J%t %s
+!RUN: %flang_fc1 -fsyntax-only -DSTEP=2 -J%t %s
+!RUN: not %flang_fc1 -fsyntax-only -DSTEP=3 -J%t %s 2>&1 | FileCheck --check-prefix=CHECK-PRIVTYPE %s
+!RUN: not %flang_fc1 -fsyntax-only -DSTEP=4 -J%t %s 2>&1 | FileCheck --check-prefix=CHECK-LEAK %s
+!RUN: %flang_fc1 -fsyntax-only -DSTEP=5 -J%t %s
! Enumerator accessibility must survive being written to a module file and read
! back: each using unit below is compiled in a SEPARATE invocation that reloads
diff --git a/flang/test/Semantics/enumeration-type-mod.f90 b/flang/test/Semantics/enumeration-type-mod.f90
index 7773a185e888db..ae8d6d30be259b 100644
--- a/flang/test/Semantics/enumeration-type-mod.f90
+++ b/flang/test/Semantics/enumeration-type-mod.f90
@@ -1,4 +1,4 @@
-! RUN: %python %S/test_modfile.py %s %flang_fc1 -fenumeration-type
+! RUN: %python %S/test_modfile.py %s %flang_fc1
! Check correct modfile generation for enumeration types.
! Basic enumeration type
diff --git a/flang/test/Semantics/enumeration-type-relational.f90 b/flang/test/Semantics/enumeration-type-relational.f90
index abaa237bcedd3b..fe76aaf98f5362 100644
--- a/flang/test/Semantics/enumeration-type-relational.f90
+++ b/flang/test/Semantics/enumeration-type-relational.f90
@@ -1,18 +1,15 @@
-! RUN: %python %S/test_errors.py %s %flang_fc1 -fenumeration-type
+! RUN: %python %S/test_errors.py %s %flang_fc1
! Test relational operators and SELECT CASE for enumeration types (F2023 7.6.2)
module enum_mod
- !WARNING: ENUMERATION TYPE support is incomplete and should be enabled only for testing
enumeration type :: color
enumerator :: red, green, blue
end enumeration type
- !WARNING: ENUMERATION TYPE support is incomplete and should be enabled only for testing
enumeration type :: direction
enumerator :: north, south, east, west
end enumeration type
- !WARNING: ENUMERATION TYPE support is incomplete and should be enabled only for testing
enumeration type :: w_value
enumerator :: w1, w2, w3, w4, w5
end enumeration type
>From 51481e0dfc7f3e088632b560335873c0382295b2 Mon Sep 17 00:00:00 2001
From: Kevin Wyatt <kwyatt at hpe.com>
Date: Tue, 13 Oct 2026 15:02:35 -0500
Subject: [PATCH 2/3] Added 'G' extension and additional type check test.
---
flang/docs/Extensions.md | 5 ++++
flang/test/Lower/enumeration-type.f90 | 39 +++++++++++++++++++++++++++
2 files changed, 44 insertions(+)
diff --git a/flang/docs/Extensions.md b/flang/docs/Extensions.md
index 958bf109c4632c..6edc40bf996771 100644
--- a/flang/docs/Extensions.md
+++ b/flang/docs/Extensions.md
@@ -659,6 +659,11 @@ The following extensions are not classified as `SIMPLE`: `CHDIR`, `DSECNDS`, `ET
Use `-Wrelaxed-c-loc-checks` (alongside `-frelaxed-c-loc-checks`) to
enable a diagnostic warning for affected call sites.
[-frelaxed-c-loc-checks]
+* In formatted I/O, an item of enumeration type may correspond to a `G`
+ edit descriptor, which is processed like an `I` edit descriptor (the
+ value written or read is the ordinal position). F2023 12.6.3 permits
+ only the `I`, `B`, `O`, and `Z` edit descriptors for enumeration type
+ items. No diagnostic is issued.
### Extensions and legacy features deliberately not supported
diff --git a/flang/test/Lower/enumeration-type.f90 b/flang/test/Lower/enumeration-type.f90
index dea023cb85acfc..299320d106604c 100644
--- a/flang/test/Lower/enumeration-type.f90
+++ b/flang/test/Lower/enumeration-type.f90
@@ -528,6 +528,45 @@ subroutine test_allocate_color()
allocate(color :: x)
end subroutine
+! SAME_TYPE_AS and EXTENDS_TYPE_OF are processor dependent when neither dynamic
+! type is extensible. An enumeration value passed to CLASS(*) carries its own
+! type descriptor, so the runtime sees (green, 7) as different types (F) and
+! (green, blue) as the same type (T).
+
+! CHECK-LABEL: func.func @_QPtest_same_type_as(
+subroutine test_same_type_as(a, b, same, extends)
+ class(*), intent(in) :: a, b
+ logical, intent(out) :: same, extends
+ ! CHECK: fir.call @_FortranASameTypeAs(
+ same = same_type_as(a, b)
+ ! CHECK: fir.call @_FortranAExtendsTypeOf(
+ extends = extends_type_of(a, b)
+end subroutine
+
+! CHECK-LABEL: func.func @_QPtest_same_type_as_args()
+subroutine test_same_type_as_args()
+ use enum_mod
+ interface
+ subroutine test_same_type_as(a, b, same, extends)
+ class(*), intent(in) :: a, b
+ logical, intent(out) :: same, extends
+ end subroutine
+ end interface
+ logical :: same, extends
+ ! CHECK: %[[G1:.*]] = fir.embox %{{.*}} : (!fir.ref<!fir.type<_QMenum_modTcolor{__ordinal:i32}>>) -> !fir.box<!fir.type<_QMenum_modTcolor{__ordinal:i32}>>
+ ! CHECK: %[[G1C:.*]] = fir.convert %[[G1]] : (!fir.box<!fir.type<_QMenum_modTcolor{__ordinal:i32}>>) -> !fir.class<none>
+ ! CHECK: %[[I:.*]] = fir.embox %{{.*}} : (!fir.ref<i32>) -> !fir.box<i32>
+ ! CHECK: %[[IC:.*]] = fir.rebox %[[I]] : (!fir.box<i32>) -> !fir.class<none>
+ ! CHECK: fir.call @_QPtest_same_type_as(%[[G1C]], %[[IC]], %{{.*}}, %{{.*}})
+ call test_same_type_as(green, 7, same, extends)
+ ! CHECK: %[[G2:.*]] = fir.embox %{{.*}} : (!fir.ref<!fir.type<_QMenum_modTcolor{__ordinal:i32}>>) -> !fir.box<!fir.type<_QMenum_modTcolor{__ordinal:i32}>>
+ ! CHECK: %[[G2C:.*]] = fir.convert %[[G2]] : (!fir.box<!fir.type<_QMenum_modTcolor{__ordinal:i32}>>) -> !fir.class<none>
+ ! CHECK: %[[B:.*]] = fir.embox %{{.*}} : (!fir.ref<!fir.type<_QMenum_modTcolor{__ordinal:i32}>>) -> !fir.box<!fir.type<_QMenum_modTcolor{__ordinal:i32}>>
+ ! CHECK: %[[BC:.*]] = fir.convert %[[B]] : (!fir.box<!fir.type<_QMenum_modTcolor{__ordinal:i32}>>) -> !fir.class<none>
+ ! CHECK: fir.call @_QPtest_same_type_as(%[[G2C]], %[[BC]], %{{.*}}, %{{.*}})
+ call test_same_type_as(green, blue, same, extends)
+end subroutine
+
! -----------------------------------------------------------------------------
! Verify the enumeration globals
! -----------------------------------------------------------------------------
>From 279d7f77ef235d41605d608ccadf00c31eb63f87 Mon Sep 17 00:00:00 2001
From: Kevin Wyatt <kwyatt at hpe.com>
Date: Mon, 19 Oct 2026 15:10:42 -0500
Subject: [PATCH 3/3] Address review feedback on enabling ENUMERATION TYPE
- Enumeration types are not derived types (F2023 7.6.2), so
IsExtensibleType() now returns false for them. As a result,
CLASS(enum), CLASSOF(enum) and CLASS IS (enum) are rejected.
- EXTENDS(enum) is rejected while the type is being resolved, so no
parent component is created and later uses of the extended type
don't produce misleading errors.
- TYPE IS (enum) is still allowed with an unlimited polymorphic selector
and is rejected otherwise.
- Pointer assignment from a CLASS(*) target to an enumeration pointer is
still rejected (C1017).
- A defined I/O procedure whose dtv is an enumeration type is now
reported as not having a derived type.
- A type parameter list on an enumeration type, as in type(state(1)), is
now an error instead of being silently dropped.
- Removed the unused LanguageFeature::EnumerationType, along with
-Wenumeration-type.
- Release notes now cover the removed -f[no-]enumeration-type options,
the NEXT/PREVIOUS name clash, and the known limitations.
- Extensions.md: moved the G editing entry to the default extensions and
added a note that CLASSOF requires an extensible type.
- FortranStandardsSupport.md now says that named interoperable enums
aren't supported.
- New tests: enumeration-type-extensible.f90, a type parameter section in
enumeration-type-declarations.f90, and module round-trip steps in
enumeration-type-mod-readback.F90.
- Fixed a stale comment in enumeration-type-intrinsics-nonenum.f90.
---
clang/lib/Driver/ToolChains/Flang.cpp | 18 ++--
flang/docs/Extensions.md | 20 ++--
flang/docs/FortranStandardsSupport.md | 2 +-
flang/docs/ReleaseNotes.md | 9 ++
.../include/flang/Support/Fortran-features.h | 2 +-
flang/lib/Evaluate/tools.cpp | 4 +-
flang/lib/Semantics/check-declarations.cpp | 4 +-
flang/lib/Semantics/check-select-type.cpp | 15 ++-
flang/lib/Semantics/pointer-assignment.cpp | 5 +-
flang/lib/Semantics/resolve-names.cpp | 34 ++++---
.../enumeration-type-declarations.f90 | 31 ++++++
.../Semantics/enumeration-type-extensible.f90 | 94 +++++++++++++++++++
.../enumeration-type-intrinsics-nonenum.f90 | 6 +-
.../enumeration-type-mod-readback.F90 | 47 ++++++++++
14 files changed, 257 insertions(+), 34 deletions(-)
create mode 100644 flang/test/Semantics/enumeration-type-extensible.f90
diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp
index f2eb0173bedb1b..ba51adc06a5637 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -228,12 +228,18 @@ void Flang::addDebugOptions(const llvm::opt::ArgList &Args, const JobAction &JA,
const auto &TC = getToolChain();
const Driver &D = TC.getDriver();
Args.addAllArgs(CmdArgs,
- {options::OPT_module_dir, options::OPT_fdebug_module_writer,
- options::OPT_fintrinsic_modules_path, options::OPT_pedantic,
- options::OPT_std_EQ, options::OPT_W_Joined,
- options::OPT_fconvert_EQ, options::OPT_fpass_plugin_EQ,
- options::OPT_funderscoring, options::OPT_fno_underscoring,
- options::OPT_funsigned, options::OPT_fno_unsigned,
+ {options::OPT_module_dir,
+ options::OPT_fdebug_module_writer,
+ options::OPT_fintrinsic_modules_path,
+ options::OPT_pedantic,
+ options::OPT_std_EQ,
+ options::OPT_W_Joined,
+ options::OPT_fconvert_EQ,
+ options::OPT_fpass_plugin_EQ,
+ options::OPT_funderscoring,
+ options::OPT_fno_underscoring,
+ options::OPT_funsigned,
+ options::OPT_fno_unsigned,
options::OPT_fout_of_bounds_subscripts,
options::OPT_fno_out_of_bounds_subscripts,
options::OPT_fopenacc_default_none_scalars_strict,
diff --git a/flang/docs/Extensions.md b/flang/docs/Extensions.md
index 6edc40bf996771..f822220e4d4b8a 100644
--- a/flang/docs/Extensions.md
+++ b/flang/docs/Extensions.md
@@ -596,7 +596,12 @@ end program
* When the argument to intrinsic `ALLOCATED(p)` is actually a pointer
rather than an allocatable, it is interpreted as `ASSOCIATED(p)` with a
stern warning.
-
+* In formatted I/O, an item of enumeration type may correspond to a `G`
+ edit descriptor, which is processed like an `I` edit descriptor (the
+ value written or read is the ordinal position). F2023 12.6.3 permits
+ only the `I`, `B`, `O`, and `Z` edit descriptors for enumeration type
+ items. No diagnostic is issued.
+
### `SIMPLE` classification of extensions
The following extensions are `SIMPLE`: `IARGC`, `INT2`, `INT8`, `INT_PTR_KIND`, `ISNAN`,
@@ -659,11 +664,6 @@ The following extensions are not classified as `SIMPLE`: `CHDIR`, `DSECNDS`, `ET
Use `-Wrelaxed-c-loc-checks` (alongside `-frelaxed-c-loc-checks`) to
enable a diagnostic warning for affected call sites.
[-frelaxed-c-loc-checks]
-* In formatted I/O, an item of enumeration type may correspond to a `G`
- edit descriptor, which is processed like an `I` edit descriptor (the
- value written or read is the ordinal position). F2023 12.6.3 permits
- only the `I`, `B`, `O`, and `Z` edit descriptors for enumeration type
- items. No diagnostic is issued.
### Extensions and legacy features deliberately not supported
@@ -760,6 +760,14 @@ The following extensions are not classified as `SIMPLE`: `CHDIR`, `DSECNDS`, `ET
error. This can be a temporary flang limitation while enumeration-type
support is incomplete, not a standard requirement.
+* F2023 C712 prohibits only an assumed-type or intrinsic-type data-ref
+ in a `CLASSOF` type specifier, so it does not exclude a data-ref of a
+ non-extensible type, such as a `SEQUENCE` or `BIND(C)` derived type or
+ an enumeration type. A polymorphic entity of such a type could never
+ have a dynamic type other than its declared type, and C705 prohibits
+ the equivalent `CLASS` type specifier. Flang requires the data-ref of
+ `CLASSOF` to be of an extensible type and reports an error otherwise.
+
## Standard features that might as well not be
* Flang supports designators with constant expressions, properly
diff --git a/flang/docs/FortranStandardsSupport.md b/flang/docs/FortranStandardsSupport.md
index ed53afeab8762d..762d62da06427e 100644
--- a/flang/docs/FortranStandardsSupport.md
+++ b/flang/docs/FortranStandardsSupport.md
@@ -53,7 +53,7 @@ status of all important Fortran 2023 features. The table entries are based on th
| Using integer arrays to specify rank and bound of an array | N | |
| Using an integer constant to specify rank | Y | |
| Reduction specifier for do concurrent | P | |
-| Enumerations | P | New non-interoperable ENUMERATION TYPE supported, interoperable enum types not supported |
+| Enumerations | P | New non-interoperable ENUMERATION TYPE supported, named interoperable enum types not yet supported |
## Fortran 2018
All features except those listed in the following table are supported. Almost all of the unsupported features are related to
diff --git a/flang/docs/ReleaseNotes.md b/flang/docs/ReleaseNotes.md
index 447f19ebd3f5b4..05eb399225818e 100644
--- a/flang/docs/ReleaseNotes.md
+++ b/flang/docs/ReleaseNotes.md
@@ -180,6 +180,15 @@ page](https://llvm.org/releases/).
- the `INT` intrinsic applied to an enumeration value, and the `HUGE`,
`NEXT` and `PREVIOUS` intrinsics;
- formatted I/O using the `I`, `B`, `O` and `Z` edit descriptors.
+ Known Limitations:
+ - unformatted I/O of enumeration types is rejected (issue 231638);
+ - formatted input is not range-checked (231636);
+ - NEXT/PREVIOUS with STAT= inside FORALL is not yet implemented (229873);
+ - WHERE with a derived-type vector-subscript gather fails to verify (230617).
+ Side effects:
+ - `-fenumeration-type` and `-fno-enumeration-type` have been removed;
+ - NEXT and PREVIOUS are new intrinsic functions, name re-use requires EXTERNAL
+ declaration or an explicit interface.
## Build System Changes
diff --git a/flang/include/flang/Support/Fortran-features.h b/flang/include/flang/Support/Fortran-features.h
index 587221ba5dd6d6..5fe92201c7b5ec 100644
--- a/flang/include/flang/Support/Fortran-features.h
+++ b/flang/include/flang/Support/Fortran-features.h
@@ -61,7 +61,7 @@ ENUM_CLASS(LanguageFeature, BackslashEscapes, OldDebugLines,
MultipleProgramUnitsOnSameLine, AllocatedForAssociated,
OpenMPThreadprivateEquivalence, RelaxedCLocChecks, CudaPinned,
CUDAImplicitDataAttrSpelling, OpenAccDefaultNoneScalarsStrict,
- OpenACCMultipleNamesInRoutine, EnumerationType, CUDAInit,
+ OpenACCMultipleNamesInRoutine, CUDAInit,
PreferIntrinsicModuleUseAssociation, MultipleCommonBlockInit,
OutOfBoundsSubscripts, ImplicitModulePrefix)
diff --git a/flang/lib/Evaluate/tools.cpp b/flang/lib/Evaluate/tools.cpp
index a27ce955ebd68b..b06bca4930c103 100644
--- a/flang/lib/Evaluate/tools.cpp
+++ b/flang/lib/Evaluate/tools.cpp
@@ -2982,7 +2982,9 @@ bool IsLenTypeParameter(const Symbol &symbol) {
bool IsExtensibleType(const DerivedTypeSpec *derived) {
return !IsSequenceOrBindCType(derived) && !IsIsoCType(derived) &&
- !(derived && derived->IsVectorType());
+ !(derived && derived->IsVectorType()) &&
+ !(derived &&
+ derived->typeSymbol().get<DerivedTypeDetails>().isEnumerationType());
}
bool IsSequenceOrBindCType(const DerivedTypeSpec *derived) {
diff --git a/flang/lib/Semantics/check-declarations.cpp b/flang/lib/Semantics/check-declarations.cpp
index 2abefd381850ad..2a6cbda3c7c747 100644
--- a/flang/lib/Semantics/check-declarations.cpp
+++ b/flang/lib/Semantics/check-declarations.cpp
@@ -3710,7 +3710,9 @@ void CheckHelper::CheckAlreadySeenDefinedIo(const DerivedTypeSpec &derivedType,
void CheckHelper::CheckDioDummyIsDerived(const Symbol &proc, const Symbol &arg,
common::DefinedIo ioKind, const Symbol &generic) {
if (const DeclTypeSpec *type{arg.GetType()}) {
- if (const DerivedTypeSpec *derivedType{type->AsDerived()}) {
+ // An enumeration type is not a derived type (F2023 R1221).
+ if (const DerivedTypeSpec *derivedType{type->AsDerived()};
+ derivedType && !IsEnumerationType(derivedType->typeSymbol())) {
if (derivedType->IsVectorType()) {
messages_.Say(arg.name(),
"Dummy argument '%s' of a defined input/output procedure must not be a vector type"_err_en_US,
diff --git a/flang/lib/Semantics/check-select-type.cpp b/flang/lib/Semantics/check-select-type.cpp
index 406d48d7961186..2b90f9d77291ab 100644
--- a/flang/lib/Semantics/check-select-type.cpp
+++ b/flang/lib/Semantics/check-select-type.cpp
@@ -98,8 +98,16 @@ class TypeCaseValues {
"LEN type parameter as assumed"_err_en_US);
typeSpecRetVal = false;
}
+ } else if (const DerivedTypeSpec *derived{spec->AsDerived()};
+ IsEnumerationType(derived->typeSymbol())) {
+ // An enumeration type extends nothing (F2023 C1167).
+ typeSpecRetVal = true;
+ if (!selectorType_.IsUnlimitedPolymorphic()) {
+ context_.Say(stmt.source,
+ "If selector is not unlimited polymorphic, an enumeration type specification must not be specified in the type guard statement"_err_en_US);
+ typeSpecRetVal = false;
+ }
} else {
- const DerivedTypeSpec *derived{spec->AsDerived()};
typeSpecRetVal = PassesDerivedTypeChecks(
*derived, parser::FindSourceLocation(typeSpec));
}
@@ -108,6 +116,11 @@ class TypeCaseValues {
[&](const parser::DerivedTypeSpec &x) {
CHECK(x.derivedTypeSpec);
const semantics::DerivedTypeSpec *derived{x.derivedTypeSpec};
+ if (IsEnumerationType(derived->typeSymbol())) { // R1156
+ context_.Say(parser::FindSourceLocation(x),
+ "An enumeration type may not appear in a CLASS IS type guard statement"_err_en_US);
+ return false;
+ }
return PassesDerivedTypeChecks(
*derived, parser::FindSourceLocation(x));
},
diff --git a/flang/lib/Semantics/pointer-assignment.cpp b/flang/lib/Semantics/pointer-assignment.cpp
index 7425f831b51b48..55c3d7fd320ae7 100644
--- a/flang/lib/Semantics/pointer-assignment.cpp
+++ b/flang/lib/Semantics/pointer-assignment.cpp
@@ -466,7 +466,10 @@ bool PointerAssignmentChecker::LhsOkForUnlimitedPoly() const {
} else if (type.IsUnlimitedPolymorphic()) {
return true;
} else {
- return !IsExtensibleType(&type.GetDerivedTypeSpec());
+ // F2023 C1017 does not permit enumeration types here.
+ const DerivedTypeSpec &derived{type.GetDerivedTypeSpec()};
+ return !IsExtensibleType(&derived) &&
+ !IsEnumerationType(derived.typeSymbol());
}
}
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index d5d5356288b5a0..1f4c37fed13a46 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -7260,9 +7260,23 @@ void DeclarationVisitor::Post(const parser::DerivedTypeSpec &x) {
if (!spec) {
return;
}
+ const auto &typeParamSpecs{std::get<std::list<parser::TypeParamSpec>>(x.t)};
+ // Enumeration types are a special case of derived types and are handled
+ // differently.
+ if (spec->typeSymbol().get<DerivedTypeDetails>().isEnumerationType()) {
+ if (!typeParamSpecs.empty()) { // F2023 7.6.2
+ Say(typeName.source,
+ "Enumeration type '%s' has no type parameters"_err_en_US);
+ }
+ spec->set_category(DerivedTypeSpec::Category::EnumerationType);
+ DeclTypeSpec &type{currScope().MakeDerivedType(
+ GetDeclTypeSpecCategory(), std::move(*spec))};
+ SetDeclTypeSpec(type);
+ x.derivedTypeSpec = &GetDeclTypeSpec()->derivedTypeSpec();
+ return;
+ }
bool seenAnyName{false};
- for (const auto &typeParamSpec :
- std::get<std::list<parser::TypeParamSpec>>(x.t)) {
+ for (const auto &typeParamSpec : typeParamSpecs) {
const auto &optKeyword{
std::get<std::optional<parser::Keyword>>(typeParamSpec.t)};
std::optional<SourceName> name;
@@ -7292,17 +7306,6 @@ void DeclarationVisitor::Post(const parser::DerivedTypeSpec &x) {
// in the current scope, this spec will be moved into that collection.
const auto &dtDetails{spec->typeSymbol().get<DerivedTypeDetails>()};
auto category{GetDeclTypeSpecCategory()};
-
- // Enumeration types are a special case of derived types and are handled
- // differently.
- if (dtDetails.isEnumerationType()) {
- spec->set_category(DerivedTypeSpec::Category::EnumerationType);
- DeclTypeSpec &type{currScope().MakeDerivedType(category, std::move(*spec))};
- SetDeclTypeSpec(type);
- x.derivedTypeSpec = &GetDeclTypeSpec()->derivedTypeSpec();
- return;
- }
-
if (dtDetails.isForwardReferenced()) {
DeclTypeSpec &type{currScope().MakeDerivedType(category, std::move(*spec))};
SetDeclTypeSpec(type);
@@ -8765,6 +8768,11 @@ std::optional<DerivedTypeSpec> DeclarationVisitor::ResolveExtendsType(
Say(extendsName->source,
"Derived type '%s' cannot extend itself"_err_en_US);
} else if (auto dtSpec{ResolveDerivedType(*extendsName)}) {
+ // Reject now so that no parent component of enumeration type is made.
+ if (IsEnumerationType(dtSpec->typeSymbol())) {
+ Say(extendsName->source, "The parent type is not extensible"_err_en_US);
+ return std::nullopt;
+ }
if (!dtSpec->IsForwardReferenced()) {
return dtSpec;
}
diff --git a/flang/test/Semantics/enumeration-type-declarations.f90 b/flang/test/Semantics/enumeration-type-declarations.f90
index 23e0f14f63d6e4..9fb5c0d365d04c 100644
--- a/flang/test/Semantics/enumeration-type-declarations.f90
+++ b/flang/test/Semantics/enumeration-type-declarations.f90
@@ -156,3 +156,34 @@ subroutine test_assignment_and_arithmetic()
!ERROR: Operands of + must be numeric; have TYPE(color) and TYPE(color)
c = red + green
end subroutine
+
+! An enumeration type has no type parameters (F2023 7.6.2), so no type-spec may
+! give it a type-param-spec-list. An enumeration constructor is still valid.
+subroutine test_type_parameters(u)
+ enumeration type :: state
+ enumerator :: off, on
+ end enumeration type
+ type :: holder
+ !ERROR: Enumeration type 'state' has no type parameters
+ type(state(1)) :: comp
+ end type
+ class(*), intent(in) :: u
+ !ERROR: Enumeration type 'state' has no type parameters
+ type(state(1)) :: a
+ !ERROR: Enumeration type 'state' has no type parameters
+ type(state(k=2)) :: b
+ !ERROR: Enumeration type 'state' has no type parameters
+ type(state(:)), allocatable :: c
+ class(*), allocatable :: d
+
+ a = state(1)
+ b = off
+ !ERROR: Enumeration type 'state' has no type parameters
+ allocate(state(1) :: d)
+ deallocate(d)
+ allocate(d, source=state(2))
+ select type (u)
+ !ERROR: Enumeration type 'state' has no type parameters
+ type is (state(1))
+ end select
+end subroutine
diff --git a/flang/test/Semantics/enumeration-type-extensible.f90 b/flang/test/Semantics/enumeration-type-extensible.f90
new file mode 100644
index 00000000000000..bbcae08188f14c
--- /dev/null
+++ b/flang/test/Semantics/enumeration-type-extensible.f90
@@ -0,0 +1,94 @@
+! RUN: %python %S/test_errors.py %s %flang_fc1
+! An enumeration type is not a derived type (F2023 7.6.2), so it is not an
+! extensible type (F2023 7.5.7.1).
+
+module enum_ext_mod
+ enumeration type :: color
+ enumerator :: red, green
+ end enumeration type
+
+ type :: base
+ end type
+
+ !ERROR: The parent type is not extensible
+ type, extends(color) :: child
+ integer :: n = 0
+ end type
+
+ ! The rejected EXTENDS must not leave a hidden parent component behind.
+ type, extends(child) :: grandchild
+ integer :: k
+ end type
+
+ !ERROR: Non-extensible derived type 'color' may not be used with CLASS keyword
+ class(color), allocatable :: x
+
+contains
+ subroutine use_child()
+ type(child) :: c
+ type(grandchild) :: g
+ c = child(n=1)
+ c%n = c%n + 1
+ g = grandchild(k=3)
+ end subroutine
+
+ subroutine classof_enum(e)
+ type(color), intent(in) :: e
+ !ERROR: CLASSOF requires a data-ref of extensible type
+ classof(e), allocatable :: f
+ end subroutine
+
+ subroutine type_is_ok(u)
+ class(*), intent(in) :: u
+ select type (u)
+ type is (color)
+ end select
+ end subroutine
+
+ subroutine class_is_enum(u)
+ class(*), intent(in) :: u
+ select type (u)
+ !ERROR: An enumeration type may not appear in a CLASS IS type guard statement
+ class is (color)
+ end select
+ end subroutine
+
+ subroutine type_is_not_unlimited(b)
+ class(base), intent(in) :: b
+ select type (b)
+ !ERROR: If selector is not unlimited polymorphic, an enumeration type specification must not be specified in the type guard statement
+ type is (color)
+ end select
+ end subroutine
+
+ subroutine pointer_to_unlimited(q)
+ class(*), pointer, intent(in) :: q
+ type(color), pointer :: p
+ !ERROR: Pointer type must be unlimited polymorphic or non-extensible derived type when target is unlimited polymorphic
+ p => q
+ end subroutine
+
+ subroutine same_type(a, b)
+ type(color), intent(in) :: a, b
+ !ERROR: Actual argument for 'a=' has type 'color', but was expected to be an extensible or unlimited polymorphic type
+ print *, same_type_as(a, b)
+ end subroutine
+end module
+
+module enum_ext_dio_mod
+ enumeration type :: color
+ enumerator :: red, green
+ end enumeration type
+ interface write(formatted)
+ subroutine wf(dtv, unit, iotype, vlist, iostat, iomsg)
+ import color
+ !ERROR: Dummy argument 'dtv' of a defined input/output procedure must have a derived type
+ type(color), intent(in) :: dtv
+ integer, intent(in) :: unit
+ character(*), intent(in) :: iotype
+ integer, intent(in) :: vlist(:)
+ integer, intent(out) :: iostat
+ character(*), intent(inout) :: iomsg
+ end subroutine
+ end interface
+end module
diff --git a/flang/test/Semantics/enumeration-type-intrinsics-nonenum.f90 b/flang/test/Semantics/enumeration-type-intrinsics-nonenum.f90
index 087d0d4db5715e..44bce74daa1baa 100644
--- a/flang/test/Semantics/enumeration-type-intrinsics-nonenum.f90
+++ b/flang/test/Semantics/enumeration-type-intrinsics-nonenum.f90
@@ -1,7 +1,7 @@
! RUN: not %flang_fc1 -fsyntax-only %s 2>&1 | FileCheck %s
-! With the enumeration-type feature enabled, NEXT and PREVIOUS require an
-! argument of enumeration type. A non-enumeration argument must produce a
-! proper diagnostic rather than an internal compiler error.
+! NEXT and PREVIOUS require an argument of enumeration type. A non-enumeration
+! argument must produce a proper diagnostic rather than an internal compiler
+! error.
subroutine test_next_nonenum()
integer :: i, j
diff --git a/flang/test/Semantics/enumeration-type-mod-readback.F90 b/flang/test/Semantics/enumeration-type-mod-readback.F90
index 3823931ff4a075..c9402b8d5c3b60 100644
--- a/flang/test/Semantics/enumeration-type-mod-readback.F90
+++ b/flang/test/Semantics/enumeration-type-mod-readback.F90
@@ -4,6 +4,9 @@
!RUN: not %flang_fc1 -fsyntax-only -DSTEP=3 -J%t %s 2>&1 | FileCheck --check-prefix=CHECK-PRIVTYPE %s
!RUN: not %flang_fc1 -fsyntax-only -DSTEP=4 -J%t %s 2>&1 | FileCheck --check-prefix=CHECK-LEAK %s
!RUN: %flang_fc1 -fsyntax-only -DSTEP=5 -J%t %s
+!RUN: %flang_fc1 -fsyntax-only -DSTEP=6 -J%t %s
+!RUN: %flang_fc1 -fsyntax-only -DSTEP=7 -J%t %s
+!RUN: %flang_fc1 -fsyntax-only -DSTEP=8 -J%t %s
! Enumerator accessibility must survive being written to a module file and read
! back: each using unit below is compiled in a SEPARATE invocation that reloads
@@ -80,3 +83,47 @@ subroutine use_renamed
use m7d, only: v
end subroutine
#endif
+
+#if STEP == 6
+! Producer for the declaration forms of an enumeration type that reach a
+! module file: TYPE() dummies, TYPEOF() of an enumeration entity, a component
+! with an enumerator default, and TYPE IS in SELECT TYPE.
+module m8
+ enumeration type :: state
+ enumerator :: off, on
+ end enumeration type
+ type :: holder
+ type(state) :: s = on
+ end type
+contains
+ subroutine show(x)
+ type(state), intent(in) :: x
+ end subroutine
+ subroutine show_typeof(x, y)
+ type(state), intent(in) :: x
+ typeof(x), intent(in) :: y
+ end subroutine
+ subroutine show_poly(u)
+ class(*), intent(in) :: u
+ select type (u)
+ type is (state)
+ end select
+ end subroutine
+end module
+#endif
+
+#if STEP == 7
+subroutine use_enumerator_only
+ use m8, only: on
+end subroutine
+#endif
+
+#if STEP == 8
+subroutine use_all
+ use m8
+ type(holder) :: h
+ call show(on)
+ call show_typeof(off, h%s)
+ call show_poly(on)
+end subroutine
+#endif
More information about the flang-commits
mailing list