[flang-commits] [flang] [flang][Semantics] Avoid crash when pointer init follows PARAMETER with same name (PR #211604)

via flang-commits flang-commits at lists.llvm.org
Sat Aug 8 00:38:39 PDT 2026


https://github.com/shivaramaarao updated https://github.com/llvm/llvm-project/pull/211604

>From 08d18cab50f376b01b3aecde479fe579c66d6e11 Mon Sep 17 00:00:00 2001
From: Shivarama Rao <shivarama.rao at amd.com>
Date: Thu, 23 Jul 2026 21:39:40 +0530
Subject: [PATCH] [flang][Semantics] Avoid crash when pointer init follows
 PARAMETER on same name

Moved the attribute conflicting checks prior to the declaration checks.
This generates the diagnostic messages earlier and avoids the crash at pointer
initialization. Modified the test cases accordingly.

fixes issue #209980
---
 flang/lib/Semantics/resolve-names.cpp   | 31 +++++++++++++++++++++++++
 flang/test/Semantics/assign02.f90       |  4 +++-
 flang/test/Semantics/declarations02.f90 | 11 ++++-----
 flang/test/Semantics/pointer01.f90      |  2 +-
 flang/test/Semantics/pointer03.f90      |  7 ++++++
 flang/test/Semantics/resolve129.f90     |  4 ++--
 flang/test/Semantics/resolve61.f90      |  1 +
 7 files changed, 50 insertions(+), 10 deletions(-)
 create mode 100644 flang/test/Semantics/pointer03.f90

diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 996c05d0e193b..46807cf2c3c38 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -635,6 +635,7 @@ class ScopeHandler : public ImplicitRulesVisitor {
           } else if (derivedType->CanReplaceDetails(details)) {
             // was forward-referenced
             CheckDuplicatedAttrs(name, *symbol, attrs);
+            CheckConflictingAttrs(name, *symbol, attrs);
             SetExplicitAttrs(*derivedType, attrs);
             derivedType->set_details(std::move(details));
           } else {
@@ -671,11 +672,13 @@ class ScopeHandler : public ImplicitRulesVisitor {
         }
       }
       CheckDuplicatedAttrs(name, *symbol, attrs);
+      CheckConflictingAttrs(name, *symbol, attrs);
       SetExplicitAttrs(*symbol, attrs);
       symbol->set_details(std::move(details));
       return *symbol;
     } else if constexpr (std::is_same_v<UnknownDetails, D>) {
       CheckDuplicatedAttrs(name, *symbol, attrs);
+      CheckConflictingAttrs(name, *symbol, attrs);
       SetExplicitAttrs(*symbol, attrs);
       return *symbol;
     } else {
@@ -707,6 +710,7 @@ class ScopeHandler : public ImplicitRulesVisitor {
   // C815 duplicated attribute checking; returns false on error
   bool CheckDuplicatedAttr(SourceName, Symbol &, Attr);
   bool CheckDuplicatedAttrs(SourceName, Symbol &, Attrs);
+  void CheckConflictingAttrs(SourceName, Symbol &, Attrs newAttrs);
 
   void SetExplicitAttr(Symbol &symbol, Attr attr) const {
     symbol.attrs().set(attr);
@@ -3314,6 +3318,7 @@ Symbol &ScopeHandler::MakeSymbol(
     Scope &scope, const SourceName &name, Attrs attrs) {
   if (Symbol * symbol{FindInScope(scope, name)}) {
     CheckDuplicatedAttrs(name, *symbol, attrs);
+    CheckConflictingAttrs(name, *symbol, attrs);
     SetExplicitAttrs(*symbol, attrs);
     return *symbol;
   } else {
@@ -3741,6 +3746,30 @@ bool ScopeHandler::CheckDuplicatedAttrs(
   return ok;
 }
 
+void ScopeHandler::CheckConflictingAttrs(
+    SourceName source, Symbol &symbol, Attrs newAttrs) {
+  static const std::pair<Attr, Attr> conflicts[] = {
+      {Attr::POINTER, Attr::ALLOCATABLE},
+      {Attr::POINTER, Attr::TARGET},
+      {Attr::POINTER, Attr::INTRINSIC},
+      {Attr::POINTER, Attr::PARAMETER},
+      {Attr::ALLOCATABLE, Attr::PARAMETER},
+      {Attr::ASYNCHRONOUS, Attr::PARAMETER},
+      {Attr::SAVE, Attr::PARAMETER},
+      {Attr::TARGET, Attr::PARAMETER},
+      {Attr::VOLATILE, Attr::PARAMETER},
+  };
+  bool hasConflicts = false;
+  for (auto [a1, a2] : conflicts) {
+    if ((newAttrs.test(a1) && symbol.attrs().test(a2)) ||
+        (newAttrs.test(a2) && symbol.attrs().test(a1))) {
+        Say(source, "'%s' may not have both the %s and %s attributes"_err_en_US,
+            symbol.name(), AttrToString(a1), AttrToString(a2));
+	hasConflicts = true;
+    }
+  }
+  if (hasConflicts) context().SetError(symbol);
+}
 void ScopeHandler::SetCUDADataAttr(SourceName source, Symbol &symbol,
     std::optional<common::CUDADataAttr> attr) {
   if (attr) {
@@ -5422,6 +5451,7 @@ void SubprogramVisitor::CreateEntry(
           // Forward reference to ENTRY from a generic interface
           entrySymbol = specific;
           CheckDuplicatedAttrs(entryName.source, *entrySymbol, attrs);
+          CheckConflictingAttrs(entryName.source, *entrySymbol, attrs);
           SetExplicitAttrs(*entrySymbol, attrs);
         }
       }
@@ -6454,6 +6484,7 @@ Symbol &DeclarationVisitor::HandleAttributeStmt(
     HandleSaveName(name.source, Attrs{attr});
     SetExplicitAttr(*symbol, attr);
   }
+  CheckConflictingAttrs(name.source, *symbol, Attrs{attr});
   return *symbol;
 }
 // C1107
diff --git a/flang/test/Semantics/assign02.f90 b/flang/test/Semantics/assign02.f90
index c4470789476ad..ae3104fb81a45 100644
--- a/flang/test/Semantics/assign02.f90
+++ b/flang/test/Semantics/assign02.f90
@@ -16,15 +16,17 @@ module m1
   end type
 contains
 
+
   ! C852
   subroutine s0
     !ERROR: 'p1' may not have both the POINTER and TARGET attributes
     real, pointer :: p1, p3
-    !ERROR: 'p2' may not have both the POINTER and ALLOCATABLE attributes
     allocatable :: p2
     !ERROR: 'sin' may not have both the POINTER and INTRINSIC attributes
     real, intrinsic, pointer :: sin
+    !ERROR: 'p1' may not have both the POINTER and TARGET attributes
     target :: p1
+    !ERROR: 'p2' may not have both the POINTER and ALLOCATABLE attributes
     pointer :: p2
     !ERROR: 'a' may not have the POINTER attribute because it is a coarray
     real, pointer :: a(:)[*]
diff --git a/flang/test/Semantics/declarations02.f90 b/flang/test/Semantics/declarations02.f90
index 32c3517d13cd1..843eb39a2ba3a 100644
--- a/flang/test/Semantics/declarations02.f90
+++ b/flang/test/Semantics/declarations02.f90
@@ -10,18 +10,17 @@ module m
   integer, parameter :: x3 = 1
   bind(c) :: x3
 
-  !ERROR: 'x4' may not have both the ALLOCATABLE and PARAMETER attributes
-  !ERROR: 'x4' may not have both the ASYNCHRONOUS and PARAMETER attributes
-  !ERROR: 'x4' may not have both the SAVE and PARAMETER attributes
   !ERROR: 'x4' may not have both the TARGET and PARAMETER attributes
-  !ERROR: 'x4' may not have both the VOLATILE and PARAMETER attributes
-  !ERROR: The entity 'x4' with an explicit SAVE attribute must be a variable, procedure pointer, or COMMON block
-  !ERROR: An entity may not have the ASYNCHRONOUS attribute unless it is a variable
   integer, parameter :: x4 = 1
+  !ERROR: 'x4' may not have both the ALLOCATABLE and PARAMETER attributes
   allocatable x4
+  !ERROR: 'x4' may not have both the ASYNCHRONOUS and PARAMETER attributes
   asynchronous x4
+  !ERROR: 'x4' may not have both the SAVE and PARAMETER attributes
   save x4
+  !ERROR: 'x4' may not have both the TARGET and PARAMETER attributes
   target x4
+  !ERROR: 'x4' may not have both the VOLATILE and PARAMETER attributes
   volatile x4
 
   type :: my_type1
diff --git a/flang/test/Semantics/pointer01.f90 b/flang/test/Semantics/pointer01.f90
index 79d6016a6af46..a03cead60b49d 100644
--- a/flang/test/Semantics/pointer01.f90
+++ b/flang/test/Semantics/pointer01.f90
@@ -15,8 +15,8 @@ program main
   !ERROR: 'inner' cannot have the POINTER attribute
   pointer inner
   real obj
-  !ERROR: 'ip' may not have both the POINTER and PARAMETER attributes
   integer, parameter :: ip = 123
+  !ERROR: 'ip' may not have both the POINTER and PARAMETER attributes
   pointer ip
   type dt; end type
   !ERROR: 'dt' cannot have the POINTER attribute
diff --git a/flang/test/Semantics/pointer03.f90 b/flang/test/Semantics/pointer03.f90
new file mode 100644
index 0000000000000..513c385295014
--- /dev/null
+++ b/flang/test/Semantics/pointer03.f90
@@ -0,0 +1,7 @@
+! RUN: %python %S/test_errors.py %s %flang_fc1
+module m
+  integer :: t
+  parameter(i=1)
+  !ERROR: 'i' may not have both the POINTER and PARAMETER attributes
+  integer, pointer :: i => t
+end module
diff --git a/flang/test/Semantics/resolve129.f90 b/flang/test/Semantics/resolve129.f90
index 579fe50240eaf..3a89d41bb96d3 100644
--- a/flang/test/Semantics/resolve129.f90
+++ b/flang/test/Semantics/resolve129.f90
@@ -3,15 +3,15 @@
 ! Test that POINTER with PARAMETER doesn't crash.
 
 subroutine s1
-  !ERROR: 'a' may not have both the POINTER and PARAMETER attributes
   pointer a
   !ERROR: PARAMETER attribute not allowed on 'a'
+  !ERROR: 'a' may not have both the POINTER and PARAMETER attributes
   parameter(a=3)
 end subroutine
 
 subroutine s2
-  !ERROR: 'b' may not have both the POINTER and PARAMETER attributes
   integer, pointer :: b
+  !ERROR: 'b' may not have both the POINTER and PARAMETER attributes
   !ERROR: PARAMETER attribute not allowed on 'b'
   parameter(b=3)
 end subroutine
diff --git a/flang/test/Semantics/resolve61.f90 b/flang/test/Semantics/resolve61.f90
index ffee32243af6e..5a38ad2efa564 100644
--- a/flang/test/Semantics/resolve61.f90
+++ b/flang/test/Semantics/resolve61.f90
@@ -132,6 +132,7 @@ subroutine p14
   block
     asynchronous :: r
     !ERROR: PARAMETER attribute not allowed on 'r'
+    !ERROR: 'r' may not have both the ASYNCHRONOUS and PARAMETER attributes
     parameter (r = 1.0)
   end block
 end



More information about the flang-commits mailing list