diff options
| -rw-r--r-- | parse.c | 19 | ||||
| -rw-r--r-- | test.c | 2 | ||||
| -rw-r--r-- | type.c | 4 |
3 files changed, 23 insertions, 2 deletions
@@ -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); @@ -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); } + // @@ -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; |