[flang-commits] [flang] [flang] Correctly buffer warnings in Semantics/check-call.cpp (PR #172738)
via flang-commits
flang-commits at lists.llvm.org
Wed Dec 17 12:58:25 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-semantics
Author: Peter Klausler (klausler)
<details>
<summary>Changes</summary>
There are calls to semantics::SemanticsContext::Warn() in check-call.cpp that are not properly directing their output to the local message buffer, so they can appear unconditionally in the output of the compiler. This is a problem for generic interface resolution, which checks procedure actual arguments against specific procedures using this code, buffering the messages that might appear, and discarding the messages for failed matches. Worse, the bogus warnings that escape the buffering can be associated with completely unrelated locations.
Fix by passing the local message buffer to these Warn() calls.
(I couldn't come up with a good reduced test case, and am not sure that the original code can be copied for use as one.)
---
Full diff: https://github.com/llvm/llvm-project/pull/172738.diff
1 Files Affected:
- (modified) flang/lib/Semantics/check-call.cpp (+14-16)
``````````diff
diff --git a/flang/lib/Semantics/check-call.cpp b/flang/lib/Semantics/check-call.cpp
index 022b4289b4e7c..1f8e8a96a5027 100644
--- a/flang/lib/Semantics/check-call.cpp
+++ b/flang/lib/Semantics/check-call.cpp
@@ -208,6 +208,7 @@ static void CheckCharacterActual(evaluate::Expr<evaluate::SomeType> &actual,
} else {
context.Warn(messages,
common::UsageWarning::ShortCharacterActual,
+ messages.at(),
"Actual argument has fewer characters remaining in storage sequence (%jd) than %s (%jd)"_warn_en_US,
static_cast<std::intmax_t>(actualChars), dummyName,
static_cast<std::intmax_t>(dummyChars));
@@ -227,7 +228,7 @@ static void CheckCharacterActual(evaluate::Expr<evaluate::SomeType> &actual,
static_cast<std::intmax_t>(*dummySize * *dummyLength));
} else {
context.Warn(messages,
- common::UsageWarning::ShortCharacterActual,
+ common::UsageWarning::ShortCharacterActual, messages.at(),
"Actual argument array has fewer characters (%jd) than %s array (%jd)"_warn_en_US,
static_cast<std::intmax_t>(*actualSize * *actualLength),
dummyName,
@@ -610,9 +611,8 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
!dummy.ignoreTKR.test(common::IgnoreTKR::Contiguous)) {
if (IsPointer(*actualLastSymbol)) {
if (isOkBecauseContiguous) {
- context.Warn(
+ context.Warn(messages,
common::LanguageFeature::ContiguousOkForSeqAssociation,
- messages.at(),
"Element of contiguous pointer array is accepted for storage sequence association"_port_en_US);
} else {
basicError = true;
@@ -623,9 +623,8 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
} else if (IsAssumedShape(*actualLastSymbol) &&
!dummy.ignoreTKR.test(common::IgnoreTKR::Contiguous)) {
if (isOkBecauseContiguous) {
- context.Warn(
+ context.Warn(messages,
common::LanguageFeature::ContiguousOkForSeqAssociation,
- messages.at(),
"Element of contiguous assumed-shape array is accepted for storage sequence association"_port_en_US);
} else {
basicError = true;
@@ -653,9 +652,8 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
messages.Say(
"Assumed-rank array may not be associated with a dummy argument that is not assumed-rank"_err_en_US);
} else {
- context.Warn(
+ context.Warn(messages,
common::LanguageFeature::AssumedRankPassedToNonAssumedRank,
- messages.at(),
"Assumed-rank array should not be associated with a dummy argument that is not assumed-rank"_port_en_US);
}
} else if (actualRank == 0) {
@@ -693,7 +691,7 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
static_cast<std::intmax_t>(*actualElements), dummyName,
static_cast<std::intmax_t>(*dummySize));
} else {
- context.Warn(common::UsageWarning::ShortArrayActual,
+ context.Warn(messages, common::UsageWarning::ShortArrayActual,
"Actual argument has fewer elements remaining in storage sequence (%jd) than %s array (%jd)"_warn_en_US,
static_cast<std::intmax_t>(*actualElements), dummyName,
static_cast<std::intmax_t>(*dummySize));
@@ -711,7 +709,7 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
static_cast<std::intmax_t>(*actualSize), dummyName,
static_cast<std::intmax_t>(*dummySize));
} else {
- context.Warn(common::UsageWarning::ShortArrayActual,
+ context.Warn(messages, common::UsageWarning::ShortArrayActual,
"Actual argument array has fewer elements (%jd) than %s array (%jd)"_warn_en_US,
static_cast<std::intmax_t>(*actualSize), dummyName,
static_cast<std::intmax_t>(*dummySize));
@@ -826,8 +824,8 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
(actualIsPointer && dummyIsPointer)) &&
evaluate::IsArraySection(actual) && !actualIsContiguous &&
!evaluate::HasVectorSubscript(actual)) {
- context.Warn(common::UsageWarning::VolatileOrAsynchronousTemporary,
- messages.at(),
+ context.Warn(messages,
+ common::UsageWarning::VolatileOrAsynchronousTemporary,
"The array section '%s' should not be associated with %s with %s attribute, unless the dummy is assumed-shape or assumed-rank"_warn_en_US,
actual.AsFortran(), dummyName,
dummyIsAsynchronous ? "ASYNCHRONOUS" : "VOLATILE");
@@ -844,8 +842,8 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
if (copyOutNeeded && !volatileOrAsyncNeedsTempDiagnosticIssued) {
if ((actualIsVolatile || actualIsAsynchronous) &&
(dummyIsVolatile || dummyIsAsynchronous)) {
- context.Warn(common::UsageWarning::VolatileOrAsynchronousTemporary,
- messages.at(),
+ context.Warn(messages,
+ common::UsageWarning::VolatileOrAsynchronousTemporary,
"The actual argument '%s' with %s attribute should not be associated with %s with %s attribute, because a temporary copy is required during the call"_warn_en_US,
actual.AsFortran(), actualIsVolatile ? "VOLATILE" : "ASYNCHRONOUS",
dummyName, dummyIsVolatile ? "VOLATILE" : "ASYNCHRONOUS");
@@ -863,7 +861,7 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
(actualIsPointer && dummyIsPointer)) &&
evaluate::IsArraySection(actual) &&
!evaluate::HasVectorSubscript(actual)) {
- context.Warn(common::UsageWarning::Portability, messages.at(),
+ context.Warn(messages, common::UsageWarning::Portability,
"The array section '%s' should not be associated with %s with %s attribute, unless the dummy is assumed-shape or assumed-rank"_port_en_US,
actual.AsFortran(), dummyName,
dummyIsAsynchronous ? "ASYNCHRONOUS" : "VOLATILE");
@@ -872,7 +870,7 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
if (copyOutNeeded && !volatileOrAsyncNeedsTempDiagnosticIssued) {
if ((dummyIsVolatile && !actualIsVolatile && !actualIsAsynchronous) ||
(dummyIsAsynchronous && !actualIsVolatile && !actualIsAsynchronous)) {
- context.Warn(common::UsageWarning::Portability, messages.at(),
+ context.Warn(messages, common::UsageWarning::Portability,
"The actual argument '%s' should not be associated with %s with %s attribute, because a temporary copy is required during the call"_port_en_US,
actual.AsFortran(), dummyName,
dummyIsVolatile ? "VOLATILE" : "ASYNCHRONOUS");
@@ -2437,7 +2435,7 @@ bool CheckArguments(const characteristics::Procedure &proc,
intrinsic, allowArgumentConversions,
/*extentErrors=*/true, ignoreImplicitVsExplicit)};
if (!explicitBuffer.empty()) {
- if (treatingExternalAsImplicit) {
+ if (treatingExternalAsImplicit && explicitBuffer.AnyFatalError()) {
// Combine all messages into one warning
if (auto *warning{messages.Warn(/*inModuleFile=*/false,
context.languageFeatures(),
``````````
</details>
https://github.com/llvm/llvm-project/pull/172738
More information about the flang-commits
mailing list