[flang-commits] [flang] [flang] Further refine errors vs warnings for ambiguous generics (PR #80161)
via flang-commits
flang-commits at lists.llvm.org
Wed Jan 31 08:39:37 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-semantics
Author: Peter Klausler (klausler)
<details>
<summary>Changes</summary>
Ensure that the compiler emits a hard error for a generic interface with ambiguous specific procedures when it is declared as such, and the ambiguity doesn't involve optional or unlimited polymorphic dummy data arguments. But: emit an optional portability warning when the ambiguity in the generic interface is due to USE association's merging of multiple generics, as USE association may involve modules not under control of the programmer; we'll emit a hard error message if any the actual arguments in a particular reference to the generic procedure doesn't resolve to exactly one specific procedure. And don't emit warnings when potential ambiguity due to USE association is taking place in a module file; the warnings, if any, will have been produced when the module file was compiled.
---
Full diff: https://github.com/llvm/llvm-project/pull/80161.diff
2 Files Affected:
- (modified) flang/lib/Semantics/check-declarations.cpp (+28-15)
- (modified) flang/test/Semantics/resolve17.f90 (+1-1)
``````````diff
diff --git a/flang/lib/Semantics/check-declarations.cpp b/flang/lib/Semantics/check-declarations.cpp
index 8af9dc11f822e..f701444e9ccd1 100644
--- a/flang/lib/Semantics/check-declarations.cpp
+++ b/flang/lib/Semantics/check-declarations.cpp
@@ -192,7 +192,7 @@ class DistinguishabilityHelper {
private:
void SayNotDistinguishable(const Scope &, const SourceName &, GenericKind,
- const Symbol &, const Symbol &, bool isError);
+ const Symbol &, const Symbol &, bool isHardConflict);
void AttachDeclaration(parser::Message &, const Scope &, const Symbol &);
SemanticsContext &context_;
@@ -3512,6 +3512,13 @@ void DistinguishabilityHelper::Add(const Symbol &generic, GenericKind kind,
}
void DistinguishabilityHelper::Check(const Scope &scope) {
+#if 0
+ if (FindModuleFileContaining(scope)) {
+ // Distinguishability was checked when the module was created;
+ // don't let optional warnings then become errors now.
+ return;
+ }
+#endif
for (const auto &[name, info] : nameToSpecifics_) {
for (auto iter1{info.begin()}; iter1 != info.end(); ++iter1) {
const auto &[ultimate, procInfo]{*iter1};
@@ -3533,15 +3540,19 @@ void DistinguishabilityHelper::Check(const Scope &scope) {
void DistinguishabilityHelper::SayNotDistinguishable(const Scope &scope,
const SourceName &name, GenericKind kind, const Symbol &proc1,
- const Symbol &proc2, bool isError) {
- if (!isError &&
- !context_.ShouldWarn(
- common::LanguageFeature::IndistinguishableSpecifics)) {
- // The rules for distinguishing specific procedures (F'2023 15.4.3.4.5)
- // are inadequate for some real-world cases like pFUnit.
- // When there are optional dummy arguments or unlimited polymorphic
- // dummy data object arguments, the best that we can do is emit an optional
- // portability warning.
+ const Symbol &proc2, bool isHardConflict) {
+ bool isUseAssociated{!scope.sourceRange().Contains(name)};
+ // The rules for distinguishing specific procedures (F'2023 15.4.3.4.5)
+ // are inadequate for some real-world cases like pFUnit.
+ // When there are optional dummy arguments or unlimited polymorphic
+ // dummy data object arguments, the best that we can do is emit an optional
+ // portability warning. Also, generics created by USE association
+ // merging shouldn't receive hard errors for ambiguity.
+ bool isWarning{!isHardConflict || isUseAssociated};
+ if (isWarning &&
+ (!context_.ShouldWarn(
+ common::LanguageFeature::IndistinguishableSpecifics) ||
+ FindModuleFileContaining(scope))) {
return;
}
std::string name1{proc1.name().ToString()};
@@ -3556,17 +3567,19 @@ void DistinguishabilityHelper::SayNotDistinguishable(const Scope &scope,
}
}
parser::Message *msg;
- if (scope.sourceRange().Contains(name)) {
+ if (!isUseAssociated) {
+ CHECK(isWarning == !isHardConflict);
msg = &context_.Say(name,
- isError
+ isHardConflict
? "Generic '%s' may not have specific procedures '%s' and '%s' as their interfaces are not distinguishable"_err_en_US
: "Generic '%s' should not have specific procedures '%s' and '%s' as their interfaces are not distinguishable by the rules in the standard"_port_en_US,
MakeOpName(name), name1, name2);
} else {
+ CHECK(isWarning);
msg = &context_.Say(*GetTopLevelUnitContaining(proc1).GetName(),
- isError
- ? "USE-associated generic '%s' may not have specific procedures '%s' and '%s' as their interfaces are not distinguishable"_err_en_US
- : "USE-associated generic '%s' should not have specific procedures '%s' and '%s' as their interfaces are not distinguishable by the incomplete rules in the standard"_port_en_US,
+ isHardConflict
+ ? "USE-associated generic '%s' should not have specific procedures '%s' and '%s' as their interfaces are not distinguishable"_warn_en_US
+ : "USE-associated generic '%s' should not have specific procedures '%s' and '%s' as their interfaces are not distinguishable by the rules in the standard"_port_en_US,
MakeOpName(name), name1, name2);
}
AttachDeclaration(*msg, scope, proc1);
diff --git a/flang/test/Semantics/resolve17.f90 b/flang/test/Semantics/resolve17.f90
index 513676fe670a1..770af756d03bc 100644
--- a/flang/test/Semantics/resolve17.f90
+++ b/flang/test/Semantics/resolve17.f90
@@ -180,7 +180,7 @@ subroutine g()
end
end module
subroutine s9
- !ERROR: USE-associated generic 'g' may not have specific procedures 'g' and 'g' as their interfaces are not distinguishable
+ !PORTABILITY: USE-associated generic 'g' should not have specific procedures 'g' and 'g' as their interfaces are not distinguishable
use m9a
use m9b
end
``````````
</details>
https://github.com/llvm/llvm-project/pull/80161
More information about the flang-commits
mailing list