Skip to content

Commit d53f48b

Browse files
committed
Full implementation of -Wpass-global-varialbe for explicit interfaces
1 parent 0daa60d commit d53f48b

File tree

1 file changed

+57
-0
lines changed

1 file changed

+57
-0
lines changed

flang/lib/Semantics/check-call.cpp

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1137,6 +1137,63 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
11371137
messages.Say(
11381138
"%VAL argument must be a scalar numeric or logical expression"_err_en_US);
11391139
}
1140+
1141+
// passing global variables
1142+
if (actualFirstSymbol) {
1143+
bool warn{false};
1144+
std::string ownerType{""};
1145+
std::string ownerName{""};
1146+
if (actualFirstSymbol->flags().test(Symbol::Flag::InCommonBlock)) {
1147+
const Symbol *common{FindCommonBlockContaining(*actualFirstSymbol)};
1148+
ownerType = "COMMON";
1149+
ownerName = common->name().ToString();
1150+
if (!(actualFirstSymbol->Rank() == 1 && actualFirstSymbol->offset() == 0)) {
1151+
warn |= true;
1152+
} else if (actualFirstSymbol->Rank() == 1) {
1153+
bool actualIsArrayElement{IsArrayElement(actual) != nullptr};
1154+
if (!actualIsArrayElement) {
1155+
warn |= true;
1156+
}
1157+
if (const ArraySpec *dims{actualFirstSymbol->GetShape()};
1158+
dims && dims->IsExplicitShape()) {
1159+
if (!((*dims)[0].lbound().GetExplicit() == (*dims)[0].ubound().GetExplicit())) {
1160+
warn |= true;
1161+
}
1162+
}
1163+
if (common->get<CommonBlockDetails>().objects().size() > 1) {
1164+
warn |= true;
1165+
}
1166+
}
1167+
} else if (const auto &owner{actualFirstSymbol->GetUltimate().owner()};
1168+
owner.IsModule() || owner.IsSubmodule()) {
1169+
const Scope *module{FindModuleContaining(owner)};
1170+
ownerType = "MODULE";
1171+
ownerName = module->GetName()->ToString();
1172+
if (actualFirstSymbol->attrs().test(Attr::PARAMETER)) {
1173+
warn |= false;
1174+
} else if (actualFirstSymbol->Rank() != 1) {
1175+
warn |= true;
1176+
} else if (!actualFirstSymbol->attrs().test(Attr::ALLOCATABLE) &&
1177+
!actualFirstSymbol->attrs().test(Attr::POINTER) &&
1178+
!actualFirstSymbol->attrs().test(Attr::VOLATILE)) {
1179+
bool actualIsArrayElement{IsArrayElement(actual) != nullptr};
1180+
if (!actualIsArrayElement) {
1181+
warn |= true;
1182+
}
1183+
if (const ArraySpec *dims{actualFirstSymbol->GetShape()};
1184+
dims && dims->IsExplicitShape()) {
1185+
if (!((*dims)[0].lbound().GetExplicit() == (*dims)[0].ubound().GetExplicit())) {
1186+
warn |= true;
1187+
}
1188+
}
1189+
}
1190+
}
1191+
if (warn) {
1192+
context.Warn(common::UsageWarning::PassGlobalVariable, messages.at(),
1193+
"Passing global variable '%s' from %s '%s' as function argument"_warn_en_US,
1194+
actualFirstSymbol->name(), ownerType, ownerName);
1195+
}
1196+
}
11401197
}
11411198

11421199
static void CheckProcedureArg(evaluate::ActualArgument &arg,

0 commit comments

Comments
 (0)