[flang-commits] [flang] [flang] Enumeration Type: (PR 4/5) Lowering (PR #193571)

via flang-commits flang-commits at lists.llvm.org
Thu Oct 1 19:49:58 PDT 2026


================
@@ -2074,6 +2379,69 @@ class HlfirBuilder {
     mlir::Location loc = getLoc();
     fir::FirOpBuilder &builder = getBuilder();
     mlir::Type ty = translateSomeExprToFIRType(converter, toEvExpr(ctor));
+
+    // Enumeration types lower to i32 — extract the __ordinal value.
+    // Check via the type symbol's DerivedTypeDetails rather than
+    // DerivedTypeSpec::IsEnumerationType(), which may not be set on
+    // all DerivedTypeSpec instances.
+    if (const auto *dtDetails =
+            ctor.derivedTypeSpec()
+                .typeSymbol()
+                .detailsIf<Fortran::semantics::DerivedTypeDetails>()) {
+      if (dtDetails->isEnumerationType()) {
+        if (const auto *scope = ctor.derivedTypeSpec().GetScope()) {
+          auto it = scope->find(Fortran::parser::CharBlock{"__ordinal", 9});
+          if (it != scope->end()) {
+            if (auto val = ctor.Find(it->second.get())) {
+              if (auto ordinal = Fortran::evaluate::ToInt64(*val)) {
+                mlir::Value result =
+                    builder.createIntegerConstant(loc, ty, *ordinal);
+                return hlfir::EntityWithAttributes{result};
+              }
+              // Non-constant ordinal (e.g. color(i) with variable i): lower
+              // the __ordinal component expression to a runtime scalar value.
+              hlfir::Entity ordinalEntity = gen(*val);
+              mlir::Value ordinal =
+                  hlfir::loadTrivialScalar(loc, builder, ordinalEntity);
+              if (ordinal.getType() != ty)
+                ordinal = builder.createConvert(loc, ty, ordinal);
+              // F2023 7.6.2 para 5 requires the constructor value to be
+              // positive and <= the number of enumerators.  We choose to always
+              // emit a runtime range check with error termination. This block
+              // could be placed behind an -fcheck=enum style flag if the
+              // community prefers an opt-in implementation like gfortran's
+              // -fcheck=bounds.
+              int count = ctor.derivedTypeSpec()
+                              .typeSymbol()
+                              .GetUltimate()
+                              .get<Fortran::semantics::DerivedTypeDetails>()
+                              .enumeratorCount();
+              mlir::Value one = builder.createIntegerConstant(loc, ty, 1);
+              mlir::Value maxVal =
+                  builder.createIntegerConstant(loc, ty, count);
+              mlir::Value tooLow = mlir::arith::CmpIOp::create(
+                  builder, loc, mlir::arith::CmpIPredicate::slt, ordinal, one);
----------------
MattPD wrote:

The constructor now rejects `4294967297_8` as out of range.

https://github.com/llvm/llvm-project/pull/193571


More information about the flang-commits mailing list