This is GCC Bugzilla
This is GCC Bugzilla Version 2.20+
View Bug Activity | Format For Printing | Clone This Bug
% cat mini.c typedef void (*mv_switch_mm)(); extern inline __attribute__ ((always_inline)) void ev5_switch_mm() {} extern inline __attribute__ ((always_inline)) void ev4_switch_mm() { ev5_switch_mm(); } mv_switch_mm eb164_mv = ev5_switch_mm; mv_switch_mm eb66p_mv = ev4_switch_mm; % gcc -c -O2 mini.c mini.c:10: error: Inlined_to pointer is set but no predecesors found ev5_switch_mm/0: (inline copy in ev4_switch_mm/1) needed always_inline called by: calls: mini.c:10: internal compiler error: verify_cgraph_node failed. Please submit a full bug report, with preprocessed source if appropriate. See <URL:http://gcc.gnu.org/bugs.html> for instructions.
Confirmed, an other unit-at-a-time problem.
Note that this is invalid code. You asking for an out-of-line copy of an always_inline function. We should have generated an error for you. Spank those kernel losers that keep mucking about with macro expanding inline, please. It won't work for the alpha kernel stuff that you're quoting here. Left open because we still shouldn't ICE.
The cgraph ICE has been fixed by my patch to mainline (so eventually propagated to tree-ssa). I am not sure about whether we really want to error out on requesting out of line copies of always_inline function, so i am keeping PR open. Doing so seems quite strict to me and I am not sure what kind of diagnostics we want (we might just output error when expand_function is invoked, but we also might want to get more infromative and check this on all cases such scenario can happen - taking pointer of static function, declaring function as global and such) Honza
Fixed.
This happens when compiling glibc-2.3.2's stdlib/atof.c for i686 as well. z.i:15: error: Inlined_to pointer is set but no predecesors found strtod/3: (inline copy in atof/2) 14 insns tree always_inline called by: calls: __strtod_internal/0 z.i:15: internal compiler error: verify_cgraph_node failed. To repeat: i686-unknown-linux-gnu-gcc -O -c z.i where z.i is: extern double strtod(__const char *__restrict __nptr, char **__restrict __endptr); extern double __strtod_internal(__const char *__restrict __nptr, char **__restrict __endptr, int __group); extern __inline double strtod(__const char *__restrict __nptr, char **__restrict __endptr) { return __strtod_internal(__nptr, __endptr, 0); } extern __inline double atof(__const char *__nptr) { return strtod(__nptr, (char **) ((void *) 0)); } double atof(const char *nptr) { return strtod(nptr, (char **) ((void *) 0)); }
I thought I had closed this as fixed, woops. Note that PR 15398 is for the glibc bug.
Richard, what's invalid about taking the address of the extern inline function? Wouldn't it be perfectly legitimate to have a non-`extern inline' definition in a separate translation unit, or even in the same translation unit, that would then be used? I'm actually not sure we should be merging inline-related attributes from extern inline definitions into out-of-line definitions. It seems to me that it would be more useful if we didn't. Not that it matters much. AFAICT, `extern inline' is a unofficially deprecated extension, and there's no way to obtain similar effect to what GCC currently supports, namely, defining the out-of-line version of a function in a translation unit that contains the extern inline definition as well.