https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105676

            Bug ID: 105676
           Summary: Bogus `-Wsuggest-attribute=pure` on function marked
                    `__attribute__((const))`
           Product: gcc
           Version: 12.1.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: sagebar at web dot de
  Target Milestone: ---

When compiling with `-Wsuggest-attribute=pure`, gcc warns about missing
`__attribute__((pure))` on functions declared as `__attribute__((const))`.

It is common knowledge that any function marked as `__attribute__((const))`
also implicitly has the behavior of a function marked as
`__attribute__((pure))` (const implies pure).

Therefor, it stands to reason that such a warning is bogus (also: earlier
version of gcc didn't emit a warning in this case; know: gcc-9 already
supported these warnings, but didn't emit `-Wsuggest-attribute=pure` on a
`__attribute__((const))` function).

Example (`gcc -Wsuggest-attribute=pure -c -O2 input.c`):

```
__attribute__((const))
extern int do_expensive_calculation(void);

__attribute__((const))
int getval(void) {
        static int cache = -1;
        if (cache == -1)
                cache = do_expensive_calculation();
        return cache;
}
```

>test.c: In function 'getval':
>test.c:5:5: warning: function might be candidate for attribute 'pure' 
>>[-Wsuggest-attribute=pure]
>    5 | int getval(void) {
>      |     ^~~~~~

When trying to declare as both pure+const:
>test.c:5:1: warning: ignoring attribute 'const' because it conflicts with 
>attribute 'pure' [-Wattributes]
>    5 | int getval(void) {
>      | ^~~


==== Explaination of why using `__attribute__((const))` is valid here ====

I see why gcc might think that `getval()` is *only* `pure`, but there is
nothing wrong with the `__attribute__((const))` annotation since we don't "read
global memory" (emphasis on the "global"), and thus don't depend on the global
state (also: what counts as "global" vs. "non-global" isn't something that can
be quantified. - It depends on the application and how memory is used).

As such, the use of `__attribute__((const))` is very much valid (and gcc might
even consider suggesting `__attribute__((const))` instead of
`__attribute__((pure))`, since because `cache` is scoped-static, it not being
used outside of `getval()` can actually be proven, though that isn't what this
bug report is about...). However, so-long as it believes that the function is
pure, there is no reason to ever emit a about that fact so-long as `getval()`
remains annotated as `__attribute__((const))`.

==== End of Explaination ====

Reply via email to