[flang-commits] [flang] 08c7d57 - [flang] Add options to control IMPLICIT NONE
Tim Keith via flang-commits
flang-commits at lists.llvm.org
Thu Aug 6 06:48:23 PDT 2020
Author: Tim Keith
Date: 2020-08-06T06:48:01-07:00
New Revision: 08c7d570d30bb9568fb2219db7b1b8a9532559dd
URL: https://github.com/llvm/llvm-project/commit/08c7d570d30bb9568fb2219db7b1b8a9532559dd
DIFF: https://github.com/llvm/llvm-project/commit/08c7d570d30bb9568fb2219db7b1b8a9532559dd.diff
LOG: [flang] Add options to control IMPLICIT NONE
Add `-fimplicit-none-type-always` to treat each specification-part
like it has `IMPLICIT NONE`. This is helpful for enforcing good Fortran
programming practices. We might consider something similar for
`IMPLICIT NONE(EXTERNAL)` as well.
Add `-fimplicit-none-type-never` to ignore occurrences of `IMPLICIT NONE`
and `IMPLICIT NONE(TYPE)`. This is to handle cases like the one below,
which violates the standard but it accepted by some compilers:
```
subroutine s(a, n)
implicit none
real :: a(n)
integer :: n
end
```
Differential Revision: https://reviews.llvm.org/D85363
Added:
flang/test/Semantics/implicit09.f90
flang/test/Semantics/implicit10.f90
Modified:
flang/documentation/Extensions.md
flang/include/flang/Common/Fortran-features.h
flang/lib/Semantics/resolve-names.cpp
flang/tools/f18/f18.cpp
Removed:
################################################################################
diff --git a/flang/documentation/Extensions.md b/flang/documentation/Extensions.md
index a2420c727e82..8bf5647bd60c 100644
--- a/flang/documentation/Extensions.md
+++ b/flang/documentation/Extensions.md
@@ -139,6 +139,10 @@ Extensions supported when enabled by options
`FINDLOC`, `MAXLOC`, and `MINLOC` in the absence of an explicit
`KIND=` actual argument. We return `INTEGER(KIND=8)` by default in
these cases when the `-flarge-sizes` option is enabled.
+* Treat each specification-part like is has `IMPLICIT NONE`
+ [-fimplicit-none-type-always]
+* Ignore occurrences of `IMPLICIT NONE` and `IMPLICIT NONE(TYPE)`
+ [-fimplicit-none-type-never]
Extensions and legacy features deliberately not supported
---------------------------------------------------------
diff --git a/flang/include/flang/Common/Fortran-features.h b/flang/include/flang/Common/Fortran-features.h
index 613aa69cc5d6..ebf7a8d9d623 100644
--- a/flang/include/flang/Common/Fortran-features.h
+++ b/flang/include/flang/Common/Fortran-features.h
@@ -28,7 +28,8 @@ ENUM_CLASS(LanguageFeature, BackslashEscapes, OldDebugLines,
CruftAfterAmpersand, ClassicCComments, AdditionalFormats, BigIntLiterals,
RealDoControls, EquivalenceNumericWithCharacter, AdditionalIntrinsics,
AnonymousParents, OldLabelDoEndStatements, LogicalIntegerAssignment,
- EmptySourceFile, ProgramReturn)
+ EmptySourceFile, ProgramReturn, ImplicitNoneTypeNever,
+ ImplicitNoneTypeAlways)
using LanguageFeatures = EnumSet<LanguageFeature, LanguageFeature_enumSize>;
@@ -39,6 +40,8 @@ class LanguageFeatureControl {
disable_.set(LanguageFeature::OldDebugLines);
disable_.set(LanguageFeature::OpenACC);
disable_.set(LanguageFeature::OpenMP);
+ disable_.set(LanguageFeature::ImplicitNoneTypeNever);
+ disable_.set(LanguageFeature::ImplicitNoneTypeAlways);
// These features, if enabled, conflict with valid standard usage,
// so there are disabled here by default.
disable_.set(LanguageFeature::BackslashEscapes);
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index c5b42473d011..b245ef91deaa 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -81,7 +81,8 @@ class ImplicitRules {
ImplicitRules *parent_;
SemanticsContext &context_;
bool inheritFromParent_{false}; // look in parent if not specified here
- bool isImplicitNoneType_{false};
+ bool isImplicitNoneType_{
+ context_.IsEnabled(common::LanguageFeature::ImplicitNoneTypeAlways)};
bool isImplicitNoneExternal_{false};
// map_ contains the mapping between letters and types that were defined
// by the IMPLICIT statements of the related scope. It does not contain
@@ -1682,9 +1683,8 @@ bool ImplicitRulesVisitor::Pre(const parser::ImplicitStmt &x) {
Say("IMPLICIT statement after IMPLICIT NONE or "
"IMPLICIT NONE(TYPE) statement"_err_en_US);
return false;
- } else {
- implicitRules().set_isImplicitNoneType(false);
}
+ implicitRules().set_isImplicitNoneType(false);
return true;
},
},
@@ -1744,12 +1744,16 @@ bool ImplicitRulesVisitor::HandleImplicitNone(
return false;
}
prevImplicitNone_ = currStmtSource();
+ bool implicitNoneTypeNever{
+ context().IsEnabled(common::LanguageFeature::ImplicitNoneTypeNever)};
if (nameSpecs.empty()) {
- prevImplicitNoneType_ = currStmtSource();
- implicitRules().set_isImplicitNoneType(true);
- if (prevImplicit_) {
- Say("IMPLICIT NONE statement after IMPLICIT statement"_err_en_US);
- return false;
+ if (!implicitNoneTypeNever) {
+ prevImplicitNoneType_ = currStmtSource();
+ implicitRules().set_isImplicitNoneType(true);
+ if (prevImplicit_) {
+ Say("IMPLICIT NONE statement after IMPLICIT statement"_err_en_US);
+ return false;
+ }
}
} else {
int sawType{0};
@@ -1761,13 +1765,15 @@ bool ImplicitRulesVisitor::HandleImplicitNone(
++sawExternal;
break;
case ImplicitNoneNameSpec::Type:
- prevImplicitNoneType_ = currStmtSource();
- implicitRules().set_isImplicitNoneType(true);
- if (prevImplicit_) {
- Say("IMPLICIT NONE(TYPE) after IMPLICIT statement"_err_en_US);
- return false;
+ if (!implicitNoneTypeNever) {
+ prevImplicitNoneType_ = currStmtSource();
+ implicitRules().set_isImplicitNoneType(true);
+ if (prevImplicit_) {
+ Say("IMPLICIT NONE(TYPE) after IMPLICIT statement"_err_en_US);
+ return false;
+ }
+ ++sawType;
}
- ++sawType;
break;
}
}
diff --git a/flang/test/Semantics/implicit09.f90 b/flang/test/Semantics/implicit09.f90
new file mode 100644
index 000000000000..30577fccb0f6
--- /dev/null
+++ b/flang/test/Semantics/implicit09.f90
@@ -0,0 +1,11 @@
+! RUN: %S/test_errors.sh %s %t %f18 -fimplicit-none-type-never
+subroutine s1
+ implicit none
+ i = j + k ! would be error without -fimplicit-none-type-never
+end
+
+subroutine s2(a, n)
+ implicit none
+ real :: a(n) ! would be error without -fimplicit-none-type-never
+ integer :: n
+end
diff --git a/flang/test/Semantics/implicit10.f90 b/flang/test/Semantics/implicit10.f90
new file mode 100644
index 000000000000..a77ada8f4893
--- /dev/null
+++ b/flang/test/Semantics/implicit10.f90
@@ -0,0 +1,7 @@
+! RUN: %S/test_errors.sh %s %t %f18 -fimplicit-none-type-always
+
+!ERROR: No explicit type declared for 'f'
+function f()
+ !ERROR: No explicit type declared for 'x'
+ f = x
+end
diff --git a/flang/tools/f18/f18.cpp b/flang/tools/f18/f18.cpp
index 338d04e7e8f5..33c7b6f6ce9e 100644
--- a/flang/tools/f18/f18.cpp
+++ b/flang/tools/f18/f18.cpp
@@ -503,6 +503,12 @@ int main(int argc, char *const argv[]) {
options.features.Enable(
Fortran::parser::LanguageFeature::LogicalAbbreviations,
arg == "-flogical-abbreviations");
+ } else if (arg == "-fimplicit-none-type-always") {
+ options.features.Enable(
+ Fortran::common::LanguageFeature::ImplicitNoneTypeAlways);
+ } else if (arg == "-fimplicit-none-type-never") {
+ options.features.Enable(
+ Fortran::common::LanguageFeature::ImplicitNoneTypeNever);
} else if (arg == "-fdebug-dump-provenance") {
driver.dumpProvenance = true;
options.needProvenanceRangeToCharBlockMappings = true;
@@ -603,7 +609,8 @@ int main(int argc, char *const argv[]) {
driver.getSymbolsSources = true;
} else if (arg == "-byteswapio") {
driver.byteswapio = true; // TODO: Pass to lowering, generate call
- } else if (arg == "-h" || arg == "-help" || arg == "--help" || arg == "-?") {
+ } else if (arg == "-h" || arg == "-help" || arg == "--help" ||
+ arg == "-?") {
llvm::errs()
<< "f18: LLVM Fortran compiler\n"
<< "\n"
More information about the flang-commits
mailing list