dpchk.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494
  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('h', Fignor);
  144. argflag('+', Fignor);
  145. argflag('-', Fignor);
  146. argflag('*', Fstar);
  147. argflag('l', Fl);
  148. argflag('o', Fverb);
  149. flagbits['x'] = flagbits['o'];
  150. flagbits['X'] = flagbits['o'];
  151. }
  152. void
  153. pragvararg(void)
  154. {
  155. Sym *s;
  156. int n, c;
  157. char *t;
  158. Rune r;
  159. Type *ty;
  160. if(!debug['F'])
  161. goto out;
  162. s = getsym();
  163. if(s && strcmp(s->name, "argpos") == 0)
  164. goto ckpos;
  165. if(s && strcmp(s->name, "type") == 0)
  166. goto cktype;
  167. if(s && strcmp(s->name, "flag") == 0)
  168. goto ckflag;
  169. yyerror("syntax in #pragma varargck");
  170. goto out;
  171. ckpos:
  172. /*#pragma varargck argpos warn 2*/
  173. s = getsym();
  174. if(s == S)
  175. goto bad;
  176. n = getnsn();
  177. if(n < 0)
  178. goto bad;
  179. newname(s->name, n);
  180. goto out;
  181. ckflag:
  182. /*#pragma varargck flag 'c'*/
  183. c = getnsc();
  184. if(c != '\'')
  185. goto bad;
  186. c = getr();
  187. if(c == '\\')
  188. c = getr();
  189. else if(c == '\'')
  190. goto bad;
  191. if(c == '\n')
  192. goto bad;
  193. if(getc() != '\'')
  194. goto bad;
  195. argflag(c, Fignor);
  196. goto out;
  197. cktype:
  198. /*#pragma varargck type O int*/
  199. c = getnsc();
  200. if(c != '"')
  201. goto bad;
  202. t = fmtbuf;
  203. for(;;) {
  204. r = getr();
  205. if(r == ' ' || r == '\n')
  206. goto bad;
  207. if(r == '"')
  208. break;
  209. t += runetochar(t, &r);
  210. }
  211. *t = 0;
  212. t = strdup(fmtbuf);
  213. s = getsym();
  214. if(s == S)
  215. goto bad;
  216. ty = s->type;
  217. while((c = getnsc()) == '*')
  218. ty = typ(TIND, ty);
  219. unget(c);
  220. newprot(s, ty, t);
  221. goto out;
  222. bad:
  223. yyerror("syntax in #pragma varargck");
  224. out:
  225. while(getnsc() != '\n')
  226. ;
  227. }
  228. Node*
  229. nextarg(Node *n, Node **a)
  230. {
  231. if(n == Z) {
  232. *a = Z;
  233. return Z;
  234. }
  235. if(n->op == OLIST) {
  236. *a = n->left;
  237. return n->right;
  238. }
  239. *a = n;
  240. return Z;
  241. }
  242. void
  243. checkargs(Node *nn, char *s, int pos)
  244. {
  245. Node *a, *n;
  246. Bits flag;
  247. Tprot *l;
  248. if(!debug['F'])
  249. return;
  250. n = nn;
  251. for(;;) {
  252. s = strchr(s, '%');
  253. if(s == 0) {
  254. nextarg(n, &a);
  255. if(a != Z)
  256. warn(nn, "more arguments than format %T",
  257. a->type);
  258. return;
  259. }
  260. s++;
  261. flag = getflag(s);
  262. while(nstar > 0) {
  263. n = nextarg(n, &a);
  264. pos++;
  265. nstar--;
  266. if(a == Z) {
  267. warn(nn, "more format than arguments %s",
  268. fmtbuf);
  269. return;
  270. }
  271. if(a->type == T)
  272. continue;
  273. if(!sametype(types[TINT], a->type) &&
  274. !sametype(types[TUINT], a->type))
  275. warn(nn, "format mismatch '*' in %s %T, arg %d",
  276. fmtbuf, a->type, pos);
  277. }
  278. for(l=tprot; l; l=l->link)
  279. if(sametype(types[TVOID], l->type)) {
  280. if(beq(flag, l->flag)) {
  281. s++;
  282. goto loop;
  283. }
  284. }
  285. n = nextarg(n, &a);
  286. pos++;
  287. if(a == Z) {
  288. warn(nn, "more format than arguments %s",
  289. fmtbuf);
  290. return;
  291. }
  292. if(a->type == 0)
  293. continue;
  294. for(l=tprot; l; l=l->link)
  295. if(sametype(a->type, l->type)) {
  296. /*print("checking %T/%ulx %T/%ulx\n", a->type, flag.b[0], l->type, l->flag.b[0]);*/
  297. if(beq(flag, l->flag))
  298. goto loop;
  299. }
  300. warn(nn, "format mismatch %s %T, arg %d", fmtbuf, a->type, pos);
  301. loop:;
  302. }
  303. }
  304. void
  305. dpcheck(Node *n)
  306. {
  307. char *s;
  308. Node *a, *b;
  309. Tname *l;
  310. int i;
  311. if(n == Z)
  312. return;
  313. b = n->left;
  314. if(b == Z || b->op != ONAME)
  315. return;
  316. s = b->sym->name;
  317. for(l=tname; l; l=l->link)
  318. if(strcmp(s, l->name) == 0)
  319. break;
  320. if(l == 0)
  321. return;
  322. i = l->param;
  323. b = n->right;
  324. while(i > 0) {
  325. b = nextarg(b, &a);
  326. i--;
  327. }
  328. if(a == Z) {
  329. warn(n, "cant find format arg");
  330. return;
  331. }
  332. if(!sametype(indchar, a->type)) {
  333. warn(n, "format arg type %T", a->type);
  334. return;
  335. }
  336. if(a->op != OADDR || a->left->op != ONAME || a->left->sym != symstring) {
  337. /* warn(n, "format arg not constant string");*/
  338. return;
  339. }
  340. s = a->left->cstring;
  341. checkargs(b, s, l->param);
  342. }
  343. void
  344. pragpack(void)
  345. {
  346. Sym *s;
  347. packflg = 0;
  348. s = getsym();
  349. if(s) {
  350. packflg = atoi(s->name+1);
  351. if(strcmp(s->name, "on") == 0 ||
  352. strcmp(s->name, "yes") == 0)
  353. packflg = 1;
  354. }
  355. while(getnsc() != '\n')
  356. ;
  357. if(debug['f'])
  358. if(packflg)
  359. print("%4ld: pack %d\n", lineno, packflg);
  360. else
  361. print("%4ld: pack off\n", lineno);
  362. }
  363. void
  364. pragfpround(void)
  365. {
  366. Sym *s;
  367. fproundflg = 0;
  368. s = getsym();
  369. if(s) {
  370. fproundflg = atoi(s->name+1);
  371. if(strcmp(s->name, "on") == 0 ||
  372. strcmp(s->name, "yes") == 0)
  373. fproundflg = 1;
  374. }
  375. while(getnsc() != '\n')
  376. ;
  377. if(debug['f'])
  378. if(fproundflg)
  379. print("%4ld: fproundflg %d\n", lineno, fproundflg);
  380. else
  381. print("%4ld: fproundflg off\n", lineno);
  382. }
  383. void
  384. pragprofile(void)
  385. {
  386. Sym *s;
  387. profileflg = 0;
  388. s = getsym();
  389. if(s) {
  390. profileflg = atoi(s->name+1);
  391. if(strcmp(s->name, "on") == 0 ||
  392. strcmp(s->name, "yes") == 0)
  393. profileflg = 1;
  394. }
  395. while(getnsc() != '\n')
  396. ;
  397. if(debug['f'])
  398. if(profileflg)
  399. print("%4ld: profileflg %d\n", lineno, profileflg);
  400. else
  401. print("%4ld: profileflg off\n", lineno);
  402. }
  403. void
  404. pragincomplete(void)
  405. {
  406. Sym *s;
  407. Type *t;
  408. int istag, w, et;
  409. istag = 0;
  410. s = getsym();
  411. if(s == nil)
  412. goto out;
  413. et = 0;
  414. w = s->lexical;
  415. if(w == LSTRUCT)
  416. et = TSTRUCT;
  417. else if(w == LUNION)
  418. et = TUNION;
  419. if(et != 0){
  420. s = getsym();
  421. if(s == nil){
  422. yyerror("missing struct/union tag in pragma incomplete");
  423. goto out;
  424. }
  425. if(s->lexical != LNAME && s->lexical != LTYPE){
  426. yyerror("invalid struct/union tag: %s", s->name);
  427. goto out;
  428. }
  429. dotag(s, et, 0);
  430. istag = 1;
  431. }else if(strcmp(s->name, "_off_") == 0){
  432. debug['T'] = 0;
  433. goto out;
  434. }else if(strcmp(s->name, "_on_") == 0){
  435. debug['T'] = 1;
  436. goto out;
  437. }
  438. t = s->type;
  439. if(istag)
  440. t = s->suetag;
  441. if(t == T)
  442. yyerror("unknown type %s in pragma incomplete", s->name);
  443. else if(!typesu[t->etype])
  444. yyerror("not struct/union type in pragma incomplete: %s", s->name);
  445. else
  446. t->garb |= GINCOMPLETE;
  447. out:
  448. while(getnsc() != '\n')
  449. ;
  450. if(debug['f'])
  451. print("%s incomplete\n", s->name);
  452. }