Bug 59197 - An alias from an always_inline function causes inconsistent behavior
Summary: An alias from an always_inline function causes inconsistent behavior
Status: RESOLVED DUPLICATE of bug 46596
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 4.9.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-11-20 01:03 UTC by Andy Lutomirski
Modified: 2024-03-01 23:11 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2013-11-20 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Andy Lutomirski 2013-11-20 01:03:27 UTC
This program:

extern void func(void);
extern __inline __attribute__((__always_inline__)) __attribute__((__gnu_inline__)) void func(void) { }

extern void alias_target_func(void) {}
extern void func(void) __attribute__((alias("alias_target_func")));

extern void caller(void)
{
  func();
}

fails to compile on 4.7, 4.8, and trunk with -c -fPIC -O2, saying:

inline_alias.c: In function ‘caller’:
inline_alias.c:5:13: error: inlining failed in call to always_inline ‘func’: function body can be overwritten at link time
 extern void func(void) __attribute__((alias("alias_target_func")));
             ^
inline_alias.c:9:7: error: called from here
   func();
       ^

It compiles on an old copy of gcc 4.5 I have lying around, although I don't think I agree with the generated code.

gcc 4.5.1 (and gcc 4.8.2 with -O0) emit the call to func.  With the alias removed, the call to func is not emitted, even at -O0.  Oddly, without -fPIC, gcc 4.8 and trunk inline the call to func.

trunk's behavior with -O0 (w/o -fPIC) is even stranger: it emits a call to alias_target_func.  I can't reproduce that with other flags or on gcc 4.8.

I think that the correct behavior would be to either (a) reject the alias as a redefinition of func or (b) accept this code as valid and inline func.  Given the documented behavior for "extern __attribute__((gnu_inline))", the inline version of func should be used (or this code should be rejected outright).

This may be related to PR33763 or PR46596, but I don't think it's the same issue as either one, although the respective fixes could be involved in the behavior changes.

It came up in practice when openonload-201310 failed to build with _FORTIFY_SOURCE=2.
Comment 1 Richard Biener 2013-11-20 10:50:03 UTC
And with

extern void func(void);
extern void func(void) __attribute__((alias("alias_target_func")));

extern __inline __attribute__((__always_inline__)) __attribute__((__gnu_inline__)) void func(void) { }

extern void alias_target_func(void) {}

extern void caller(void)
{
    func();
}

you get

t.c:4:89: error: redefinition of 'func'
 extern __inline __attribute__((__always_inline__)) __attribute__((__gnu_inline__)) void func(void) { }
                                                                                         ^
t.c:2:13: note: previous definition of 'func' was here
 extern void func(void) __attribute__((alias("alias_target_func")));
             ^

even though I'd say that providing an extern inline definition should
still work?

But yeah, gnu extern inlines have interesting behavior...
Comment 2 Andrew Pinski 2024-03-01 23:09:39 UTC
Dup.
Comment 3 Andrew Pinski 2024-03-01 23:09:45 UTC
.

*** This bug has been marked as a duplicate of bug 46596 ***