[flang-commits] [flang] [flang][semantics] fix IsConstantExpr for intrinsic with optional argument (PR #161915)
Andre Kuhlenschmidt via flang-commits
flang-commits at lists.llvm.org
Fri Oct 3 22:03:27 PDT 2025
https://github.com/akuhlens updated https://github.com/llvm/llvm-project/pull/161915
>From 3e11d688a7bb19ddb1a893e5b016e368acc82092 Mon Sep 17 00:00:00 2001
From: Andre Kuhlenschmidt <akuhlenschmi at nvidia.com>
Date: Fri, 3 Oct 2025 14:53:58 -0700
Subject: [PATCH 1/7] initial commit
---
flang/include/flang/Parser/message.h | 2 +-
flang/lib/Parser/message.cpp | 24 ++++++++++++++++++++----
flang/test/Semantics/associated.f90 | 2 --
3 files changed, 21 insertions(+), 7 deletions(-)
diff --git a/flang/include/flang/Parser/message.h b/flang/include/flang/Parser/message.h
index 224263e4be860..7c639eff1eeef 100644
--- a/flang/include/flang/Parser/message.h
+++ b/flang/include/flang/Parser/message.h
@@ -307,9 +307,9 @@ class Message : public common::ReferenceCounted<Message> {
bool Merge(const Message &);
bool operator==(const Message &that) const;
bool operator!=(const Message &that) const { return !(*this == that); }
+ bool AtSameLocation(const Message &) const;
private:
- bool AtSameLocation(const Message &) const;
std::variant<ProvenanceRange, CharBlock> location_;
std::variant<MessageFixedText, MessageFormattedText, MessageExpectedText>
text_;
diff --git a/flang/lib/Parser/message.cpp b/flang/lib/Parser/message.cpp
index 2c4f930c0b088..0e06711c5b71b 100644
--- a/flang/lib/Parser/message.cpp
+++ b/flang/lib/Parser/message.cpp
@@ -477,15 +477,31 @@ void Messages::Emit(llvm::raw_ostream &o, const AllCookedSources &allCooked,
}
std::stable_sort(sorted.begin(), sorted.end(),
[](const Message *x, const Message *y) { return x->SortBefore(*y); });
- const Message *lastMsg{nullptr};
+ std::vector<const Message *> msgsWithLastLocation;
std::size_t errorsEmitted{0};
for (const Message *msg : sorted) {
- if (lastMsg && *msg == *lastMsg) {
- // Don't emit two identical messages for the same location
+ bool shouldSkipMsg = false;
+ // Don't emit two identical messages for the same location
+ // At the same location messages are sorted by the order they were
+ // added to the list, which is a decent proxy for the causality
+ // of the messages.
+ if (!msgsWithLastLocation.empty()) {
+ if (msgsWithLastLocation[0]->AtSameLocation(*msg)) {
+ for (const Message *msgAtThisLocation : msgsWithLastLocation) {
+ if (*msg == *msgAtThisLocation) {
+ shouldSkipMsg = true; // continue loop over sorted messages
+ break;
+ }
+ }
+ } else {
+ msgsWithLastLocation.clear();
+ }
+ }
+ if (shouldSkipMsg) {
continue;
}
+ msgsWithLastLocation.push_back(msg);
msg->Emit(o, allCooked, echoSourceLines, hintFlagPtr);
- lastMsg = msg;
if (warningsAreErrors || msg->IsFatal()) {
++errorsEmitted;
}
diff --git a/flang/test/Semantics/associated.f90 b/flang/test/Semantics/associated.f90
index 7cb6c240db226..731f2d828995f 100644
--- a/flang/test/Semantics/associated.f90
+++ b/flang/test/Semantics/associated.f90
@@ -253,8 +253,6 @@ subroutine test(assumedRank)
lvar = associated(intPointerVar1, targetIntCoarray[1])
!ERROR: 'neverdeclared' is not a procedure
!ERROR: Could not characterize intrinsic function actual argument 'badpointer'
- !ERROR: 'neverdeclared' is not a procedure
- !ERROR: Could not characterize intrinsic function actual argument 'badpointer'
lvar = associated(badPointer)
end subroutine test
end subroutine assoc
>From 22e8f069f67cc740d36d6da52441a54d9093cbfe Mon Sep 17 00:00:00 2001
From: Andre Kuhlenschmidt <akuhlenschmi at nvidia.com>
Date: Fri, 3 Oct 2025 15:29:05 -0700
Subject: [PATCH 2/7] don't used brace initialization
---
flang/lib/Parser/message.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/flang/lib/Parser/message.cpp b/flang/lib/Parser/message.cpp
index 0e06711c5b71b..006d3be74b6fe 100644
--- a/flang/lib/Parser/message.cpp
+++ b/flang/lib/Parser/message.cpp
@@ -480,7 +480,7 @@ void Messages::Emit(llvm::raw_ostream &o, const AllCookedSources &allCooked,
std::vector<const Message *> msgsWithLastLocation;
std::size_t errorsEmitted{0};
for (const Message *msg : sorted) {
- bool shouldSkipMsg = false;
+ bool shouldSkipMsg{false};
// Don't emit two identical messages for the same location
// At the same location messages are sorted by the order they were
// added to the list, which is a decent proxy for the causality
>From 7bb937ed5ad529d292d1b8a3a32de56f8255d18d Mon Sep 17 00:00:00 2001
From: Andre Kuhlenschmidt <akuhlenschmi at nvidia.com>
Date: Fri, 3 Oct 2025 15:44:46 -0700
Subject: [PATCH 3/7] clean up comment
---
flang/lib/Parser/message.cpp | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/flang/lib/Parser/message.cpp b/flang/lib/Parser/message.cpp
index 006d3be74b6fe..cfcd08b0861ef 100644
--- a/flang/lib/Parser/message.cpp
+++ b/flang/lib/Parser/message.cpp
@@ -481,10 +481,10 @@ void Messages::Emit(llvm::raw_ostream &o, const AllCookedSources &allCooked,
std::size_t errorsEmitted{0};
for (const Message *msg : sorted) {
bool shouldSkipMsg{false};
- // Don't emit two identical messages for the same location
- // At the same location messages are sorted by the order they were
- // added to the list, which is a decent proxy for the causality
- // of the messages.
+ // Don't emit two identical messages for the same location.
+ // At the same location, messages are sorted by the order they were
+ // added to the Messages buffer, which is a decent proxy for the
+ // causality of the messages.
if (!msgsWithLastLocation.empty()) {
if (msgsWithLastLocation[0]->AtSameLocation(*msg)) {
for (const Message *msgAtThisLocation : msgsWithLastLocation) {
>From 904ed439d37a9dbb0606b80b39990b86b7556724 Mon Sep 17 00:00:00 2001
From: Andre Kuhlenschmidt <akuhlenschmi at nvidia.com>
Date: Fri, 3 Oct 2025 09:32:18 -0700
Subject: [PATCH 4/7] initial commit
---
flang/lib/Evaluate/check-expression.cpp | 17 +++++++++++------
flang/test/Semantics/intrinsics03.f90 | 5 ++++-
flang/test/Semantics/intrinsics04.f90 | 5 ++++-
3 files changed, 19 insertions(+), 8 deletions(-)
diff --git a/flang/lib/Evaluate/check-expression.cpp b/flang/lib/Evaluate/check-expression.cpp
index 8931cbe485ac2..012b44e7d3747 100644
--- a/flang/lib/Evaluate/check-expression.cpp
+++ b/flang/lib/Evaluate/check-expression.cpp
@@ -135,16 +135,21 @@ bool IsConstantExprHelper<INVARIANT>::operator()(
} else if (proc.IsPure()) {
std::size_t j{0};
for (const auto &arg : call.arguments()) {
- if (const auto *dataDummy{j < proc.dummyArguments.size()
- ? std::get_if<characteristics::DummyDataObject>(
- &proc.dummyArguments[j].u)
- : nullptr};
- dataDummy &&
+ const auto *dataDummy{j < proc.dummyArguments.size()
+ ? std::get_if<characteristics::DummyDataObject>(
+ &proc.dummyArguments[j].u)
+ : nullptr};
+ if (dataDummy &&
dataDummy->attrs.test(
characteristics::DummyDataObject::Attr::OnlyIntrinsicInquiry)) {
// The value of the argument doesn't matter
} else if (!arg) {
- return false;
+ // Missing optional arguments are constant
+ if (!(dataDummy &&
+ dataDummy->attrs.test(
+ characteristics::DummyDataObject::Attr::Optional))) {
+ return false;
+ }
} else if (const auto *expr{arg->UnwrapExpr()};
!expr || !(*this)(*expr)) {
return false;
diff --git a/flang/test/Semantics/intrinsics03.f90 b/flang/test/Semantics/intrinsics03.f90
index a5b13b655cf41..2b07c5ee98eaf 100644
--- a/flang/test/Semantics/intrinsics03.f90
+++ b/flang/test/Semantics/intrinsics03.f90
@@ -129,6 +129,9 @@ subroutine ichar_tests()
!Without -Wportability, the warning isn't emitted and the parameter is constant.
integer, parameter :: a2 = ichar('B ')
!ERROR: Character in intrinsic function ichar must have length one
- !ERROR: Must be a constant value
+ !ERROR: Value of named constant 'a3' (ichar("")) cannot be computed as a constant value
+ !ERROR: Character in intrinsic function ichar must have length one
+ !ERROR: Value of named constant 'a3' (ichar("")) cannot be computed as a constant value
+ !ERROR: Character in intrinsic function ichar must have length one
integer, parameter :: a3 = ichar('')
end subroutine
diff --git a/flang/test/Semantics/intrinsics04.f90 b/flang/test/Semantics/intrinsics04.f90
index abb8fe321a572..8b6b29fed2128 100644
--- a/flang/test/Semantics/intrinsics04.f90
+++ b/flang/test/Semantics/intrinsics04.f90
@@ -29,6 +29,9 @@ subroutine ichar_tests()
!WARNING: Character in intrinsic function ichar should have length one [-Wportability]
integer, parameter :: a2 = ichar('B ')
!ERROR: Character in intrinsic function ichar must have length one
- !ERROR: Must be a constant value
+ !ERROR: Value of named constant 'a3' (ichar("")) cannot be computed as a constant value
+ !ERROR: Character in intrinsic function ichar must have length one
+ !ERROR: Value of named constant 'a3' (ichar("")) cannot be computed as a constant value
+ !ERROR: Character in intrinsic function ichar must have length one
integer, parameter :: a3 = ichar('')
end subroutine
>From 8c3b43fb3d3346504dddc009c80105df6df14e8a Mon Sep 17 00:00:00 2001
From: Andre Kuhlenschmidt <akuhlenschmi at nvidia.com>
Date: Fri, 3 Oct 2025 15:37:09 -0700
Subject: [PATCH 5/7] address feedback
---
flang/lib/Evaluate/check-expression.cpp | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/flang/lib/Evaluate/check-expression.cpp b/flang/lib/Evaluate/check-expression.cpp
index 012b44e7d3747..647eebaaa070b 100644
--- a/flang/lib/Evaluate/check-expression.cpp
+++ b/flang/lib/Evaluate/check-expression.cpp
@@ -144,10 +144,11 @@ bool IsConstantExprHelper<INVARIANT>::operator()(
characteristics::DummyDataObject::Attr::OnlyIntrinsicInquiry)) {
// The value of the argument doesn't matter
} else if (!arg) {
- // Missing optional arguments are constant
- if (!(dataDummy &&
- dataDummy->attrs.test(
- characteristics::DummyDataObject::Attr::Optional))) {
+ if (dataDummy &&
+ dataDummy->attrs.test(
+ characteristics::DummyDataObject::Attr::Optional)) {
+ // Missing optional arguments are okay.
+ } else {
return false;
}
} else if (const auto *expr{arg->UnwrapExpr()};
>From d9811423ce68826043e4792c09e525fb5e616d8c Mon Sep 17 00:00:00 2001
From: Andre Kuhlenschmidt <akuhlenschmi at nvidia.com>
Date: Fri, 3 Oct 2025 16:06:20 -0700
Subject: [PATCH 6/7] add test
---
flang/test/Semantics/type-parameter-constant.f90 | 15 +++++++++++++++
1 file changed, 15 insertions(+)
create mode 100644 flang/test/Semantics/type-parameter-constant.f90
diff --git a/flang/test/Semantics/type-parameter-constant.f90 b/flang/test/Semantics/type-parameter-constant.f90
new file mode 100644
index 0000000000000..376bffd0233ff
--- /dev/null
+++ b/flang/test/Semantics/type-parameter-constant.f90
@@ -0,0 +1,15 @@
+! RUN: %python %S/test_errors.py %s %flang_fc1
+type A (p, r)
+ integer, kind :: p, r
+ !ERROR: KIND parameter expression (int(selected_real_kind(six,twenty_three),kind=8)) of intrinsic type REAL did not resolve to a constant value
+ real (selected_real_kind(p, r)) :: data
+end type
+ integer :: six = 6, twenty_three = 23
+ type(a(6,23)) :: a1
+ !ERROR: Value of KIND type parameter 'p' must be constant
+ !ERROR: Value of KIND type parameter 'r' must be constant
+ !WARNING: specification expression refers to local object 'six' (initialized and saved) [-Wsaved-local-in-spec-expr]
+ !WARNING: specification expression refers to local object 'twenty_three' (initialized and saved) [-Wsaved-local-in-spec-expr]
+ type(a(six, twenty_three)) :: a2
+ print *, a1%data%kind
+end
\ No newline at end of file
>From b395191a517a61456fad7271ee58353021a9f6b6 Mon Sep 17 00:00:00 2001
From: Andre Kuhlenschmidt <akuhlenschmi at nvidia.com>
Date: Fri, 3 Oct 2025 16:17:58 -0700
Subject: [PATCH 7/7] fix duplicate messages in results
---
flang/test/Semantics/intrinsics03.f90 | 3 ---
flang/test/Semantics/intrinsics04.f90 | 3 ---
2 files changed, 6 deletions(-)
diff --git a/flang/test/Semantics/intrinsics03.f90 b/flang/test/Semantics/intrinsics03.f90
index 2b07c5ee98eaf..1a4269868a3d4 100644
--- a/flang/test/Semantics/intrinsics03.f90
+++ b/flang/test/Semantics/intrinsics03.f90
@@ -130,8 +130,5 @@ subroutine ichar_tests()
integer, parameter :: a2 = ichar('B ')
!ERROR: Character in intrinsic function ichar must have length one
!ERROR: Value of named constant 'a3' (ichar("")) cannot be computed as a constant value
- !ERROR: Character in intrinsic function ichar must have length one
- !ERROR: Value of named constant 'a3' (ichar("")) cannot be computed as a constant value
- !ERROR: Character in intrinsic function ichar must have length one
integer, parameter :: a3 = ichar('')
end subroutine
diff --git a/flang/test/Semantics/intrinsics04.f90 b/flang/test/Semantics/intrinsics04.f90
index 8b6b29fed2128..e733067237d17 100644
--- a/flang/test/Semantics/intrinsics04.f90
+++ b/flang/test/Semantics/intrinsics04.f90
@@ -30,8 +30,5 @@ subroutine ichar_tests()
integer, parameter :: a2 = ichar('B ')
!ERROR: Character in intrinsic function ichar must have length one
!ERROR: Value of named constant 'a3' (ichar("")) cannot be computed as a constant value
- !ERROR: Character in intrinsic function ichar must have length one
- !ERROR: Value of named constant 'a3' (ichar("")) cannot be computed as a constant value
- !ERROR: Character in intrinsic function ichar must have length one
integer, parameter :: a3 = ichar('')
end subroutine
More information about the flang-commits
mailing list