dpchk.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  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, int pos)
  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. pos++;
  264. nstar--;
  265. if(a == Z) {
  266. warn(nn, "more format than arguments %s",
  267. fmtbuf);
  268. return;
  269. }
  270. if(a->type == T)
  271. continue;
  272. if(!sametype(types[TINT], a->type) &&
  273. !sametype(types[TUINT], a->type))
  274. warn(nn, "format mismatch '*' in %s %T, arg %d",
  275. fmtbuf, a->type, pos);
  276. }
  277. for(l=tprot; l; l=l->link)
  278. if(sametype(types[TVOID], l->type)) {
  279. if(beq(flag, l->flag)) {
  280. s++;
  281. goto loop;
  282. }
  283. }
  284. n = nextarg(n, &a);
  285. pos++;
  286. if(a == Z) {
  287. warn(nn, "more format than arguments %s",
  288. fmtbuf);
  289. return;
  290. }
  291. if(a->type == 0)
  292. continue;
  293. for(l=tprot; l; l=l->link)
  294. if(sametype(a->type, l->type)) {
  295. /*print("checking %T/%ulx %T/%ulx\n", a->type, flag.b[0], l->type, l->flag.b[0]);*/
  296. if(beq(flag, l->flag))
  297. goto loop;
  298. }
  299. warn(nn, "format mismatch %s %T, arg %d", fmtbuf, a->type, pos);
  300. loop:;
  301. }
  302. }
  303. void
  304. dpcheck(Node *n)
  305. {
  306. char *s;
  307. Node *a, *b;
  308. Tname *l;
  309. int i;
  310. if(n == Z)
  311. return;
  312. b = n->left;
  313. if(b == Z || b->op != ONAME)
  314. return;
  315. s = b->sym->name;
  316. for(l=tname; l; l=l->link)
  317. if(strcmp(s, l->name) == 0)
  318. break;
  319. if(l == 0)
  320. return;
  321. i = l->param;
  322. b = n->right;
  323. while(i > 0) {
  324. b = nextarg(b, &a);
  325. i--;
  326. }
  327. if(a == Z) {
  328. warn(n, "cant find format arg");
  329. return;
  330. }
  331. if(!sametype(indchar, a->type)) {
  332. warn(n, "format arg type %T", a->type);
  333. return;
  334. }
  335. if(a->op != OADDR || a->left->op != ONAME || a->left->sym != symstring) {
  336. /* warn(n, "format arg not constant string");*/
  337. return;
  338. }
  339. s = a->left->cstring;
  340. checkargs(b, s, l->param);
  341. }
  342. void
  343. pragpack(void)
  344. {
  345. Sym *s;
  346. packflg = 0;
  347. s = getsym();
  348. if(s) {
  349. packflg = atoi(s->name+1);
  350. if(strcmp(s->name, "on") == 0 ||
  351. strcmp(s->name, "yes") == 0)
  352. packflg = 1;
  353. }
  354. while(getnsc() != '\n')
  355. ;
  356. if(debug['f'])
  357. if(packflg)
  358. print("%4ld: pack %d\n", lineno, packflg);
  359. else
  360. print("%4ld: pack off\n", lineno);
  361. }
  362. void
  363. pragfpround(void)
  364. {
  365. Sym *s;
  366. fproundflg = 0;
  367. s = getsym();
  368. if(s) {
  369. fproundflg = atoi(s->name+1);
  370. if(strcmp(s->name, "on") == 0 ||
  371. strcmp(s->name, "yes") == 0)
  372. fproundflg = 1;
  373. }
  374. while(getnsc() != '\n')
  375. ;
  376. if(debug['f'])
  377. if(fproundflg)
  378. print("%4ld: fproundflg %d\n", lineno, fproundflg);
  379. else
  380. print("%4ld: fproundflg off\n", lineno);
  381. }
  382. void
  383. pragprofile(void)
  384. {
  385. Sym *s;
  386. profileflg = 0;
  387. s = getsym();
  388. if(s) {
  389. profileflg = atoi(s->name+1);
  390. if(strcmp(s->name, "on") == 0 ||
  391. strcmp(s->name, "yes") == 0)
  392. profileflg = 1;
  393. }
  394. while(getnsc() != '\n')
  395. ;
  396. if(debug['f'])
  397. if(profileflg)
  398. print("%4ld: profileflg %d\n", lineno, profileflg);
  399. else
  400. print("%4ld: profileflg off\n", lineno);
  401. }
  402. void
  403. pragincomplete(void)
  404. {
  405. Sym *s;
  406. s = getsym();
  407. if(s){
  408. if(s->type == T)
  409. diag(Z, "unknown type %s in pragma incomplete", s->name);
  410. else
  411. s->type->garb |= GINCOMPLETE;
  412. }
  413. while(getnsc() != '\n')
  414. ;
  415. if(debug['f'])
  416. print("%s incomplete\n", s->name);
  417. }