https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95631
Bug ID: 95631 Summary: Unable to redefine a literal with `-std=legacy' Product: gcc Version: 11.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: fortran Assignee: unassigned at gcc dot gnu.org Reporter: ma...@linux-mips.org Target Milestone: --- This is an interesting one. This was mentioned by Eric Korpela here: <http://www.classiccmp.org/pipermail/cctalk/2020-May/053704.html> as a language peculiarity of up to at least FORTRAN 77. Which is given the following program: C C CHANGE THE VALUE OF 4 C CALL INC(4) WRITE (*, 30) 4 30 FORMAT ('2+2=',I4) END SUBROUTINE INC(I) I = I + 1 END the supposed output is: 2+2= 5 Eric says: 'Most languages will give you some way to shoot yourself in the foot. The question is how much work do you need to do? In FORTRAN the easiest method was changing the value of a literal in a subroutine call. It is standard compliant behavior that goes back to at least FORTRAN IV. Current compliers and converters go to pains to make sure it still happens. Not sure if it is still present in f90 and beyond. At least modern compilers for other languages will give you a "potential foot shooting warning", although in C++ that warning statement could take 200 kB.' However when this program is built with GCC like this and run on an `x86_64-linux-gnu' system, it causes SIGSEGV at the incrementation: $ gfortran -Wall -W -Wextra -pedantic -std=legacy -O2 -g -o four four.f $ ./four Program received signal SIGSEGV: Segmentation fault - invalid memory reference. Backtrace for this error: #0 0x7f0e8c9f5b90 in ??? #1 0x7f0e8c9f4dc5 in ??? #2 0x7f0e8c66683f in ??? #3 0x4011b1 in inc_ at /home/macro/src/four.f:11 #4 0x4011b1 in MAIN__ at /home/macro/src/four.f:5 #5 0x40109c in main at /home/macro/src/four.f:8 $ The reason is the literal to be incremented (4) has been assigned to `.rodata'. There is no warning issued with the compilation either. Conversely with the `riscv64-linux-gnu' target the literal gets assigned to `.sdata' and the program executes as expected: $ ./four 2+2= 5 $ but I take it it is by chance rather than design (no `.srodata' has been defined, for obvious reasons). My Fortran experience is so-so, but I did some language standard examination and indeed it says something like: "INTENT (INOUT) is not equivalent to omitting the INTENT attribute. The argument corresponding to an INTENT (INOUT) dummy argument always shall be definable, while an argument corresponding to a dummy argument without an INTENT attribute need be definable only if the dummy argument is actually redefined." which essentially means that the actual argument associated with I in the call to INC here has to be a variable rather than a literal. My understanding however is we still intend to support peculiar old programs if built with the `-std=legacy' level. If not, then perhaps we ought to at least give that "potential foot shooting warning" Eric talks about?