-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[flang][Semantics] Introduce -Wpass-global-variable
warning
#160324
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
✅ With the latest revision this PR passed the C/C++ code formatter. |
flang/lib/Semantics/check-call.cpp
Outdated
if (const ArraySpec *dims{base->GetShape()}; | ||
dims && dims->IsExplicitShape()) { | ||
if (!((*dims)[0].lbound().GetExplicit() == (*dims)[0].ubound().GetExplicit())) { | ||
warn |= true; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@klausler, do you have an idea why base->GetShape()
returns nullptr
? It happens for variables defined in modules, but not for variables defined in common blocks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
llvm-project/flang/lib/Semantics/symbol.cpp
Line 453 in d79036c
const ArraySpec *Symbol::GetShape() const { |
This could be found by searching for GetShape path:flang path:symbol
within the repo. I use path:symbol because there were too many entries when I searched without it, and you were calling GetShape which seems to be a method of Symbols.
Based on the code, it returns nullptr when the symbol doesn't refer to a "object entity". I think this corresponds to "data entity" in the fortran '23 standard 5.4.3, which roughly corresponds to the notion of a value in general programming language theory (I think it specifically refers to the reference to a value). Not sure how familiar you are with fortran, but Fortran is weird in that the type system (and thus values) doesn't actually cover all "entities" that can be referenced in the syntax of the language. For instance functions can be referenced via symbols, but are not actually values (data entities) only their results are.
I don't understand what you're trying to do and I don't really have time to figure it out. |
warnUsage_.set(UsageWarning::HostAssociatedIntentOutInSpecExpr); | ||
warnUsage_.set(UsageWarning::NonVolatilePointerToVolatile); | ||
warnUsage_.set(UsageWarning::RealConstantWidening); | ||
warnUsage_.set(UsageWarning::PassGlobalVariable); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should definitely not be a warning enabled by default, and I probably wouldn't even want this one to fire with -Wall
, which leads to questions about how this should be implemented.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be nice to enable this warning with -Wall
. It helps to avoid global states. By default, I disabled this warning.
flang/lib/Semantics/check-call.cpp
Outdated
if (const ArraySpec *dims{base->GetShape()}; | ||
dims && dims->IsExplicitShape()) { | ||
if (!((*dims)[0].lbound().GetExplicit() == (*dims)[0].ubound().GetExplicit())) { | ||
warn |= true; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
llvm-project/flang/lib/Semantics/symbol.cpp
Line 453 in d79036c
const ArraySpec *Symbol::GetShape() const { |
This could be found by searching for GetShape path:flang path:symbol
within the repo. I use path:symbol because there were too many entries when I searched without it, and you were calling GetShape which seems to be a method of Symbols.
Based on the code, it returns nullptr when the symbol doesn't refer to a "object entity". I think this corresponds to "data entity" in the fortran '23 standard 5.4.3, which roughly corresponds to the notion of a value in general programming language theory (I think it specifically refers to the reference to a value). Not sure how familiar you are with fortran, but Fortran is weird in that the type system (and thus values) doesn't actually cover all "entities" that can be referenced in the syntax of the language. For instance functions can be referenced via symbols, but are not actually values (data entities) only their results are.
In fact, it depends on code. For MRCC, the most problematic code is full of these warnings (and not only this warning), while where I do not see this warning, we also do not have a bug with For GAMESS(US), the compilation log is full of |
d056747
to
6192c00
Compare
Yep, that was a problem. I had "use entity" which inside is an "object entity". But for "use entity", GetShape could not provide GetShape (while it can, actually). Now, it is fixed and my problem is gone. |
For some cases, it may lead to undefined behaviour. For example, for the following pieces of code (it violates Fortran standard): main.f90: program main
implicit none
common /mem/ imem
integer :: imem
imem = 0
call test(imem)
end program main
subroutine update_imem
implicit none
common /mem/ imem
integer :: imem
imem = 30
end subroutine update_imem test.f90:
No opts: $ flang test.f90 main.f90 -O0 -o a.exe && ./a.exe
0
30 With -O3:
With this PR, one gets: $ flang -Wpass-global-variable -fsyntax-only *.f90
./main.f90:6:13: warning: Passing global variable 'imem' from COMMON 'mem' as function argument [-Wpass-global-variable]
call test(imem)
^^^^
Now, it is not. I have reduced some possible invalid cases that, unfortunately, used a lot, but in general they should not give a problem. And in some valid contexts it also does not give warnings. I have played with GAMESS(US), MRCC and xtb and it does not give a lot of warnings. |
6192c00
to
39a63c8
Compare
In this PR, I've implemented detection of passing global variables defined in common blocks or/and modules in a bit naive way.
The main reason of implementing this that we have a lot of bugs with ifx compiler due extensively usage of passing all possible variables from common blocks to subroutines.
Sometimes, Fortran programs actively utilises passing of global variables in a valid context, especially for stack memory allocators (like in GAMESS(US) or MRCC or Gaussian). For such cases, I've excluded those warning:
allocatable
,pointer
orvolatile
parameter
orprivate
To reduce warnings in other codebases, extra limitations are also added:
See allowed cases in tests. However, some warning happens in already written tests.