@@ -56,9 +56,64 @@ static void CheckImplicitInterfaceArg(evaluate::ActualArgument &arg,
56
56
" %VAL argument must be a scalar numeric or logical expression" _err_en_US);
57
57
}
58
58
if (const auto *expr{arg.UnwrapExpr ()}) {
59
- if (const Symbol * base{GetFirstSymbol (*expr)};
60
- base && IsFunctionResult (*base)) {
61
- context.NoteDefinedSymbol (*base);
59
+ if (const Symbol * base{GetFirstSymbol (*expr)}) {
60
+ if (IsFunctionResult (*base)) {
61
+ context.NoteDefinedSymbol (*base);
62
+ } else {
63
+ // passing global variables
64
+ // here, arrays with subscripts are processing
65
+ bool warn{false };
66
+ std::string ownerName{" " };
67
+ std::string ownerType{" " };
68
+ if (base->flags ().test (Symbol::Flag::InCommonBlock)) {
69
+ const Symbol *common{FindCommonBlockContaining (*base)};
70
+ ownerType = " COMMON" ;
71
+ ownerName = common->name ().ToString ();
72
+ if (!(base->Rank () == 1 && base->offset () == 0 )) {
73
+ warn |= true ;
74
+ } else if (base->Rank () == 1 ) {
75
+ if (const ArraySpec *dims{base->GetShape ()};
76
+ dims && dims->IsExplicitShape ()) {
77
+ if (!((*dims)[0 ].lbound ().GetExplicit () == (*dims)[0 ].ubound ().GetExplicit ())) {
78
+ warn |= true ;
79
+ }
80
+ }
81
+ if (common->get <CommonBlockDetails>().objects ().size () > 1 ) {
82
+ warn |= true ;
83
+ }
84
+ }
85
+ } else if (const auto &owner{base->GetUltimate ().owner ()};
86
+ owner.IsModule () || owner.IsSubmodule ()) {
87
+ const Scope *module {FindModuleContaining (owner)};
88
+ ownerType = " MODULE" ;
89
+ ownerName = module ->GetName ()->ToString ();
90
+ if (base->attrs ().test (Attr::PARAMETER)) {
91
+ warn |= false ;
92
+ } else if (base->Rank () != 1 ) {
93
+ warn |= true ;
94
+ } else if (!base->attrs ().test (Attr::ALLOCATABLE) &&
95
+ !base->attrs ().test (Attr::POINTER) &&
96
+ !base->attrs ().test (Attr::VOLATILE)) {
97
+ // by some reason, dims is not constructed here. For common blocks' variables, it works
98
+ // it leads to three skipped tests
99
+ /*
100
+ if (const ArraySpec *dims{base->GetShape()};
101
+ dims && dims->IsExplicitShape()) {
102
+ if (!((*dims)[0].lbound().GetExplicit() == (*dims)[0].ubound().GetExplicit())) {
103
+ warn |= true;
104
+ }
105
+ }
106
+ */
107
+ // just give some warnings in code where modules and implicit interfaces are mixed
108
+ warn |= true ;
109
+ }
110
+ }
111
+ if (warn) {
112
+ context.Warn (common::UsageWarning::PassGlobalVariable, messages.at (),
113
+ " Passing global variable '%s' from %s '%s' as function argument" _warn_en_US,
114
+ base->name (), ownerType, ownerName);
115
+ }
116
+ }
62
117
}
63
118
if (IsBOZLiteral (*expr)) {
64
119
messages.Say (" BOZ argument requires an explicit interface" _err_en_US);
@@ -79,6 +134,36 @@ static void CheckImplicitInterfaceArg(evaluate::ActualArgument &arg,
79
134
messages.Say (
80
135
" VOLATILE argument requires an explicit interface" _err_en_US);
81
136
}
137
+ // passing global variables
138
+ // here, scalars and arrays without subscripts are processing
139
+ bool warn{false };
140
+ std::string ownerName{" " };
141
+ std::string ownerType{" " };
142
+ if (symbol.flags ().test (Symbol::Flag::InCommonBlock)) {
143
+ const Symbol *common{FindCommonBlockContaining (symbol)};
144
+ ownerType = " COMMON" ;
145
+ ownerName = common->name ().ToString ();
146
+ warn |= true ;
147
+ } else if (const auto & owner{symbol.GetUltimate ().owner ()};
148
+ owner.IsModule () || owner.IsSubmodule ()) {
149
+ const Scope *module {FindModuleContaining (owner)};
150
+ ownerType = " MODULE" ;
151
+ ownerName = module ->GetName ()->ToString ();
152
+ if (symbol.attrs ().test (Attr::PARAMETER)) {
153
+ warn |= false ;
154
+ } else if (symbol.Rank () != 1 ) {
155
+ warn |= true ;
156
+ } else if (!symbol.attrs ().test (Attr::ALLOCATABLE) &&
157
+ !symbol.attrs ().test (Attr::POINTER) &&
158
+ !symbol.attrs ().test (Attr::VOLATILE)) {
159
+ warn |= true ;
160
+ }
161
+ }
162
+ if (warn) {
163
+ context.Warn (common::UsageWarning::PassGlobalVariable, messages.at (),
164
+ " Passing global variable '%s' from %s '%s' as function argument" _warn_en_US,
165
+ symbol.name (), ownerType, ownerName);
166
+ }
82
167
} else if (auto argChars{characteristics::DummyArgument::FromActual (
83
168
" actual argument" , *expr, context.foldingContext (),
84
169
/* forImplicitInterface=*/ true )}) {
0 commit comments