[flang-commits] [flang] c66645d - [flang] Catch more initialization errors (#77850)
via flang-commits
flang-commits at lists.llvm.org
Mon Jan 15 13:02:08 PST 2024
Author: Peter Klausler
Date: 2024-01-15T13:02:04-08:00
New Revision: c66645da55b9f4c13f4a612392dcc5a84b086ba7
URL: https://github.com/llvm/llvm-project/commit/c66645da55b9f4c13f4a612392dcc5a84b086ba7
DIFF: https://github.com/llvm/llvm-project/commit/c66645da55b9f4c13f4a612392dcc5a84b086ba7.diff
LOG: [flang] Catch more initialization errors (#77850)
[flang] Catch more initialization errors
Diagnose some error cases related to initialization that are
slipping past semantic checking: don't allow multiple initializations
of the same symbol, and don't allow an object that was initialized
as a scalar to become an array afterward.
Fixes llvm-test-suite/Fortran/gfortran/regression/initialization_17.f90.
Added:
Modified:
flang/lib/Semantics/resolve-names.cpp
flang/test/Semantics/init01.f90
flang/test/Semantics/pointer01.f90
Removed:
################################################################################
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 0e62a48784bc26..e4a841ec28486c 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -4554,6 +4554,9 @@ bool DeclarationVisitor::Pre(const parser::NamedConstantDef &x) {
}
const auto &expr{std::get<parser::ConstantExpr>(x.t)};
auto &details{symbol.get<ObjectEntityDetails>()};
+ if (details.init() || symbol.test(Symbol::Flag::InDataStmt)) {
+ Say(name, "Named constant '%s' already has a value"_err_en_US);
+ }
if (inOldStyleParameterStmt_) {
// non-standard extension PARAMETER statement (no parentheses)
Walk(expr);
@@ -4932,6 +4935,8 @@ Symbol &DeclarationVisitor::DeclareObjectEntity(
} else if (MustBeScalar(symbol)) {
Say(name,
"'%s' appeared earlier as a scalar actual argument to a specification function"_warn_en_US);
+ } else if (details->init() || symbol.test(Symbol::Flag::InDataStmt)) {
+ Say(name, "'%s' was initialized earlier as a scalar"_err_en_US);
} else {
details->set_shape(arraySpec());
}
@@ -7577,9 +7582,11 @@ void DeclarationVisitor::Initialization(const parser::Name &name,
"Pointer initializer must be intrinsic NULL()"_err_en_US);
} else if (IsPointer(ultimate)) {
if (auto *object{ultimate.detailsIf<ObjectEntityDetails>()}) {
+ CHECK(!object->init());
object->set_init(std::move(*nullInit));
} else if (auto *procPtr{
ultimate.detailsIf<ProcEntityDetails>()}) {
+ CHECK(!procPtr->init());
procPtr->set_init(nullptr);
}
} else {
@@ -7679,6 +7686,8 @@ void DeclarationVisitor::NonPointerInitialization(
"'%s' is a pointer but is not initialized like one"_err_en_US);
} else if (auto *details{ultimate.detailsIf<ObjectEntityDetails>()}) {
if (details->init()) {
+ SayWithDecl(name, *name.symbol,
+ "'%s' has already been initialized"_err_en_US);
} else if (IsAllocatable(ultimate)) {
Say(name, "Allocatable object '%s' cannot be initialized"_err_en_US);
} else if (ultimate.owner().IsParameterizedDerivedType()) {
@@ -8928,7 +8937,12 @@ class DeferredCheckVisitor {
resolver_.PointerInitialization(name, *target);
} else if (const auto *expr{
std::get_if<parser::ConstantExpr>(&init->u)}) {
- resolver_.NonPointerInitialization(name, *expr);
+ if (name.symbol) {
+ if (const auto *object{name.symbol->detailsIf<ObjectEntityDetails>()};
+ !object || !object->init()) {
+ resolver_.NonPointerInitialization(name, *expr);
+ }
+ }
}
}
}
diff --git a/flang/test/Semantics/init01.f90 b/flang/test/Semantics/init01.f90
index 0f5a2144c79f97..f58c034d5deab2 100644
--- a/flang/test/Semantics/init01.f90
+++ b/flang/test/Semantics/init01.f90
@@ -106,3 +106,21 @@ subroutine notObjects
!ERROR: 'x4' is not a pointer but is initialized like one
real, intrinsic :: x4 => cos
end subroutine
+
+subroutine edgeCases
+ integer :: j = 1, m = 2
+ !ERROR: Data statement object must be a variable
+ data k/3/
+ data n/4/
+ !ERROR: Named constant 'j' already has a value
+ parameter(j = 5)
+ !ERROR: Named constant 'k' already has a value
+ parameter(k = 6)
+ parameter(l = 7)
+ !ERROR: 'm' was initialized earlier as a scalar
+ dimension m(1)
+ !ERROR: 'l' was initialized earlier as a scalar
+ dimension l(1)
+ !ERROR: 'n' was initialized earlier as a scalar
+ dimension n(1)
+end
diff --git a/flang/test/Semantics/pointer01.f90 b/flang/test/Semantics/pointer01.f90
index 9e87d1b689eb2b..cb860f3a3f437c 100644
--- a/flang/test/Semantics/pointer01.f90
+++ b/flang/test/Semantics/pointer01.f90
@@ -16,7 +16,6 @@ program main
!ERROR: 'inner' cannot have the POINTER attribute
pointer inner
real obj
- !ERROR: 'ip' is a pointer but is not initialized like one
!ERROR: 'ip' may not have both the POINTER and PARAMETER attributes
integer, parameter :: ip = 123
pointer ip
More information about the flang-commits
mailing list