For even more aggressiveness, try __attribute__((const)) which tells it that the func accesses NOTHING but the params, not even global vars. Of course this is quite limiting. You can also use this as a trick when YOU know that the only accessed global state is itself constant but gcc does not know that. This can produce substantial savings in number of calls of funcs that, for example, do lookups in large constant data tables, like table-based versions of sin() and cos().
In the example the article gives, adding __attribute__((pure)) to constFunc() does produce the behaviour author wanted and then some
LWN has more: https://lwn.net/Articles/285332/