Created attachment 58521 [details] A minimal working example of the access-to-subprogram check circumvention, ready for 'gnatchop' According to the Rationale for Ada 2005. 3.4 Downward closures [1], "[A]nonymous access to subprogram parameters /.../ do not carry an indication of the accessibility level of the actual parameter but simply treat it as if it were infinite (strictly – deeper than anything else). This of course prevents the conversion to the type APT and all is well; this is detected at compile time." However, if the 'access procedure' type (APT) is a field of a record, then a value of such field can be initialized using an anonymous access to procedure value, and later values of such record can be freely copied around, essentially circumventing the check mentioned in [1] and leading to programs that compile without warnings but have unpredictable behavior. NB: This is not the same as bug #84194; that one is fixed in the new compiler. Ref.: [1] Rationale for Ada 2005. 3.4 Downward closures. URL: https://www.adaic.org/resources/add_content/standards/05rat/html/Rat-3-4.html Below is the minimal working example ('minimal-working-example.ada') and a log demonstrating this situation: saulius@pterodaktilis minimal-working-example/ $ gnatchop -w minimal-working-example.ada splitting minimal-working-example.ada into: access_procedure_assignment.adb function_pointers.adb function_pointers.ads saulius@pterodaktilis minimal-working-example/ $ gnatmake -gnata access_procedure_assignment.adb gcc -c -gnata access_procedure_assignment.adb gcc -c -gnata function_pointers.adb gnatbind -x access_procedure_assignment.ali gnatlink access_procedure_assignment.ali # Expected behavior: gnat compiler preventing assignment of the 'Function_Pointer_Wrapper'; # Actuall behaviour: the program compiles without errors or warnings but crashes when run; the run-time behavior is unpredictable (from no error to STORAGE_ERROR to 'segfault', depending on what other code is added): saulius@pterodaktilis minimal-working-example/ $ ./access_procedure_assignment PP.PPtr (B), main scope, after calling 'Evil_Crasher': raised STORAGE_ERROR : stack overflow or erroneous memory access saulius@pterodaktilis minimal-working-example/ $ lsb_release -a No LSB modules are available. Distributor ID: Linuxmint Description: Linux Mint 21.2 Release: 21.2 Codename: victoria saulius@pterodaktilis minimal-working-example/ $ uname -a Linux pterodaktilis 5.15.0-112-generic #122-Ubuntu SMP Thu May 23 07:48:21 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux saulius@pterodaktilis minimal-working-example/ $ gcc -v Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/home/saulius/install/gcc/gcc-gnu-commit-7fada36c778/libexec/gcc/x86_64-pc-linux-gnu/15.0.0/lto-wrapper Target: x86_64-pc-linux-gnu Configured with: ../gcc/configure --prefix=/home/saulius/install/gcc/gcc-gnu-commit-7fada36c778 --enable-languages=c,c++,ada --disable-nls --disable-multilib --enable-shared --enable-threads=posix --enable-__cxa_atexit --enable-clocale=gnu Thread model: posix Supported LTO compression algorithms: zlib gcc version 15.0.0 20240626 (experimental) (GCC) saulius@pterodaktilis minimal-working-example/ $ gnat --version GNAT 15.0.0 20240626 (experimental) Copyright (C) 1996-2024, Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. saulius@pterodaktilis minimal-working-example/ $ which gnat /home/saulius/install/gcc/gcc-gnu-commit-7fada36c778/bin/gnat saulius@pterodaktilis minimal-working-example/ $ (cd ~/src/gcc; git remote -v) origin git://gcc.gnu.org/git/gcc.git (fetch) origin git://gcc.gnu.org/git/gcc.git (push) saulius@pterodaktilis minimal-working-example/ $ (cd ~/src/gcc; git log --oneline -1) 7fada36c778 (HEAD -> master, origin/trunk, origin/master, origin/HEAD) [aarch64] Add support for -mcpu=grace
Correction: the bug mentioned is https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84198 (not the bug #84194).
Confirmed, but nobody should write this sort of things.
Hi, Eric, thank you for updating the bug #115666 status! I am bit puzzled by your comment "nobody should write this sort of things". Could you please let me know in somewhat more detail what was wrong with my bug report? I am relatively new to GCC/GNAT Bugzilla, so I would like to avoid mistakes in the future :) Cheers, Saulius On 2024-06-27 13:45, ebotcazou at gcc dot gnu.org wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115666 > > Eric Botcazou <ebotcazou at gcc dot gnu.org> changed: > > What |Removed |Added > ---------------------------------------------------------------------------- > Ever confirmed|0 |1 > Status|UNCONFIRMED |NEW > CC| |ebotcazou at gcc dot gnu.org > Last reconfirmed| |2024-06-27 > > --- Comment #2 from Eric Botcazou <ebotcazou at gcc dot gnu.org> --- > Confirmed, but nobody should write this sort of things. > > -- > You are receiving this mail because: > You reported the bug. > You are on the CC list for the bug.
I probably should have said "but nobody should write this sort of code."
On 2024-06-27 13:58, ebotcazou at gcc dot gnu.org wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115666 > > --- Comment #5 from Eric Botcazou <ebotcazou at gcc dot gnu.org> --- > I probably should have said "but nobody should write this sort of code." > :D Thanks for the clarification! True enough, the code t is deliberately broken. I had to push hard to get MEMORY_ERROR out of the provided example. But if would be great of Ada compilers would warn us about the problems with the code. :) Regards, Saulius PS. Actually, I stumbled into the issue when applying in Ada program patterns which we regularly use in C (store a function pointer into a structure and call it later). For C, this is not a problem IMHO since C does not have nested functions. For Ada, this is clearly incorrect and bad design, but you only learn this after reading "Rationale for Ada 2005. 3.4". It would be great if GNAT informed it users about the buggy code, as it does now for the simpler case of 'access to procedure' variables.