SCM Repository
Annotation of /sml/trunk/ckit/HISTORY
Parent Directory
|
Revision Log
Revision 975 - (view) (download)
1 : | dbm | 597 | ckit history |
2 : | ============ | ||
3 : | |||
4 : | Release Changes | ||
5 : | =============== | ||
6 : | |||
7 : | Version 0.x, 14/Sept/99 (nch) | ||
8 : | ----------------------------- | ||
9 : | 1. BuildAst flags combined into compiler-mode and source-to-source-mode | ||
10 : | (control of scaling, insertion of explicit coersions, reduction of assign ops | ||
11 : | reduction of sizeof). | ||
12 : | |||
13 : | BuildAst now contains the following flags and major modes (collections of | ||
14 : | flags settings). | ||
15 : | |||
16 : | (* control of buildAst modes *) | ||
17 : | val insert_explicit_coersions : bool ref | ||
18 : | (* Insert explicit casts at points where there are implicit type conversions. | ||
19 : | If true, then reduce_assign_ops should also be set. *) | ||
20 : | val insert_scaling : bool ref | ||
21 : | (* Insert scaling computations at pointer arithmetic. *) | ||
22 : | val reduce_sizeof : bool ref | ||
23 : | (* Replace sizeof expressions by integer constants. *) | ||
24 : | val reduce_assign_ops : bool ref | ||
25 : | (* Replace assignops by simple ops and assignments. *) | ||
26 : | val multi_file_mode : bool ref | ||
27 : | (* Analysis mode -- allow repeated definitions. *) | ||
28 : | |||
29 : | val multiFileMode: unit -> unit (* was called analysis mode *) | ||
30 : | val compilerMode: unit -> unit | ||
31 : | val sourceToSourceMode: unit -> unit | ||
32 : | |||
33 : | |||
34 : | 2. Warning for zero size arrays added. | ||
35 : | |||
36 : | 3. Error messages are now bounded. | ||
37 : | Error now contains Error.errorsLimit and Error.warningsLimit | ||
38 : | which can be used to limit the printing of errors and warnings. | ||
39 : | |||
40 : | 4. Array sizes and sizeof. | ||
41 : | BuildAst now maintains the expressions used to define array sizes. | ||
42 : | When printed out, these expressions are now printed. | ||
43 : | This allows sizeof calculations to be maintained. | ||
44 : | |||
45 : | Note: In principle we should do the same thing for expressions in enums | ||
46 : | and in bitfields. However sizeof is fairly unlikely to be used in these | ||
47 : | situations. If reduce_sizeof is false and a sizeof is encountered in these | ||
48 : | situations, a warning message will be printed. | ||
49 : | |||
50 : | 5. Fixed build-ast so that if we get parse errors, we don't print type-checking | ||
51 : | errors. The philosophy here is: first get file to parse, and only then worry | ||
52 : | about semantic errors. | ||
53 : | |||
54 : | 6. Better error messages: We had mentioned capturing error messages in a | ||
55 : | data-structure so that a filter could be installed to print out more meaningful | ||
56 : | error messages (e.g. instead of "ENUM inserted"). This turns out to be a rather | ||
57 : | complex exercise. The problematic error messages involving ENUM are generated | ||
58 : | deep within ml-yacc, and dealing with these would require non-trivial rewriting | ||
59 : | of ml-yacc (in fact I suspect that the only way to do this would be to have our | ||
60 : | own version of ml-yacc). | ||
61 : | |||
62 : | So, instead I hacked the ml-yacc specification to do slightly better error | ||
63 : | recovery -- we now substiture "TYPE_NAME" for "ID" if there is an error | ||
64 : | involving "ID" tokens. | ||
65 : | |||
66 : | To see how this might help, recall that the problematic case is when you miss a | ||
67 : | typedef (or the related hancock-thingy). For example, with a missing | ||
68 : | definition of mytype, the declaration: | ||
69 : | |||
70 : | mytype x; | ||
71 : | |||
72 : | is tokenized as: | ||
73 : | |||
74 : | ID ID; | ||
75 : | |||
76 : | Now, what used to happen is that the parser would try to insert an ENUM token | ||
77 : | (a random bad choice). Instead, the parser now tries to interpret the ID as a | ||
78 : | TYPE_NAME, and so in effect we get: | ||
79 : | |||
80 : | TYPE ID; | ||
81 : | |||
82 : | and an error message: | ||
83 : | |||
84 : | "foo.c": error: syntax error: replacing ID with TYPE_NAME | ||
85 : | |||
86 : | I've experimented with some support for inserting heuristic help messages (an | ||
87 : | extension to the Error struct). I think it is rather ad hoc, but let me know | ||
88 : | how useful it is. The actual message that is printed now for the above scenario | ||
89 : | is | ||
90 : | |||
91 : | "file.c": error: syntax error: replacing ID with TYPE_NAME | ||
92 : | Likely cause: missing typedef declaration. | ||
93 : | |||
94 : | This message can be customized (it appears as a function call in the grammar | ||
95 : | file), and others could be added. | ||
96 : | |||
97 : | I've also configured build-ast so that when there are parser errors, error | ||
98 : | reporting during type checking is switched off, since such type checking errors | ||
99 : | tend to be quite confusing. | ||
100 : | |||
101 : | |||
102 : | ---------------------------------------------------------------------- | ||
103 : | Version 1.0b1, 7/Dec/1999 | ||
104 : | ------------- | ||
105 : | Error interface changed. | ||
106 : | Top level interfaces for build-ast changed. | ||
107 : | |||
108 : | |||
109 : | ---------------------------------------------------------------------- | ||
110 : | Version 1.0b2, 13/Jan/2000 | ||
111 : | -------------- | ||
112 : | Bug fixes. | ||
113 : | Revise regression test suite. | ||
114 : | |||
115 : | |||
116 : | Version 1.0b3, 15/Mar/2000 | ||
117 : | ------------- | ||
118 : | Bug fixes: Bugs 1,3,5,6,7,9,10 | ||
119 : | Made sizes (Sizes.sizes) a record and parameterized makeAst on sizes. | ||
120 : | Added various regression tests for bugs. | ||
121 : | |||
122 : | |||
123 : | Version 1.0, 15/Mar/2000 | ||
124 : | ------------- | ||
125 : | * Bug fixes: Bugs 2, 4, 8, 12, 13 | ||
126 : | * Reworked size and alignment mechanism to support parameterization | ||
127 : | (see src/ast/sizes[-sig].sml). A utility program (src/c-util/sizes.c) | ||
128 : | can be used to generate sizes info for a given compiler/platform | ||
129 : | combination. | ||
130 : | |||
131 : | blume | 975 | Version 1.x (x > 0), Halloween 2001 (boo! :-), M.Blume |
132 : | ----------- | ||
133 : | * Changed the "Function" constructor of type Ast.ctype to carry optional | ||
134 : | argument identifiers. | ||
135 : | * Changed the return type of TypeUtil.getFunction accordingly. | ||
136 : | * Type equality ignores the argument names. | ||
137 : | * TypeUtil.composite tries to preserve argument names but gives up | ||
138 : | if there is a mismatch. | ||
139 : | |||
140 : | dbm | 597 | ====================================================================== |
141 : | Bug fix history | ||
142 : | ====================================================================== | ||
143 : | |||
144 : | Test: valid-programs/a40.c | ||
145 : | Status: fixed 15/june/99 | ||
146 : | Fix: Changed (ty, ty, signedNum CT.INT, expop) | ||
147 : | to (ty, ty, ty, expop) | ||
148 : | in mulDivOp (build-ast.sml) | ||
149 : | Also change similar code in integralOp. | ||
150 : | Email: | ||
151 : | |||
152 : | From: chandra@research.bell-labs.com (Satish Chandra) | ||
153 : | Date: Fri, 21 May 1999 14:00:28 -0500 | ||
154 : | |||
155 : | Nevin: | ||
156 : | |||
157 : | Have you already caught this one? | ||
158 : | |||
159 : | File build-ast-fn.sml: | ||
160 : | |||
161 : | Function mulDivOp in case PT.Binop, about line 1216 in my version: | ||
162 : | |||
163 : | then (case usualBinaryCnv env (ty1, ty2) of | ||
164 : | SOME ty => (ty, ty, signedNum CT.INT, expop) | ||
165 : | ^^^^^^ | ||
166 : | If we were type checking a float multiplied by a float, we would | ||
167 : | lose, right? | ||
168 : | |||
169 : | The Wisconsin folks came up with this example, which does not | ||
170 : | produce the correct adornments. | ||
171 : | |||
172 : | float f = 5.6, f1; | ||
173 : | |||
174 : | int main() { | ||
175 : | f1 = f * f; | ||
176 : | |||
177 : | return 0; | ||
178 : | } | ||
179 : | |||
180 : | -satish | ||
181 : | |||
182 : | --------------------------------------------------------------------------- | ||
183 : | |||
184 : | Test: valid-programs/a37.c | ||
185 : | Status: fixed 15/june/99 | ||
186 : | Fix: added case "| ([CT.Void], nil) => (nil, nil)" to isAssignableL (type-util.sml) | ||
187 : | Email: | ||
188 : | |||
189 : | From: chandra@research.bell-labs.com (Satish Chandra) | ||
190 : | Date: Tue, 25 May 1999 15:00:52 -0500 | ||
191 : | |||
192 : | A function with a 'void' argument as its only argument is basically | ||
193 : | a function with no arguments. E.g.: | ||
194 : | |||
195 : | void f(void); | ||
196 : | |||
197 : | main() | ||
198 : | { | ||
199 : | f(); | ||
200 : | } | ||
201 : | |||
202 : | We issue a Type Warning: function call has too few args | ||
203 : | |||
204 : | I can go fix these things myself, but it will make it harder to | ||
205 : | synchronize our changes. Please give me a call so we can make a plan | ||
206 : | on how to go about it. | ||
207 : | |||
208 : | -satish | ||
209 : | |||
210 : | ------------------------------------------------------------------------------ | ||
211 : | |||
212 : | Test: valid-programs/a38.c | ||
213 : | Status: fixed sometime in early june/99 | ||
214 : | Fix: fixed during major overhaul of frontend | ||
215 : | |||
216 : | From: chandra@research.bell-labs.com (Satish Chandra) | ||
217 : | Date: Thu, 03 Jun 1999 20:17:56 -0500 | ||
218 : | |||
219 : | When perform_type_checking is on, it complains about | ||
220 : | |||
221 : | for(;;) | ||
222 : | |||
223 : | as "condition of for statement is not scalar". | ||
224 : | |||
225 : | The problem stems from the use of isScalar, without checking for EmptyExp | ||
226 : | first. | ||
227 : | |||
228 : | -satish | ||
229 : | |||
230 : | ------------------------------------------------------------------------------- | ||
231 : | |||
232 : | Test: valid-programs/a39.c | ||
233 : | Status: fixed sometime before 15/june/99 (probably before major frontend overhaul?) | ||
234 : | Fix: seems to have been fixed as side-effect of some other bug-fix or code change. | ||
235 : | Email: | ||
236 : | |||
237 : | Date: Thu, 20 May 1999 09:16:37 -0400 (EDT) | ||
238 : | From: Kathleen Fisher <kfisher@research.att.com> | ||
239 : | |||
240 : | |||
241 : | There seems to be a bug involving the ++ operator. | ||
242 : | The following does not work: | ||
243 : | p->count[i]++ /* generates an error. */ | ||
244 : | p->count[i] = p->count[i]+1; /* OK */ | ||
245 : | |||
246 : | Kathleen | ||
247 : | |||
248 : | |||
249 : | --------------------------- Sat Jul 31 18:36:00 1999 -------------------------- | ||
250 : | |||
251 : | Test: valid-programs/a60.c | ||
252 : | Status: fixed 31/july/99 | ||
253 : | Fix: add case for TCInitializer so that if type is not core, then apply getCoreType | ||
254 : | (Alternatively, we could impose the invarient that TCInitializer must be | ||
255 : | applied only to core types, but this would be a pain becuase TCInitializer | ||
256 : | has a number of recursive calls.) | ||
257 : | Email: | ||
258 : | |||
259 : | build-ast.sml (TCInitializer) does not appear to look into typedefs. | ||
260 : | Therefore, | ||
261 : | |||
262 : | typedef struct {int x,y; } point; | ||
263 : | |||
264 : | point x = {2,3}; | ||
265 : | |||
266 : | fails to typecheck although gcc accepts it. | ||
267 : | |||
268 : | |||
269 : | --------------------------- Sat Jul 31 19:12:59 1999 -------------------------- | ||
270 : | |||
271 : | Test: valid-programs/a61.c | ||
272 : | Status: fixed 31/july/99 | ||
273 : | Fix: Shadow struct definitions were simply ignored. They generated nothing in | ||
274 : | Ast, and in fact there was no way to represent these definitions. | ||
275 : | The fix was to change the TypeDecal contructor from: | ||
276 : | |||
277 : | TypeDecl of tid | ||
278 : | |||
279 : | to | ||
280 : | |||
281 : | TypeDecl of {shadow: {strct:bool} option, tid:tid} | ||
282 : | |||
283 : | and then use TypeDecl{SOME{strct=true}, tid=....} to represent "struct x;" | ||
284 : | TypeDecl{SOME{strct=false}, tid=....} to represent "union x;" | ||
285 : | |||
286 : | Email: | ||
287 : | Date: Thu, 29 Jul 1999 14:15:12 -0400 | ||
288 : | From: Fred Smith <fsmith@research.att.com | ||
289 : | I couldn't figure out exactly why but the compiler does not seem to emit | ||
290 : | anything for empty structure declarations such as | ||
291 : | |||
292 : | struct t; | ||
293 : | |||
294 : | although the code looks like it should. Instead it just omits them. In | ||
295 : | one of the libraries we are using, a declaration like this is used to | ||
296 : | hide implementation details. When omitted we get a lot of spurious | ||
297 : | warnings from the C compiler. | ||
298 : | |||
299 : | |||
300 : | --------------------------- Sat Jul 31 20:14:32 1999 -------------------------- | ||
301 : | |||
302 : | Test: valid-programs/a62.c | ||
303 : | Status: fixed 31/july/99 | ||
304 : | Fix: Spurious casts were inserted in some cases because the eq test that was used by cast | ||
305 : | did not deref typedefs (amongst other things). | ||
306 : | The simple fix is to replace: | ||
307 : | |||
308 : | if lookAid aid' = ty then expr (* DBM: gen. equality on types *) | ||
309 : | |||
310 : | by | ||
311 : | |||
312 : | if getCoreType(lookAid aid') = getCoreType ty then expr (* DBM: gen. equality on types *) | ||
313 : | |||
314 : | in the code for wrapCast. | ||
315 : | |||
316 : | Email: | ||
317 : | Date: Thu, 29 Jul 1999 17:00:54 -0400 | ||
318 : | From: Fred Smith <fsmith@research.att.com> | ||
319 : | |||
320 : | I ran some tests and a cast is being inserted whenever | ||
321 : | a typedef occurs. In fact the following code: | ||
322 : | |||
323 : | typedef struct { int x,y,z; } w; | ||
324 : | |||
325 : | void main() { | ||
326 : | w foo; | ||
327 : | foo = foo; | ||
328 : | } | ||
329 : | |||
330 : | is compiled to | ||
331 : | struct t12 { int x,y,z; }; | ||
332 : | |||
333 : | typedef struct t12 w_t13; | ||
334 : | void main () | ||
335 : | { | ||
336 : | w_t13 foo_p17; | ||
337 : | foo_p17 = ((struct t12) foo_p17); | ||
338 : | } | ||
339 : | modulo formatting. | ||
340 : | |||
341 : | |||
342 : | --------------------------- Sat Jul 31 20:24:30 1999 -------------------------- | ||
343 : | |||
344 : | Test: invalid-programs/r60.c | ||
345 : | Status: fixed 31/july/99 | ||
346 : | Fix: Get rid of extra loc args in definitions of checkAssignableTys and checkAssign. | ||
347 : | |||
348 : | Date: Fri, 30 Jul 1999 10:15:36 -0400 | ||
349 : | From: Fred Smith <fsmith@research.att.com> | ||
350 : | |||
351 : | The following C program compiles and type-checks under Ckit but | ||
352 : | obviously should not. | ||
353 : | |||
354 : | struct w { int x,y,z; }; | ||
355 : | |||
356 : | void main() { | ||
357 : | struct w foo; | ||
358 : | float x; | ||
359 : | x = foo; | ||
360 : | |||
361 : | } | ||
362 : | |||
363 : | It took me a long time to track this one down since the code looks | ||
364 : | absolutely correct. The problem was that all calls to checkAssign in | ||
365 : | build-ast.sml failed to pass in a location. Since checkAssign was being | ||
366 : | used solely for its side-effect, both occurences were in contexts like | ||
367 : | (one case preceded a ; ) | ||
368 : | val _ = checkAssign .... | ||
369 : | |||
370 : | |||
371 : | --------------------------- Wed Sep 22 17:20:03 1999 -------------------------- | ||
372 : | |||
373 : | Test: valid-programs/a63.c | ||
374 : | Status: fixed 22/Sept/99 | ||
375 : | Fix: apply preArgConv to parameter types before adding them to local symbol table | ||
376 : | |||
377 : | The following C program does not type check under ckit and it should: | ||
378 : | |||
379 : | void f(); | ||
380 : | |||
381 : | main () { | ||
382 : | int y[4]; | ||
383 : | f(y); | ||
384 : | } | ||
385 : | |||
386 : | void f(int x[4]) { | ||
387 : | int *y; | ||
388 : | x = y; | ||
389 : | x[3] = 1; | ||
390 : | } | ||
391 : | |||
392 : | C is a horrible language -- if you declare an array as an arg to a function, | ||
393 : | then "array of type" is adjusted to "pointer to type". | ||
394 : | |||
395 : | |||
396 : | --------------------------- Wed Sep 22 17:34:55 1999 -------------------------- | ||
397 : | |||
398 : | Test: invalid-programs/r62.c | ||
399 : | Status: fixed 22/Sept/99 | ||
400 : | Fix: use lookLocalScope to check if parameter is locally defined before adding it. | ||
401 : | |||
402 : | The following C program type checks under ckit and it should not: | ||
403 : | |||
404 : | main () { | ||
405 : | return(0); | ||
406 : | } | ||
407 : | |||
408 : | f(int x, int x) { | ||
409 : | x = x; | ||
410 : | } | ||
411 : | |||
412 : | |||
413 : | --------------------------- Mon Sep 27 19:17:33 1999 -------------------------- | ||
414 : | |||
415 : | Test: not available | ||
416 : | Status: fixed 27/Sept/99 | ||
417 : | Problem: Redeclarations did not inherit the pid of the previous declaration. | ||
418 : | |||
419 : | e.g. | ||
420 : | |||
421 : | extern int i; | ||
422 : | |||
423 : | extern int i; | ||
424 : | |||
425 : | would be allocated different pid's. | ||
426 : | Bug was introduced during build-ast overhaul. | ||
427 : | |||
428 : | Fix: checkIdRebinding now returns an extra parameter (a uid option). | ||
429 : | |||
430 : | |||
431 : | --------------------------- Mon Sep 27 19:20:48 1999 -------------------------- | ||
432 : | |||
433 : | Test: not available | ||
434 : | Status: fixed (see a64.c, a65.c below) | ||
435 : | Problem: We don't check for non-constant expressions in non-simple initializers. | ||
436 : | |||
437 : | int f(int j) { | ||
438 : | int x[4] = {0,1,2,3}; /* this is ok */ | ||
439 : | int x[4] = {0,j,2*j,3*j}; /* this isn't */ | ||
440 : | } | ||
441 : | |||
442 : | but our frontend currently gives an unhesitant thumbs up for this code. | ||
443 : | |||
444 : | |||
445 : | --------------------------- Fri Oct 15 14:24:36 1999 -------------------------- | ||
446 : | |||
447 : | Test: not available | ||
448 : | Status: fixed 15/Oct/99 | ||
449 : | Fix: in sizeof.sml, function computeFieldListStruct, | ||
450 : | change foldr to foldl and reverse final list. | ||
451 : | Problem: | ||
452 : | > From: chandra@research.bell-labs.com (Satish Chandra) | ||
453 : | > Date: Thu, 14 Oct 1999 22:30:05 -0500 | ||
454 : | > | ||
455 : | > This has been quite a while, and the code might have changed much, but ... | ||
456 : | > | ||
457 : | > In function computeFieldListStruct, foldr computes offsets the wrong way. | ||
458 : | > I think we need foldl, and later on reverse the accumulated list called | ||
459 : | > "tab". | ||
460 : | |||
461 : | --------------------------- Tue Sep 14 11:30:44 1999 -------------------------- | ||
462 : | |||
463 : | TEST: a64.c, a65.c | ||
464 : | STATUS: fixed 12/jan/99 | ||
465 : | FIX: propagated isZeroExpr info for function args to checkFn (in type-utils), | ||
466 : | so that zero test can be included when checking assignment of zero to | ||
467 : | arg of pointer type. | ||
468 : | EMAIL: | ||
469 : | From: Kathleen Fisher <kfisher@research.att.com> | ||
470 : | Date: Mon, 10 Jan 2000 15:28:02 -0500 (EST) | ||
471 : | |||
472 : | The ckit compiler doesn't treat 0 as a legal function pointer. The | ||
473 : | program: | ||
474 : | |||
475 : | *************************************************** | ||
476 : | void f(int(* goo)(int)){} | ||
477 : | |||
478 : | void main(){ | ||
479 : | f(0); | ||
480 : | } | ||
481 : | *************************************************** | ||
482 : | |||
483 : | gives the error message: | ||
484 : | |||
485 : | "/fs/smaug/home4/kfisher/hancock/tests/suite/test.hc":4.2-6: error: Bad | ||
486 : | function call: arg 1 has type int but fn parameter has type int (*) (int) | ||
487 : | |||
488 : | |||
489 : | Kathleen | ||
490 : | |||
491 : | --------------------------- Tue Jan 11 23:12:50 2000 -------------------------- | ||
492 : | |||
493 : | TEST: a66.c | ||
494 : | STATUS: fixed 12/jan/99 | ||
495 : | FIX: Pretty-printer bug. | ||
496 : | pp-ast-fn.sml: | ||
497 : | changed the code for the e0 case of QuestionColon to | ||
498 : | ; ppExpr {nested=true} aidinfo tidtab pps e0 | ||
499 : | EMAIL: | ||
500 : | From: Alexey Loginov <alexey@cs.wisc.edu> | ||
501 : | Date: Sun, 28 Nov 1999 12:43:16 -0600 (CST) | ||
502 : | Hi Nevin and Dave, | ||
503 : | |||
504 : | We found another bug that isn't fixed in the version of ckit you sent | ||
505 : | us. I also didn't see it in the bug list. Expressions containing the | ||
506 : | "?:" operator are not parenthesized correctly to account for its | ||
507 : | right-associativity. (In the following program, lines 5 and 7 mean | ||
508 : | the same thing but line 6 is different.) | ||
509 : | |||
510 : | void main() { | ||
511 : | |||
512 : | char a, b, c, d, e; | ||
513 : | |||
514 : | a?b:c?d:e; /* Line 5. */ | ||
515 : | (a?b:c)?d:e; /* Line 6. */ | ||
516 : | a?b:(c?d:e); /* Line 7. */ | ||
517 : | } | ||
518 : | |||
519 : | |||
520 : | Output C code: | ||
521 : | |||
522 : | - ParseToAst.fileToC "/u/a/l/alexey/types/test/quest_col.c"; | ||
523 : | |||
524 : | void main () | ||
525 : | { | ||
526 : | char a; | ||
527 : | char b; | ||
528 : | char c; | ||
529 : | char d; | ||
530 : | char e; | ||
531 : | a ? b : c ? d : e; | ||
532 : | a ? b : c ? d : e; | ||
533 : | a ? b : c ? d : e; | ||
534 : | } | ||
535 : | |||
536 : | |||
537 : | Thanks, | ||
538 : | -Alexey | ||
539 : | |||
540 : | --------------------------- Tue Jan 11 23:12:52 2000 -------------------------- | ||
541 : | |||
542 : | |||
543 : | TEST: r64.c | ||
544 : | STATUS: fixed 12/jan/00 | ||
545 : | FIX: Add check of initializers to see if const (only non-const | ||
546 : | case is an object of dynamic storage duration (i.e. non-global, non-static). | ||
547 : | Notion of const is complex -- need to recurse through arithmetic, ?-: etc. | ||
548 : | (Long term issue: constant expressions should really be reduced to constants.) | ||
549 : | EMAIL: | ||
550 : | Date: Tue, 7 Dec 1999 17:22:48 -0500 (EST) | ||
551 : | From: Kathleen Fisher <kfisher@research.att.com> | ||
552 : | |||
553 : | The following code: | ||
554 : | |||
555 : | struct foo_t{ | ||
556 : | int x; | ||
557 : | int y; | ||
558 : | }; | ||
559 : | |||
560 : | void f(int x0, int y0){ | ||
561 : | struct foo_t myfoo = {x0,y0}; | ||
562 : | } | ||
563 : | |||
564 : | void main(){ | ||
565 : | f(0,0); | ||
566 : | } | ||
567 : | |||
568 : | passes through the ckit compiler without complaint, but cc reports the | ||
569 : | following error: | ||
570 : | |||
571 : | "bug.c", line 8: error(1028): expression must have a constant value | ||
572 : | struct foo_t myfoo = {x0,y0}; | ||
573 : | ^ | ||
574 : | |||
575 : | "bug.c", line 8: error(1028): expression must have a constant value | ||
576 : | struct foo_t myfoo = {x0,y0}; | ||
577 : | |||
578 : | |||
579 : | ====================================================================== | ||
580 : | Numbered Bugs | ||
581 : | ====================================================================== | ||
582 : | |||
583 : | NUMBER: 1 | ||
584 : | SUBMITTER: Alexey Loginov <alexey@cs.wisc.edu> | ||
585 : | DATE: 2/10/00 | ||
586 : | TEST: regression/valid-programs/a211.c,a212.c,a213.c,a214.c,a215.c | ||
587 : | STATUS: fixed 3/10/00 (nch) | ||
588 : | DESCRIPTION: | ||
589 : | Enum constants which were not assigned values in original source | ||
590 : | are assigned 0 in output. | ||
591 : | |||
592 : | - enum { e1,e2,e3 } e; | ||
593 : | |||
594 : | --> enum t1 { e1=0, e2=0, e3=0 }; | ||
595 : | enum t1 e; | ||
596 : | |||
597 : | |||
598 : | ---------------------------------------------------------------------- | ||
599 : | NUMBER: 2 | ||
600 : | SUBMITTER: Alexey Loginov <alexey@cs.wisc.edu> | ||
601 : | DATE: 2/10/00 | ||
602 : | TEST: | ||
603 : | STATUS: fixed 3/31/00 | ||
604 : | DESCRIPTION: | ||
605 : | functions returning function pointers. Function signal is a good | ||
606 : | real-life example. It's mentioned in Harbison and Steele p. 270 | ||
607 : | or so (sorry I don't have the book with me). | ||
608 : | |||
609 : | int (*fp(double))(float); | ||
610 : | |||
611 : | --> int (*) (float) fp (double); | ||
612 : | |||
613 : | which does not compile. | ||
614 : | |||
615 : | |||
616 : | ---------------------------------------------------------------------- | ||
617 : | NUMBER: 3 | ||
618 : | SUBMITTER: Alexey Loginov <alexey@cs.wisc.edu> | ||
619 : | DATE: 2/10/00 | ||
620 : | TEST: regression/valid-programs/a216.c | ||
621 : | STATUS: fixed 3/10/00 | ||
622 : | FIX: The problem was that the type for the second variable was array(const char), | ||
623 : | and the code did not strip off the const inside the array constructor. | ||
624 : | The fix was to add an extra case to look for qualifiers inside arrays in initializer-normalizer. | ||
625 : | DESCRIPTION: | ||
626 : | inconsistent interpretation of initialization of constant | ||
627 : | character arrays: | ||
628 : | |||
629 : | char c[] = "abcdefg"; | ||
630 : | const char cc[] = "abcdefg"; | ||
631 : | |||
632 : | --> char c[8]={97,98,99,100,101,102,103,0}; | ||
633 : | char const cc[1]={"abcdefg"}; | ||
634 : | |||
635 : | |||
636 : | ---------------------------------------------------------------------- | ||
637 : | NUMBER: 4 | ||
638 : | SUBMITTER: Alexey Loginov <alexey@cs.wisc.edu> | ||
639 : | DATE: 2/10/00 | ||
640 : | TEST: a232.c | ||
641 : | STATUS: fixed 24/Mar/00 | ||
642 : | FIX: | ||
643 : | The pretty-printer in fact has enough information to know | ||
644 : | whether the original definition of a function was k&r or not: | ||
645 : | just look at the function params and at the function type. | ||
646 : | If the function type has no args, but the function has | ||
647 : | params, then we have k&r style. | ||
648 : | The case of FunctionDef in ppCoreExternalDecl now | ||
649 : | has code to recognize this case and print out K&R defns. | ||
650 : | |||
651 : | DESCRIPTION: | ||
652 : | old style C function parameter declarations have different | ||
653 : | semantics from new style (with respec to promotions) and | ||
654 : | should be preserved. | ||
655 : | |||
656 : | void foo(int); | ||
657 : | void foo(c) | ||
658 : | char c; { } | ||
659 : | |||
660 : | --> compiles, but | ||
661 : | |||
662 : | void foo(int); | ||
663 : | void foo(char c) { } | ||
664 : | |||
665 : | --> which is output by ckit, does not | ||
666 : | |||
667 : | |||
668 : | ---------------------------------------------------------------------- | ||
669 : | NUMBER: 5 | ||
670 : | SUBMITTER: Alexey Loginov <alexey@cs.wisc.edu> | ||
671 : | DATE: 2/10/00 | ||
672 : | TEST: regression/valid-programs/a222.c (for both problems) | ||
673 : | STATUS: fixed 3/10/00 | ||
674 : | FIX for 1: change default value of flag local_externs_ok to true | ||
675 : | FIX for 2: changed checking code for initializations (build-ast.sml and initializer-normalizer.sml) | ||
676 : | DESCRIPTION: | ||
677 : | Inconvinient Warnings: | ||
678 : | |||
679 : | - int foo() { extern int bar; } | ||
680 : | |||
681 : | --> error: `extern' not allowed in local declarations | ||
682 : | |||
683 : | - struct S s = t; (in general, struct S = <exp> where <exp> is | ||
684 : | not of the form {...}) | ||
685 : | |||
686 : | --> error: badly formed union/struct initializer: expecting { | ||
687 : | |||
688 : | COMMENT: | ||
689 : | These last two errors don't seem to affect the output, so we just | ||
690 : | ignore them. The others are causing problems on various utilities of | ||
691 : | the GNU website. (We're ignoring the issues with the use of GNU C.) | ||
692 : | |||
693 : | Local extern warning was fixed by making local_externs_ok contain true | ||
694 : | in build-ast.sml. There remains a question about whether the semantics | ||
695 : | is correct in all cases. (see regression/invalid-programs/r65.c, which | ||
696 : | appears to be handled properly -- produces an error message.) [dbm, 3/10/00] | ||
697 : | |||
698 : | |||
699 : | ---------------------------------------------------------------------- | ||
700 : | NUMBER: 6 | ||
701 : | SUBMITTER: John Reppy <jhr@research.bell-labs.com> | ||
702 : | DATE: 2/10/00 | ||
703 : | TEST: none | ||
704 : | STATUS: fixed | ||
705 : | FIX: introduced a sizes record type in sizes-sig.sml, and parameterized | ||
706 : | makeAst, SizeOf fns, and ParseToAst.fileAst' with respect to sizes. | ||
707 : | The Sizes structure provides a default value Sizes.defaultSizes. | ||
708 : | sizes-sig.sml and sizes.sml moved from variants(/ansic) to ast. | ||
709 : | [Plan is to provide a structure containing a set of sizes values for | ||
710 : | various platform/compiler combinations.] | ||
711 : | Removed bogus stale sizes-sig.sml file (the real signature contains longlong and longdouble). | ||
712 : | Fixed sizeof so that it now: | ||
713 : | a) provides the standard functionality for bitfields of char and short; | ||
714 : | b) has flags to modify the standard behaviour | ||
715 : | We can now simulate the behaviour of cc, lcc and gcc (wrt e.g. alignment | ||
716 : | issues for unnamed bitfields). | ||
717 : | |||
718 : | DESCRIPTION: | ||
719 : | The type metrics in the CKit are broken in several ways. First, it seems | ||
720 : | that the SIZES signature does not include longlong or longdouble. Second, | ||
721 : | the sizes are hard-coded in, instead of being ABI dependent. I'd recommend | ||
722 : | replacing the Sizes structure with a record type: | ||
723 : | |||
724 : | type metrics = {bits : int, align : int} | ||
725 : | |||
726 : | type interface = { | ||
727 : | charMetric : metrics, | ||
728 : | shortMetric : metrics, | ||
729 : | intMetric : metrics, | ||
730 : | longMetric : metrics, | ||
731 : | longlongMetric : metrics, | ||
732 : | floatMetric : metrics, | ||
733 : | doubleMetric : metrics, | ||
734 : | longdoubleMetric : metrics, | ||
735 : | pointerMetric : metrics, | ||
736 : | structAlign : int, | ||
737 : | bitFieldAlignment : int option | ||
738 : | } | ||
739 : | |||
740 : | For the IA32/SVID, the values should be | ||
741 : | |||
742 : | char 8 8 | ||
743 : | short 16 16 | ||
744 : | int 32 32 | ||
745 : | long 32 32 | ||
746 : | long long 64 32 | ||
747 : | float 32 32 | ||
748 : | double 64 32 | ||
749 : | long double 96 32 | ||
750 : | pointer 32 32 | ||
751 : | struct align - 8 | ||
752 : | |||
753 : | One can probably write a small C program that generates this information. | ||
754 : | [jhr has given one to nch -dbm] | ||
755 : | |||
756 : | [dbm, 3/8/00] The ast/sizes-sig.sml version of SIZES doesn't include | ||
757 : | longlong or longdouble, but the variants/sizes-sig.sml version does. | ||
758 : | That seems to be the version used in (e.g.) variants/*/config.sml. | ||
759 : | |||
760 : | The variants/sizes-sig.sml also defines a "layout" type corresponding | ||
761 : | to John's "metrics". The ast version of SIZES does not seem to be | ||
762 : | mentioned anywhere except in ast/sizes-sig.sml, where it is defined, | ||
763 : | so it looks like this is an old, vestigial version that has been superceded | ||
764 : | by the variants version. | ||
765 : | |||
766 : | [dbm, 3/14/00] John still advocates using a record. He anticipates wanting | ||
767 : | to switch target architectures dynamically (either by passing the record | ||
768 : | as a value, or by setting a global value) in the midst of processing. | ||
769 : | |||
770 : | |||
771 : | ---------------------------------------------------------------------- | ||
772 : | NUMBER: 7 | ||
773 : | SUBMITTER: Alexey Loginov <alexey@cs.wisc.edu> | ||
774 : | DATE: 2/18/00 | ||
775 : | TEST: regression/valid-programs/a224.c | ||
776 : | STATUS: fixed 3/10/00 (see bug 9) | ||
777 : | DESCRIPTION: | ||
778 : | '\0' is treated as '0' and not as a null character. We didn't check | ||
779 : | for any other special characters. | ||
780 : | |||
781 : | INPUT: | ||
782 : | |||
783 : | char c_null = '\0'; | ||
784 : | char c_zero = '0'; | ||
785 : | |||
786 : | int main () { return 0; } | ||
787 : | |||
788 : | OUTPUT: | ||
789 : | |||
790 : | char c_null=48; | ||
791 : | char c_zero=48; | ||
792 : | int main () | ||
793 : | { | ||
794 : | return 0; | ||
795 : | } | ||
796 : | |||
797 : | COMMENT: | ||
798 : | This is a special case of bug 9. | ||
799 : | |||
800 : | |||
801 : | ---------------------------------------------------------------------- | ||
802 : | NUMBER: 8 | ||
803 : | SUBMITTER: Alexey Loginov <alexey@cs.wisc.edu> | ||
804 : | DATE: 2/18/00 | ||
805 : | TEST: a227.c | ||
806 : | STATUS: fixed 24/Mar/00 | ||
807 : | FIX: | ||
808 : | The problem was in type-util.sml, | ||
809 : | where the function conditionalExp is used to type check conditional expressions. | ||
810 : | The relevant case statement in the body of the function is | ||
811 : | where both arguments (after usualUnaryCnv) have Pointer type. | ||
812 : | In this case, composite is called -- the problem is that the | ||
813 : | call to composite reverts to the original arguments ty1 and ty2 of the call | ||
814 : | to conditionalExp, rather than the results of applying usualUnaryCnv. | ||
815 : | |||
816 : | (Note that the function composite can not and should not | ||
817 : | apply usualUnaryCnv to its arguments.) | ||
818 : | |||
819 : | It turns out that this same error appears in three other places in the code | ||
820 : | (in isEquable, isSubtractable and isComparable). | ||
821 : | |||
822 : | With insert_explicit_coersions set to true, you now obtain: | ||
823 : | |||
824 : | original program (a227.c): | ||
825 : | |||
826 : | int main() { | ||
827 : | int *ip; | ||
828 : | int *jp; | ||
829 : | int ia[3]; | ||
830 : | jp = (1 ? ia : ip); | ||
831 : | } | ||
832 : | |||
833 : | fileToC output: | ||
834 : | |||
835 : | int main () | ||
836 : | { | ||
837 : | int *ip; | ||
838 : | int *jp; | ||
839 : | int ia[3]; | ||
840 : | jp = (1 ? (int *) ia : ip); | ||
841 : | } | ||
842 : | |||
843 : | |||
844 : | DESCRIPTION: | ||
845 : | "?:" operator typing. | ||
846 : | |||
847 : | int *ip; | ||
848 : | int *jp; | ||
849 : | int ia[3]; | ||
850 : | jp = (1 ? ia : ip); | ||
851 : | |||
852 : | --> error: Type Error: Unacceptable operands of question-colon. | ||
853 : | |||
854 : | C semantics (we think): | ||
855 : | --> jp = (1 ? (int *) ia : ip); | ||
856 : | ^^^^^^^ | ||
857 : | (implicit cast of ia to pointer) | ||
858 : | |||
859 : | |||
860 : | Current implementation: | ||
861 : | --> jp = (1 ? ia : (int[3]) ip); | ||
862 : | ^^^^^^^^ | ||
863 : | (implicit cast of ip to array) | ||
864 : | |||
865 : | COMMENT: | ||
866 : | Of course, code is still output correctly (without the implicit cast) | ||
867 : | but since we actually use the implicit casts to materialize some | ||
868 : | casts, we rely on their correctness. | ||
869 : | |||
870 : | |||
871 : | ---------------------------------------------------------------------- | ||
872 : | NUMBER: 9 | ||
873 : | SUBMITTER: Alexey Loginov <alexey@cs.wisc.edu> | ||
874 : | DATE: 2/22/00 | ||
875 : | TEST: regression/valid-programs/a223.c | ||
876 : | STATUS: fixed 3/10/00 | ||
877 : | DESCRIPTION: | ||
878 : | To follow up on this [bug 8] I wanted to mention that it looks like ckit | ||
879 : | handles '\ooo' in three different ways depending on the number of | ||
880 : | octal digits. In C the number of digits can be 1-3 but ckit only | ||
881 : | handles 3 digit numbers correctly. Two digit numbers are processed as | ||
882 : | decimal numbers. Single digit numbers are processed as if '\' weren't | ||
883 : | there (i.e. taken as ascii values). | ||
884 : | |||
885 : | INPUT: | ||
886 : | |||
887 : | char c_octal_0 = '\0'; | ||
888 : | char c_octal_51 = '\051'; | ||
889 : | char c_octal_60 = '\60'; | ||
890 : | char c_octal_7 = '\7'; | ||
891 : | |||
892 : | int main () { return 0; } | ||
893 : | |||
894 : | |||
895 : | OUTPUT: | ||
896 : | |||
897 : | char c_octal_0=48; /* Should be 0 */ | ||
898 : | char c_octal_51=41; /* Correct */ | ||
899 : | char c_octal_60=60; /* Should be 48 */ | ||
900 : | char c_octal_7=55; /* Should be 7 */ | ||
901 : | int main () | ||
902 : | { | ||
903 : | return 0; | ||
904 : | } | ||
905 : | |||
906 : | Of course, '\0' is the most common of these. Do you have a time frame | ||
907 : | for when you think the problems I mentioned before might be fixed? | ||
908 : | |||
909 : | COMMENT: | ||
910 : | [dbm] fixed by changing the rule in parser/grammar/c.lex to take 1 to 3 | ||
911 : | octal digits instead of exactly 3 ({1,3} replaced {3} as the modifier). | ||
912 : | |||
913 : | |||
914 : | ---------------------------------------------------------------------- | ||
915 : | NUMBER: 10 | ||
916 : | SUBMITTER: Alexey Loginov <alexey@cs.wisc.edu> | ||
917 : | DATE: 2/23/00 | ||
918 : | TEST: regression/valid-programs/a226.c | ||
919 : | STATUS: fixed 3/10/00 | ||
920 : | FIX: Stupid cut-and-paste problem: preincrements/predecrements were getting | ||
921 : | transformed into postincrements/postdecrements in build-ast.sml. | ||
922 : | DESCRIPTION: | ||
923 : | preincrement and predecrement behavior | ||
924 : | |||
925 : | INPUT: | ||
926 : | |||
927 : | int main () { | ||
928 : | int i = 10; | ||
929 : | |||
930 : | int i1 = ++i; | ||
931 : | int i2 = --i; | ||
932 : | |||
933 : | return 0; } | ||
934 : | |||
935 : | |||
936 : | OUTPUT: | ||
937 : | |||
938 : | int main () | ||
939 : | { | ||
940 : | int i=10; | ||
941 : | int i1=i++; | ||
942 : | int i2=i--; | ||
943 : | return 0; | ||
944 : | } | ||
945 : | |||
946 : | COMMENT: | ||
947 : | |||
948 : | ---------------------------------------------------------------------- | ||
949 : | NUMBER: 12 | ||
950 : | SUBMITTER: Kathleen Fisher <kfisher@research.att.com> | ||
951 : | DATE: 3/15/00 | ||
952 : | TEST: a230.c | ||
953 : | STATUS: fixed 24/Mar/00 | ||
954 : | FIX: | ||
955 : | The bug was because the implementation of the non-default | ||
956 : | behaviour of convert_function_args_to_pointers was not complete (there was | ||
957 : | a missing case in isAssignable in type-utils.sml). To put it another way, | ||
958 : | too much of the code was assuming that convert_function_args_to_pointers | ||
959 : | was set to the standard value, and in particular, that certain coersions had | ||
960 : | been performed *before* isAssignable was called. These coersions are not | ||
961 : | performed when convert_function_args_to_pointers is false. | ||
962 : | |||
963 : | DESCRIPTION: | ||
964 : | We've run into a problem with ckit when we turn the flag | ||
965 : | convert_function_args_to_pointers to false in the config.sml file. | ||
966 : | The following program: | ||
967 : | |||
968 : | ******************************************************** | ||
969 : | typedef int *windowTy[1]; | ||
970 : | |||
971 : | int f (windowTy w) | ||
972 : | { | ||
973 : | return 1; | ||
974 : | } | ||
975 : | |||
976 : | void main(){ | ||
977 : | windowTy w; | ||
978 : | f (w); | ||
979 : | } | ||
980 : | ******************************************************** | ||
981 : | |||
982 : | compiles just fine using cc, but it generates the following | ||
983 : | error if we compile it with ckit: | ||
984 : | |||
985 : | "array-param.hc":11.3-8: error: Bad function call: arg 1 has type windowTy | ||
986 : | but fn parameter has type windowTy | ||
987 : | |||
988 : | |||
989 : | ---------------------------------------------------------------------- | ||
990 : | NUMBER: 13 | ||
991 : | SUBMITTER: Olivier Tardieu | ||
992 : | DATE: 24/Mar/00 | ||
993 : | TEST: a301.c | ||
994 : | STATUS: fixed 24/Mar/00 | ||
995 : | FIX: | ||
996 : | ! should be type checked like || and && instead of like a simple | ||
997 : | unary operator. Extra code (a function logicalOp1) has | ||
998 : | been added to do this. | ||
999 : | |||
1000 : | DESCRIPTION: | ||
1001 : | |||
1002 : | main() { | ||
1003 : | void* p; | ||
1004 : | |||
1005 : | !p; | ||
1006 : | } | ||
1007 : | |||
1008 : | gives type error | ||
1009 : | error: Type Error: operand of unary op ! must be a number. | ||
1010 : | |||
1011 : | |||
1012 : | nch | 665 | ---------------------------------------------------------------------- |
1013 : | NUMBER: 14 | ||
1014 : | SUBMITTER: Alexey Loginov <alexey@cs.wisc.edu> | ||
1015 : | DATE: 4/17/00 | ||
1016 : | TEST: a240.c | ||
1017 : | STATUS: fixed 16/June/00 | ||
1018 : | FIX: | ||
1019 : | There is a flag to control this behaviour in config.sml: | ||
1020 : | Config.TypeCheckControl.convert_function_args_to_pointers | ||
1021 : | |||
1022 : | It should be set to true for standard behaviour (but was set to false | ||
1023 : | for some reason -- maybe temporarily for debugging something else, and then | ||
1024 : | not reverted back to true??). | ||
1025 : | |||
1026 : | This is actually an ambiguous case: a strict reading of the standard would | ||
1027 : | suggest that this should be flagged as a type error, but most | ||
1028 : | compilers allow it, so it is "standard". | ||
1029 : | |||
1030 : | DESCRIPTION: array formals | ||
1031 : | |||
1032 : | This one is similar to the ?: bug we reported earlier (Bug number 8). | ||
1033 : | |||
1034 : | void foo(int a[]); | ||
1035 : | |||
1036 : | int main() { | ||
1037 : | int * ip; | ||
1038 : | foo(ip); | ||
1039 : | } | ||
1040 : | |||
1041 : | Output: | ||
1042 : | |||
1043 : | "tt.c":5.3-10: error: Bad function call: | ||
1044 : | arg 1 has type int * but fn parameter has type int [] | ||
1045 : | |||
1046 : | Correct C output is still produced but the implicit type of ip inside | ||
1047 : | the call to foo has int array type. This is a problem for our | ||
1048 : | instrumentation. | ||
1049 : | |||
1050 : |
root@smlnj-gforge.cs.uchicago.edu | ViewVC Help |
Powered by ViewVC 1.0.0 |