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