[flang-commits] [flang] [flang] Improve error for component definition after CONTAINS in derived type (PR #203379)

via flang-commits flang-commits at lists.llvm.org
Thu Jun 11 12:55:03 PDT 2026


https://github.com/mleair created https://github.com/llvm/llvm-project/pull/203379

  When a data component declaration appears after CONTAINS in a derived
  type definition, flang previously emitted confusing "expected 'FINAL'",
  "expected 'GENERIC'", and "expected 'PROCEDURE'" errors for each
  misplaced component.

   This patch adds a misplaced-component detector following the same
  pattern as `misplacedSpecificationStmt` in program-parsers.cpp.
  DataComponentDefStmt is tried as a last alternative in
  TypeBoundProcBinding's first(). When it matches, fail<>() fires
  with the message:

    error: component definition must precede CONTAINS in a derived type

  CombineFailedParses then replaces the three keyword-mismatch messages
  with this single targeted one, since the component parse advances
  further than the PROCEDURE/GENERIC/FINAL failures.

  Assisted-By: AI



>From 2b7d0dc9498d87e9a5fd7c35bb5fe0c15731872b Mon Sep 17 00:00:00 2001
From: Mark Leair <leairmark at gmail.com>
Date: Tue, 9 Jun 2026 19:18:21 -0700
Subject: [PATCH 1/2] [flang] Improve error for component definition after
 CONTAINS in derived type

When a data component declaration appears after CONTAINS in a derived
type definition, flang previously emitted confusing "expected 'FINAL'",
"expected 'GENERIC'", and "expected 'PROCEDURE'" errors for each
misplaced component.  Add a misplaced-component detector (following the
same pattern as misplacedSpecificationStmt) that parses the component
statement and then fails with a targeted message:

  error: component definition must precede CONTAINS in a derived type

This reduces the error count from six to two for the standard reproducer
and gives the same quality of diagnostic that gfortran and ifx produce.

Fixes: nvhpc-eng/lorado#3209

Assisted-by: AI
---
 flang/lib/Parser/Fortran-parsers.cpp |  5 ++++-
 flang/test/Parser/recovery09.f90     | 27 +++++++++++++++++++++++++++
 2 files changed, 31 insertions(+), 1 deletion(-)
 create mode 100644 flang/test/Parser/recovery09.f90

diff --git a/flang/lib/Parser/Fortran-parsers.cpp b/flang/lib/Parser/Fortran-parsers.cpp
index 4c57a13a64f74..0d31a3e782f76 100644
--- a/flang/lib/Parser/Fortran-parsers.cpp
+++ b/flang/lib/Parser/Fortran-parsers.cpp
@@ -562,7 +562,10 @@ TYPE_CONTEXT_PARSER("type bound procedure binding"_en_US,
     recovery(
         first(construct<TypeBoundProcBinding>(Parser<TypeBoundProcedureStmt>{}),
             construct<TypeBoundProcBinding>(Parser<TypeBoundGenericStmt>{}),
-            construct<TypeBoundProcBinding>(Parser<FinalProcedureStmt>{})),
+            construct<TypeBoundProcBinding>(Parser<FinalProcedureStmt>{}),
+            Parser<DataComponentDefStmt>{} >>
+                fail<TypeBoundProcBinding>(
+                    "component definition must precede CONTAINS in a derived type"_err_en_US)),
         construct<TypeBoundProcBinding>(
             !"END"_tok >> SkipTo<'\n'>{} >> construct<ErrorRecovery>())))
 
diff --git a/flang/test/Parser/recovery09.f90 b/flang/test/Parser/recovery09.f90
new file mode 100644
index 0000000000000..8be4fd0853b9d
--- /dev/null
+++ b/flang/test/Parser/recovery09.f90
@@ -0,0 +1,27 @@
+! RUN: not %flang_fc1 -fsyntax-only %s 2>&1 | FileCheck %s
+
+! Verify that a data component definition appearing after CONTAINS in a
+! derived type gives a clear error instead of misleading
+! "expected 'FINAL'/'GENERIC'/'PROCEDURE'" messages.
+
+module m
+  implicit none
+
+  type, public :: t1
+     real :: x
+   contains
+     procedure, public :: init
+! CHECK: error: component definition must precede CONTAINS in a derived type
+     integer, public :: n(3) = 1
+! CHECK: error: component definition must precede CONTAINS in a derived type
+     real, pointer, dimension(:,:,:), public :: gpoint => null()
+! CHECK-NOT: expected 'FINAL'
+! CHECK-NOT: expected 'GENERIC'
+! CHECK-NOT: expected 'PROCEDURE'
+  end type t1
+
+contains
+  subroutine init(this)
+    class(t1), intent(inout) :: this
+  end subroutine init
+end module m

>From 9614ed58286b0ecf3451247ef3ddb865cac3f601 Mon Sep 17 00:00:00 2001
From: Mark Leair <leairmark at gmail.com>
Date: Tue, 9 Jun 2026 19:38:56 -0700
Subject: [PATCH 2/2] [flang] Tighten CHECK patterns in recovery09 test

Bind each error diagnostic to its specific source line using CHECK-NEXT
so a regression emitting both errors from only one misplaced component
cannot satisfy the test.

Assisted-by: AI
---
 flang/test/Parser/recovery09.f90 | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/flang/test/Parser/recovery09.f90 b/flang/test/Parser/recovery09.f90
index 8be4fd0853b9d..0642fc98a0674 100644
--- a/flang/test/Parser/recovery09.f90
+++ b/flang/test/Parser/recovery09.f90
@@ -12,8 +12,10 @@ module m
    contains
      procedure, public :: init
 ! CHECK: error: component definition must precede CONTAINS in a derived type
+! CHECK-NEXT: {{.*}}integer, public :: n(3) = 1
      integer, public :: n(3) = 1
 ! CHECK: error: component definition must precede CONTAINS in a derived type
+! CHECK-NEXT: {{.*}}real, pointer, dimension(:,:,:), public :: gpoint => null()
      real, pointer, dimension(:,:,:), public :: gpoint => null()
 ! CHECK-NOT: expected 'FINAL'
 ! CHECK-NOT: expected 'GENERIC'



More information about the flang-commits mailing list