aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--parse.c19
-rw-r--r--test.c2
-rw-r--r--type.c4
3 files changed, 23 insertions, 2 deletions
diff --git a/parse.c b/parse.c
index 228f6c8..dc6717b 100644
--- a/parse.c
+++ b/parse.c
@@ -593,6 +593,17 @@ callexpr(struct parser *pr, const struct span *span_, const struct expr *callee)
bool spanok = joinspan(&span.ex, span_->ex);
bool printsig = 0;
+ if (callee->t == ESYM && !callee->ty.t) { /* implicit function decl.. */
+ const char *name = (void *)callee->sym;
+ struct decl decl = {
+ ty = mkfntype(mktype(TYINT), 0, NULL, NULL, /* kandr */ 1, 0),
+ .scls = SCEXTERN, .span = callee->span, .name = name
+ };
+ (ccopt.cstd > STDC89 ? error : warn)(&callee->span, "call to undeclared function '%s'", name);
+ ((struct expr *)callee)->sym = putdecl(pr, &decl);
+ td = &typedata[ty.dat];
+ }
+
if (ty.t == TYPTR) /* auto-deref when calling a function pointer */
ty = typechild(ty);
if (ty.t != TYFUNC) error(&callee->span, "calling a value of type '%ty'", callee->ty);
@@ -693,8 +704,12 @@ Unary:
case TKIDENT:
decl = finddecl(pr, tk.s);
if (!decl) {
- error(&tk.span, "undeclared identifier %'tk", &tk);
- ex = mkexpr(ESYM, tk.span, mktype(TYINT), .sym = NULL);
+ if (lexpeek(pr, NULL) == '(') { /* implicit function decl? */
+ ex = mkexpr(ESYM, tk.span, mktype(0), .sym = (void *)tk.s);
+ } else {
+ error(&tk.span, "undeclared identifier %'tk", &tk);
+ ex = mkexpr(ESYM, tk.span, mktype(TYINT), .sym = NULL);
+ }
} else if (decl->scls == SCTYPEDEF) {
error(&tk.span, "unexpected typename %'tk (expected expression)", &tk);
ex = mkexpr(ESYM, tk.span, decl->ty, .sym = NULL);
diff --git a/test.c b/test.c
index a2a1a7c..670c7c6 100644
--- a/test.c
+++ b/test.c
@@ -62,5 +62,7 @@ void fill(char *p, int c, unsigned long n)
if (n) do t = *p++ = c; while (--n);
}
+main(t) { putc(t); }
+
//
diff --git a/type.c b/type.c
index 798994d..c698817 100644
--- a/type.c
+++ b/type.c
@@ -8,6 +8,7 @@ static ushort
hashtd(const struct typedata *td)
{
uint h = td->t*33;
+ bool t;
switch (td->t) {
case TYARRAY:
h = hashb(h, &td->arrlen, sizeof td->arrlen);
@@ -23,6 +24,8 @@ hashtd(const struct typedata *td)
case TYFUNC:
h = hashb(h, &td->ret, sizeof td->ret);
h = hashb(h, &td->nmemb, sizeof td->nmemb);
+ h = hashb(h, (t = td->kandr, &t), sizeof t);
+ h = hashb(h, (t = td->variadic, &t), sizeof t);
for (int i = 0; i < td->nmemb; ++i) {
uchar q = tdgetqual(td->quals, i);
h = hashb(h, &td->param[i], sizeof *td->param);
@@ -52,6 +55,7 @@ tdequ(const struct typedata *a, const struct typedata *b)
if (a->ret.bits != b->ret.bits) return 0;
if (a->nmemb != b->nmemb) return 0;
if (a->variadic != b->variadic) return 0;
+ if (a->kandr != b->kandr) return 0;
for (int i = 0; i < a->nmemb; ++i) {
if (!a->quals != !b->quals || a->param[i].bits != b->param[i].bits)
return 0;