scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

commit e6ddda1e88b759c40880707accff6a8f3340ee3c
parent 30f4972a841a70650813e929c990e2ae724f355c
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Thu, 23 Mar 2023 18:00:53 +0100

cc1: Add support for __func__ variable

__func__ is a variable with the name of the current function
and only can be used inside of functions and we take the
decision of giving an error when it is redefined in any way,
that is a valid behaviour since the standard defines this
situation as undefined behaviour.

Diffstat:
Msrc/cmd/cc/cc1/decl.c | 5+++++
Msrc/cmd/cc/cc1/expr.c | 21++++++++++++++++++++-
Atests/cc/error/0036-func.c | 13+++++++++++++
Mtests/cc/error/scc-tests.lst | 1+
Atests/cc/execute/0225-func.c | 12++++++++++++
Mtests/cc/execute/scc-tests.lst | 1+
6 files changed, 52 insertions(+), 1 deletion(-)

diff --git a/src/cmd/cc/cc1/decl.c b/src/cmd/cc/cc1/decl.c @@ -272,6 +272,9 @@ identifier(struct decl *dcl) } } + if (strcmp(name, "__func__") == 0) + errorp("__func__ is a reserved variable name"); + if (sym->flags & SDECLARED) { sym = redcl(dcl->sym, tp, sclass); } else { @@ -363,6 +366,8 @@ parameter(struct decl *dcl) sym->name); return NULL; } + if (strcmp(name, "__func__") == 0) + errorp("__func__ is a reserved variable name"); sym->flags |= SDECLARED; } diff --git a/src/cmd/cc/cc1/expr.c b/src/cmd/cc/cc1/expr.c @@ -674,6 +674,23 @@ adjstrings(Symbol *sym) return sym; } +static Node * +funcsym(Symbol *sym) +{ + char *s; + Node *np; + + sym = install(sym->ns, sym); + s = curfun->name; + np = constnode(newstring(s, strlen(s)+1)); + sym->type = np->type; + sym->flags |= SHASINIT | SLOCAL | SUSED; + emit(ODECL, sym); + emit(OINIT, np); + + return varnode(sym); +} + /************************************************************* * grammar functions * *************************************************************/ @@ -721,10 +738,12 @@ primary(void) np = varnode(sym); } else if (namespace == NS_CPP) { np = constnode(zero); + } else if (!strcmp(yytext, "__func__") && curctx > PARAMCTX) { + np = funcsym(sym); } else { errorp("'%s' undeclared", yytext); sym->type = inttype; - sym = install(sym->ns, yylval.sym); + sym = install(sym->ns, sym); sym->flags |= SUSED; np = varnode(sym); } diff --git a/tests/cc/error/0036-func.c b/tests/cc/error/0036-func.c @@ -0,0 +1,13 @@ +/* +PATTERN: +0036-func.c:8: error: __func__ is a reserved variable name +0036-func.c:10: error: __func__ is a reserved variable name +0036-func.c:13: warning: '__func__' defined but not used +. +*/ +int __func__; + +int foo(int __func__) +{ + return 0; +} diff --git a/tests/cc/error/scc-tests.lst b/tests/cc/error/scc-tests.lst @@ -33,3 +33,4 @@ 0033-character.c 0034-eof.c 0035-cpp.c +0036-func.c diff --git a/tests/cc/execute/0225-func.c b/tests/cc/execute/0225-func.c @@ -0,0 +1,12 @@ +int +main(void) +{ + char *p = __func__; + int i; + + for (i = 0; i < sizeof(__func__); i++) { + if (p[i] != "main"[i]) + return 1; + } + return 0; +} diff --git a/tests/cc/execute/scc-tests.lst b/tests/cc/execute/scc-tests.lst @@ -215,3 +215,4 @@ 0222-ifdef.c 0223-macro.c 0224-macro.c +0225-func.c