[flang-commits] [flang] 3293272 - [flang][semantics] Reject DATA-style initializer on EXTERNAL/INTRINSIC (#222256)

via flang-commits flang-commits at lists.llvm.org
Thu Oct 8 16:00:01 PDT 2026


Author: Adarsh Mishra
Date: 2026-10-08T18:59:56-04:00
New Revision: 32932727b33e8b5c04093eef51481713fbeb6823

URL: https://github.com/llvm/llvm-project/commit/32932727b33e8b5c04093eef51481713fbeb6823
DIFF: https://github.com/llvm/llvm-project/commit/32932727b33e8b5c04093eef51481713fbeb6823.diff

LOG: [flang][semantics] Reject DATA-style initializer on EXTERNAL/INTRINSIC (#222256)

An `entity-decl` carrying a legacy `/initialization/` (an extension) was silently
accepted, and the initializer dropped, when the name had already been
declared `EXTERNAL` or `INTRINSIC`:

```fortran
subroutine s
  external foo
  integer foo /1/   ! accepted, no initialization emitted
end subroutine
```

`DataChecker::Leave(const parser::EntityDecl &)` passed the value list to
`AccumulateDataInitializations` without checking the symbol's class, so the
initialization never reached the emitted code and no diagnostic was produced.
Reversing the two statements already errors, so the behaviour was also
order-dependent. For an intrinsic name that is not an unrestricted specific
function (`sum`), the accumulated value instead tripped
`CHECK(designator.has_value())` in `data-to-inits.cpp` and crashed the
compiler.

A procedure name is not a data-stmt-object (F2023 C880, R842), so reject it here.
Procedure pointer initialization is an accepted extension (8.6.7), so
`IsProcedurePointer` symbols still take the existing path.

Fixes #222168

Assisted-by: Qoder (AI assistant)

Added: 
    flang/test/Semantics/data28.f90

Modified: 
    flang/lib/Semantics/check-data.cpp

Removed: 
    


################################################################################
diff  --git a/flang/lib/Semantics/check-data.cpp b/flang/lib/Semantics/check-data.cpp
index 921128ced5d61b..75b2e91f6290f5 100644
--- a/flang/lib/Semantics/check-data.cpp
+++ b/flang/lib/Semantics/check-data.cpp
@@ -266,7 +266,16 @@ void DataChecker::Leave(const parser::EntityDecl &decl) {
         std::get_if<std::list<common::Indirection<parser::DataStmtValue>>>(
             &init->u)};
     if (name && list && !exprAnalyzer_.context().HasError(*name)) {
-      AccumulateDataInitializations(inits_, exprAnalyzer_, *name, *list);
+      // A procedure name is not a data-stmt-object (F2023 C880, R842), but
+      // procedure pointer initialization is supported as an extension, so
+      // exclude procedure pointers here.
+      if (IsProcedure(*name) && !IsProcedurePointer(*name)) {
+        exprAnalyzer_.context().Say(std::get<parser::Name>(decl.t).source,
+            "Procedure '%s' may not have a DATA-style initializer"_err_en_US,
+            name->name());
+      } else {
+        AccumulateDataInitializations(inits_, exprAnalyzer_, *name, *list);
+      }
     }
   }
 }

diff  --git a/flang/test/Semantics/data28.f90 b/flang/test/Semantics/data28.f90
new file mode 100644
index 00000000000000..572f3dab123aae
--- /dev/null
+++ b/flang/test/Semantics/data28.f90
@@ -0,0 +1,36 @@
+! RUN: %python %S/test_errors.py %s %flang_fc1
+! A procedure (EXTERNAL/INTRINSIC) may not have a DATA-style initializer.
+! The initializer used to be silently accepted and dropped (#222168), or,
+! for an intrinsic that is not an unrestricted specific function, crashed
+! the compiler (CHECK(designator.has_value()) in data-to-inits.cpp).
+subroutine s1
+  external foo
+  !ERROR: Procedure 'foo' may not have a DATA-style initializer
+  integer foo /1/
+end subroutine
+subroutine s2
+  intrinsic sin
+  !ERROR: Procedure 'sin' may not have a DATA-style initializer
+  integer sin /1/
+end subroutine
+subroutine s3 ! used to crash: SUM is not an unrestricted specific intrinsic
+  intrinsic sum
+  !ERROR: Procedure 'sum' may not have a DATA-style initializer
+  integer sum /1/
+end subroutine
+subroutine s4(f) ! dummy procedure
+  external f
+  !ERROR: Procedure 'f' may not have a DATA-style initializer
+  integer f /1/
+end subroutine
+subroutine s5 ! no INTRINSIC/EXTERNAL: a plain local object named like an
+  integer sum /1/ ! intrinsic must stay accepted (guard keys on symbol class)
+  print *, sum
+end subroutine
+subroutine s6 ! procedure POINTER initialization must stay accepted (8.6.7)
+  interface
+    integer function tgt()
+    end function
+  end interface
+  procedure(tgt), pointer :: p => null()
+end subroutine


        


More information about the flang-commits mailing list