https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93491
--- Comment #2 from Alexander Cherepanov <ch3root at openwall dot com> --- (In reply to Andrew Pinski from comment #1) > Const functions by definition dont trap or throw. They don't trap in all cases when they are really called. But this doesn't mean they must have a sane behavior for other combinations of arguments. At least that's what I got from the definition[1] of this attribute. In particular, it reads: "Declaring such functions with the const attribute allows GCC to avoid emitting some calls in repeated invocations of the function with the same argument values." That is, it allow gcc to eliminate some calls, but not to introduce new ones. But this is a gcc extension so it could be assigned any meaning that is seemed beneficial to gcc. In such a case this pr should be considered as a documentation clarification request. [1] https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-const-function-attribute > So adding const to a function that traps makes the testcase undefined. Let me describe the testcase like this: the function `g` is defined only for non-zero arguments, conforms to the rules of the const attribute for non-zero arguments, and is called only with non-zero arguments, but the optimizer introduces a call to it with the zero argument. Perhaps the minimized example that I posted looks weird. The situation could be more subtle in real life. For instance, the bad call could be due to an unitialized variable used as the argument. I mean this variable could be uninitialized only during speculative execution but perfectly initialized during ordinary execution. Or it could be something like this: ---------------------------------------------------------------------- #include <stdlib.h> #include <stdio.h> __attribute__((noipa)) void check_value(int x) { if (x == 0) { puts("Fatal error: got invalid value. Shutting down cleanly!"); exit(0); } } __attribute__((const,noipa)) int calc(int x) { return 1 / x; } int main(int c, char **v) { (void)v; int x = 0; // invalid value by default // some complex initialization of x that doesn't always succeed if (c > 5) x = 123; // etc. for (int i = 0; i < 10; i++) { check_value(x); printf("result = %d\n", calc(x)); } } ---------------------------------------------------------------------- $ gcc -std=c11 -pedantic -Wall -Wextra test.c && ./a.out Fatal error: got invalid value. Shutting down cleanly! $ gcc -std=c11 -pedantic -Wall -Wextra -O3 test.c && ./a.out Floating point exception ---------------------------------------------------------------------- gcc x86-64 version: gcc (GCC) 10.0.1 20200129 (experimental) ---------------------------------------------------------------------- Again, this doesn't mean that gcc have to support such use cases. > Do you have a testcase were gcc does this optimize without the user adding > const and still traps? No. I'll file a separate bug if I stumble upon one, so please disregard this possibility for now.