Skip to content

Commit c66645d

Browse files
authored
[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.
1 parent 8375030 commit c66645d

File tree

3 files changed

+33
-2
lines changed

3 files changed

+33
-2
lines changed

flang/lib/Semantics/resolve-names.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4554,6 +4554,9 @@ bool DeclarationVisitor::Pre(const parser::NamedConstantDef &x) {
45544554
}
45554555
const auto &expr{std::get<parser::ConstantExpr>(x.t)};
45564556
auto &details{symbol.get<ObjectEntityDetails>()};
4557+
if (details.init() || symbol.test(Symbol::Flag::InDataStmt)) {
4558+
Say(name, "Named constant '%s' already has a value"_err_en_US);
4559+
}
45574560
if (inOldStyleParameterStmt_) {
45584561
// non-standard extension PARAMETER statement (no parentheses)
45594562
Walk(expr);
@@ -4932,6 +4935,8 @@ Symbol &DeclarationVisitor::DeclareObjectEntity(
49324935
} else if (MustBeScalar(symbol)) {
49334936
Say(name,
49344937
"'%s' appeared earlier as a scalar actual argument to a specification function"_warn_en_US);
4938+
} else if (details->init() || symbol.test(Symbol::Flag::InDataStmt)) {
4939+
Say(name, "'%s' was initialized earlier as a scalar"_err_en_US);
49354940
} else {
49364941
details->set_shape(arraySpec());
49374942
}
@@ -7577,9 +7582,11 @@ void DeclarationVisitor::Initialization(const parser::Name &name,
75777582
"Pointer initializer must be intrinsic NULL()"_err_en_US);
75787583
} else if (IsPointer(ultimate)) {
75797584
if (auto *object{ultimate.detailsIf<ObjectEntityDetails>()}) {
7585+
CHECK(!object->init());
75807586
object->set_init(std::move(*nullInit));
75817587
} else if (auto *procPtr{
75827588
ultimate.detailsIf<ProcEntityDetails>()}) {
7589+
CHECK(!procPtr->init());
75837590
procPtr->set_init(nullptr);
75847591
}
75857592
} else {
@@ -7679,6 +7686,8 @@ void DeclarationVisitor::NonPointerInitialization(
76797686
"'%s' is a pointer but is not initialized like one"_err_en_US);
76807687
} else if (auto *details{ultimate.detailsIf<ObjectEntityDetails>()}) {
76817688
if (details->init()) {
7689+
SayWithDecl(name, *name.symbol,
7690+
"'%s' has already been initialized"_err_en_US);
76827691
} else if (IsAllocatable(ultimate)) {
76837692
Say(name, "Allocatable object '%s' cannot be initialized"_err_en_US);
76847693
} else if (ultimate.owner().IsParameterizedDerivedType()) {
@@ -8928,7 +8937,12 @@ class DeferredCheckVisitor {
89288937
resolver_.PointerInitialization(name, *target);
89298938
} else if (const auto *expr{
89308939
std::get_if<parser::ConstantExpr>(&init->u)}) {
8931-
resolver_.NonPointerInitialization(name, *expr);
8940+
if (name.symbol) {
8941+
if (const auto *object{name.symbol->detailsIf<ObjectEntityDetails>()};
8942+
!object || !object->init()) {
8943+
resolver_.NonPointerInitialization(name, *expr);
8944+
}
8945+
}
89328946
}
89338947
}
89348948
}

flang/test/Semantics/init01.f90

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,3 +106,21 @@ subroutine notObjects
106106
!ERROR: 'x4' is not a pointer but is initialized like one
107107
real, intrinsic :: x4 => cos
108108
end subroutine
109+
110+
subroutine edgeCases
111+
integer :: j = 1, m = 2
112+
!ERROR: Data statement object must be a variable
113+
data k/3/
114+
data n/4/
115+
!ERROR: Named constant 'j' already has a value
116+
parameter(j = 5)
117+
!ERROR: Named constant 'k' already has a value
118+
parameter(k = 6)
119+
parameter(l = 7)
120+
!ERROR: 'm' was initialized earlier as a scalar
121+
dimension m(1)
122+
!ERROR: 'l' was initialized earlier as a scalar
123+
dimension l(1)
124+
!ERROR: 'n' was initialized earlier as a scalar
125+
dimension n(1)
126+
end

flang/test/Semantics/pointer01.f90

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ program main
1616
!ERROR: 'inner' cannot have the POINTER attribute
1717
pointer inner
1818
real obj
19-
!ERROR: 'ip' is a pointer but is not initialized like one
2019
!ERROR: 'ip' may not have both the POINTER and PARAMETER attributes
2120
integer, parameter :: ip = 123
2221
pointer ip

0 commit comments

Comments
 (0)