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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to