dpchk.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440
  1. #include "cc.h"
  2. #include "y.tab.h"
  3. enum
  4. {
  5. Fnone = 0,
  6. Fl,
  7. Fvl,
  8. Fignor,
  9. Fstar,
  10. Fadj,
  11. Fverb = 10,
  12. };
  13. typedef struct Tprot Tprot;
  14. struct Tprot
  15. {
  16. Type* type;
  17. Bits flag;
  18. Tprot* link;
  19. };
  20. typedef struct Tname Tname;
  21. struct Tname
  22. {
  23. char* name;
  24. int param;
  25. Tname* link;
  26. };
  27. static Type* indchar;
  28. static uchar flagbits[512];
  29. static char fmtbuf[100];
  30. static int lastadj;
  31. static int lastverb;
  32. static int nstar;
  33. static Tprot* tprot;
  34. static Tname* tname;
  35. void
  36. argflag(int c, int v)
  37. {
  38. switch(v) {
  39. case Fignor:
  40. case Fstar:
  41. case Fl:
  42. case Fvl:
  43. flagbits[c] = v;
  44. break;
  45. case Fverb:
  46. flagbits[c] = lastverb;
  47. //print("flag-v %c %d\n", c, lastadj);
  48. lastverb++;
  49. break;
  50. case Fadj:
  51. flagbits[c] = lastadj;
  52. //print("flag-l %c %d\n", c, lastadj);
  53. lastadj++;
  54. break;
  55. }
  56. }
  57. Bits
  58. getflag(char *s)
  59. {
  60. Bits flag;
  61. int f;
  62. char *fmt;
  63. Rune c;
  64. fmt = fmtbuf;
  65. flag = zbits;
  66. nstar = 0;
  67. for(;;) {
  68. s += chartorune(&c, s);
  69. if(c == 0 || c >= nelem(flagbits))
  70. break;
  71. fmt += runetochar(fmt, &c);
  72. f = flagbits[c];
  73. switch(f) {
  74. case Fnone:
  75. argflag(c, Fverb);
  76. f = flagbits[c];
  77. break;
  78. case Fstar:
  79. nstar++;
  80. case Fignor:
  81. continue;
  82. case Fl:
  83. if(bset(flag, Fl))
  84. flag = bor(flag, blsh(Fvl));
  85. }
  86. flag = bor(flag, blsh(f));
  87. if(f >= Fverb)
  88. break;
  89. }
  90. *fmt = 0;
  91. return flag;
  92. }
  93. void
  94. newprot(Sym *m, Type *t, char *s)
  95. {
  96. Bits flag;
  97. Tprot *l;
  98. if(t == T) {
  99. warn(Z, "%s: newprot: type not defined", m->name);
  100. return;
  101. }
  102. flag = getflag(s);
  103. for(l=tprot; l; l=l->link)
  104. if(beq(flag, l->flag) && sametype(t, l->type))
  105. return;
  106. l = alloc(sizeof(*l));
  107. l->type = t;
  108. l->flag = flag;
  109. l->link = tprot;
  110. tprot = l;
  111. }
  112. void
  113. newname(char *s, int p)
  114. {
  115. Tname *l;
  116. for(l=tname; l; l=l->link)
  117. if(strcmp(l->name, s) == 0) {
  118. if(l->param != p)
  119. yyerror("vargck %s already defined\n", s);
  120. return;
  121. }
  122. l = alloc(sizeof(*l));
  123. l->name = s;
  124. l->param = p;
  125. l->link = tname;
  126. tname = l;
  127. }
  128. void
  129. arginit(void)
  130. {
  131. int i;
  132. // debug['F'] = 1;
  133. // debug['w'] = 1;
  134. lastadj = Fadj;
  135. lastverb = Fverb;
  136. indchar = typ(TIND, types[TCHAR]);
  137. memset(flagbits, Fnone, sizeof(flagbits));
  138. for(i='0'; i<='9'; i++)
  139. argflag(i, Fignor);
  140. argflag('.', Fignor);
  141. argflag('#', Fignor);
  142. argflag('u', Fignor);
  143. argflag('+', Fignor);
  144. argflag('-', Fignor);
  145. argflag('*', Fstar);
  146. argflag('l', Fl);
  147. argflag('o', Fverb);
  148. flagbits['x'] = flagbits['o'];
  149. flagbits['X'] = flagbits['o'];
  150. }
  151. void
  152. pragvararg(void)
  153. {
  154. Sym *s;
  155. int n, c;
  156. char *t;
  157. Rune r;
  158. Type *ty;
  159. if(!debug['F'])
  160. goto out;
  161. s = getsym();
  162. if(s && strcmp(s->name, "argpos") == 0)
  163. goto ckpos;
  164. if(s && strcmp(s->name, "type") == 0)
  165. goto cktype;
  166. if(s && strcmp(s->name, "flag") == 0)
  167. goto ckflag;
  168. yyerror("syntax in #pragma varargck");
  169. goto out;
  170. ckpos:
  171. //#pragma varargck argpos warn 2
  172. s = getsym();
  173. if(s == S)
  174. goto bad;
  175. n = getnsn();
  176. if(n < 0)
  177. goto bad;
  178. newname(s->name, n);
  179. goto out;
  180. ckflag:
  181. //#pragma varargck flag 'c'
  182. c = getnsc();
  183. if(c != '\'')
  184. goto bad;
  185. c = getr();
  186. if(c == '\\')
  187. c = getr();
  188. else if(c == '\'')
  189. goto bad;
  190. if(c == '\n')
  191. goto bad;
  192. if(getc() != '\'')
  193. goto bad;
  194. argflag(c, Fignor);
  195. goto out;
  196. cktype:
  197. //#pragma varargck type O int
  198. c = getnsc();
  199. if(c != '"')
  200. goto bad;
  201. t = fmtbuf;
  202. for(;;) {
  203. r = getr();
  204. if(r == ' ' || r == '\n')
  205. goto bad;
  206. if(r == '"')
  207. break;
  208. t += runetochar(t, &r);
  209. }
  210. *t = 0;
  211. t = strdup(fmtbuf);
  212. s = getsym();
  213. if(s == S)
  214. goto bad;
  215. ty = s->type;
  216. while((c = getnsc()) == '*')
  217. ty = typ(TIND, ty);
  218. unget(c);
  219. newprot(s, ty, t);
  220. goto out;
  221. bad:
  222. yyerror("syntax in #pragma varargck");
  223. out:
  224. while(getnsc() != '\n')
  225. ;
  226. }
  227. Node*
  228. nextarg(Node *n, Node **a)
  229. {
  230. if(n == Z) {
  231. *a = Z;
  232. return Z;
  233. }
  234. if(n->op == OLIST) {
  235. *a = n->left;
  236. return n->right;
  237. }
  238. *a = n;
  239. return Z;
  240. }
  241. void
  242. checkargs(Node *nn, char *s)
  243. {
  244. Node *a, *n;
  245. Bits flag;
  246. Tprot *l;
  247. if(!debug['F'])
  248. return;
  249. n = nn;
  250. for(;;) {
  251. s = strchr(s, '%');
  252. if(s == 0) {
  253. nextarg(n, &a);
  254. if(a != Z)
  255. warn(nn, "more arguments than format %T",
  256. a->type);
  257. return;
  258. }
  259. s++;
  260. flag = getflag(s);
  261. while(nstar > 0) {
  262. n = nextarg(n, &a);
  263. nstar--;
  264. if(a == Z) {
  265. warn(nn, "more format than arguments %s",
  266. fmtbuf);
  267. return;
  268. }
  269. if(a->type == T)
  270. continue;
  271. if(!sametype(types[TINT], a->type) &&
  272. !sametype(types[TUINT], a->type))
  273. warn(nn, "format mismatch '*' in %s %T",
  274. fmtbuf, a->type);
  275. }
  276. for(l=tprot; l; l=l->link)
  277. if(sametype(types[TVOID], l->type)) {
  278. if(beq(flag, l->flag)) {
  279. s++;
  280. goto loop;
  281. }
  282. }
  283. n = nextarg(n, &a);
  284. if(a == Z) {
  285. warn(nn, "more format than arguments %s",
  286. fmtbuf);
  287. return;
  288. }
  289. if(a->type == 0)
  290. continue;
  291. for(l=tprot; l; l=l->link)
  292. if(sametype(a->type, l->type)) {
  293. //print("checking %T/%ulx %T/%ulx\n", a->type, flag.b[0], l->type, l->flag.b[0]);
  294. if(beq(flag, l->flag))
  295. goto loop;
  296. }
  297. warn(nn, "format mismatch %s %T", fmtbuf, a->type);
  298. loop:;
  299. }
  300. }
  301. void
  302. dpcheck(Node *n)
  303. {
  304. char *s;
  305. Node *a, *b;
  306. Tname *l;
  307. int i;
  308. if(n == Z)
  309. return;
  310. b = n->left;
  311. if(b == Z || b->op != ONAME)
  312. return;
  313. s = b->sym->name;
  314. for(l=tname; l; l=l->link)
  315. if(strcmp(s, l->name) == 0)
  316. break;
  317. if(l == 0)
  318. return;
  319. i = l->param;
  320. b = n->right;
  321. while(i > 0) {
  322. b = nextarg(b, &a);
  323. i--;
  324. }
  325. if(a == Z) {
  326. warn(n, "cant find format arg");
  327. return;
  328. }
  329. if(!sametype(indchar, a->type)) {
  330. warn(n, "format arg type %T", a->type);
  331. return;
  332. }
  333. if(a->op != OADDR || a->left->op != ONAME || a->left->sym != symstring) {
  334. // warn(n, "format arg not constant string");
  335. return;
  336. }
  337. s = a->left->cstring;
  338. checkargs(b, s);
  339. }
  340. void
  341. praghjdicks(void)
  342. {
  343. Sym *s;
  344. hjdickflg = 0;
  345. s = getsym();
  346. if(s) {
  347. hjdickflg = atoi(s->name+1);
  348. if(strcmp(s->name, "on") == 0 ||
  349. strcmp(s->name, "yes") == 0 ||
  350. strcmp(s->name, "dick") == 0)
  351. hjdickflg = 1;
  352. }
  353. while(getnsc() != '\n')
  354. ;
  355. if(debug['f'])
  356. if(hjdickflg)
  357. print("%4ld: hjdicks %d\n", lineno, hjdickflg);
  358. else
  359. print("%4ld: hjdicks off\n", lineno);
  360. }
  361. void
  362. pragfpround(void)
  363. {
  364. Sym *s;
  365. fproundflg = 0;
  366. s = getsym();
  367. if(s) {
  368. fproundflg = atoi(s->name+1);
  369. if(strcmp(s->name, "on") == 0 ||
  370. strcmp(s->name, "yes") == 0)
  371. fproundflg = 1;
  372. }
  373. while(getnsc() != '\n')
  374. ;
  375. if(debug['f'])
  376. if(fproundflg)
  377. print("%4ld: fproundflg %d\n", lineno, fproundflg);
  378. else
  379. print("%4ld: fproundflg off\n", lineno);
  380. }
  381. void
  382. pragprofile(void)
  383. {
  384. Sym *s;
  385. profileflg = 0;
  386. s = getsym();
  387. if(s) {
  388. profileflg = atoi(s->name+1);
  389. if(strcmp(s->name, "on") == 0 ||
  390. strcmp(s->name, "yes") == 0)
  391. profileflg = 1;
  392. }
  393. while(getnsc() != '\n')
  394. ;
  395. if(debug['f'])
  396. if(profileflg)
  397. print("%4ld: profileflg %d\n", lineno, profileflg);
  398. else
  399. print("%4ld: profileflg off\n", lineno);
  400. }