cproc

Unnamed repository; edit this file 'description' to name the repository.
git clone git://git.nihaljere.xyz/cproc
Log | Files | Refs | Submodules | README | LICENSE

commit 5b575aa2e3e42085d9087210b41560cf5849c746
parent 3849dd77204177fce2568b5bbace6e400c6a6064
Author: Michael Forney <mforney@mforney.org>
Date:   Thu, 30 Jan 2020 13:53:18 -0800

decl: Better check for inline definitions

Diffstat:
Mcc.h | 3+++
Mdecl.c | 3++-
Atest/inline-definition.c | 7+++++++
Atest/inline-definition.qbe | 6++++++
4 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/cc.h b/cc.h @@ -262,6 +262,9 @@ struct decl { /* alignment of object storage (may be stricter than type requires) */ int align; + /* the function might have an "inline definition" (C11 6.7.4p7) */ + _Bool inlinedefn; + enum builtinkind builtin; }; diff --git a/decl.c b/decl.c @@ -994,6 +994,7 @@ decl(struct scope *s, struct func *f) } } d = declcommon(s, kind, name, asmname, t, tq, sc, prior); + d->inlinedefn = d->linkage == LINKEXTERN && fs & FUNCINLINE && !(sc & SCEXTERN) && (!prior || prior->inlinedefn); if (tok.kind == TLBRACE) { if (!allowfunc) error(&tok.loc, "function definition not allowed"); @@ -1003,7 +1004,7 @@ decl(struct scope *s, struct func *f) f = mkfunc(d, name, t, s); stmt(f, s); /* XXX: need to keep track of function in case a later declaration specifies extern */ - if (!(fs & FUNCINLINE) || sc) + if (!d->inlinedefn) emitfunc(f, d->linkage == LINKEXTERN); s = delscope(s); delfunc(f); diff --git a/test/inline-definition.c b/test/inline-definition.c @@ -0,0 +1,7 @@ +extern void f(void); + +/* +f is not an inline definition, due to the preceeding declaration, +so we *should* emit an external definition for it. +*/ +inline void f(void) {} diff --git a/test/inline-definition.qbe b/test/inline-definition.qbe @@ -0,0 +1,6 @@ +export +function $f() { +@start.1 +@body.2 + ret +}