Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extern inline prototypes should not replace definitions #14

Open
stephenrkell opened this issue Jul 19, 2014 · 0 comments
Open

Extern inline prototypes should not replace definitions #14

stephenrkell opened this issue Jul 19, 2014 · 0 comments

Comments

@stephenrkell
Copy link
Contributor

Currently CIL is defeated by always_inline extern inline functions whose prototypes are repeated after their definition (but before their use).

$ cat vminimal.i
extern void f(void);
extern inline __attribute__((always_inline)) void g()
{
        f();
}

extern inline __attribute__((always_inline)) void g();

void v(void)
{
        g();
}

$ cc -c -o vminimal.o vminimal.i
$ cilly -c -o vminimal.o vminimal.i

vminimal.i: In function ‘v’:
vminimal.i:2:59: error: inlining failed in call to always_inline ‘g’: function body not available
 extern inline __attribute__((always_inline)) void g()
                                                           ^
vminimal.i:11:3: error: called from here
  g();
   ^

The following patch fixes things for me. (I'll forward it by e-mail too, since GitHub doesn't let me attach it.)

diff --git a/src/frontc/cabs2cil.ml b/src/frontc/cabs2cil.ml
index dc185e1..30633c6 100644
--- a/src/frontc/cabs2cil.ml
+++ b/src/frontc/cabs2cil.ml
@@ -1792,7 +1792,7 @@ let makeGlobalVarinfo (isadef: bool) (vi: varinfo) : varinfo * bool =

     (* New-style extern inline handling: the real definition replaces the extern
        inline one *)
-    if (not !Cil.oldstyleExternInline) && oldvi.vstorage = Extern && oldvi.vinline then begin
+    if (not !Cil.oldstyleExternInline) && oldvi.vstorage = Extern && oldvi.vinline && isadef then begin
       H.remove alreadyDefined oldvi.vname;
       theFile := Util.list_map (fun g -> match g with
           | GFun (fi, l) when fi.svar == oldvi -> GVarDecl(fi.svar, l)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant