From: SourceForge.net <no...@so...> - 2009-05-01 20:45:46
|
Bugs item #2783061, was opened at 2009-04-28 20:21 Message generated for change (Comment added) made by borutr You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=100599&aid=2783061&group_id=599 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: Icode generator Group: fixed Status: Closed Resolution: Accepted Priority: 5 Private: No Submitted By: Keith Packard (keithp) Assigned to: Maarten Brock (maartenbrock) Summary: mcs51 varargs functions do not promote pointers to generic Initial Comment: When a varags function (like printf) is passed a non-generic pointer (__code char *, for instance), that argument is not promoted to a generic pointer when pushed on the stack. This is a change from the 2.8 version which did this promotion. The test is small enough to include in-line here: extern void f(char *x, ...); void func(__code char *s) { f("hi", s); } SDCC command: $ sdcc -c --model-small --debug --opt-code-speed -otest.rel test.c SDCC version: SDCC : mcs51/gbz80/z80/avr/ds390/pic16/pic14/TININative/xa51/ds400/hc08 2.9.0 #5416 (Apr 9 2009) (UNIX) Incorrect output (note missing mov a,#0x80; push acc after the push ar3) 0000 AA 82 109 mov r2,dpl 0002 AB 83 110 mov r3,dph 0004 111 C$test.c$6$1$1 ==. 112 ; test.c:6: f("hi", s); 0004 C0 02 113 push ar2 0006 C0 03 114 push ar3 0008 74r00 115 mov a,#__str_0 000A C0 E0 116 push acc 000C 74s00 117 mov a,#(__str_0 >> 8) 000E C0 E0 118 push acc 0010 74 80 119 mov a,#0x80 0012 C0 E0 120 push acc 0014 12s00r00 121 lcall _f Email address: ke...@ke... ---------------------------------------------------------------------- >Comment By: Borut Ražem (borutr) Date: 2009-05-01 22:45 Message: Maarten, I think that behavior of passing pointers as varargs should be also documented in sdccman.lyx. Borut ---------------------------------------------------------------------- Comment By: Maarten Brock (maartenbrock) Date: 2009-05-01 20:38 Message: Fixed in SDCC 2.9.1 #5445. Applied the patch without changes, thanks. ---------------------------------------------------------------------- Comment By: Maarten Brock (maartenbrock) Date: 2009-04-30 15:51 Message: Keith, If casting does not help then this definitely is a bug. And since others prefer to send generic pointers by default, that's how it will be. Only with an explicit cast it will be transferred as a non-generic pointer. I'll have a look at the patch. ---------------------------------------------------------------------- Comment By: Keith Packard (keithp) Date: 2009-04-30 04:24 Message: I can't figure out how I'd pass a generic pointer with 2.9.0; adding an explicit cast to (char *) generates precisely the same code as without the cast; it's the cast type conversion code which is broken precisely in this case, after all (ask for RESULT_TYPE_NONE and you'll never get a generic pointer). With 2.8.0 (or 2.9.0 with my patch), you can ask the code to pass a short pointer with an explicit cast to __xdata (or whatever). Without my patch, you can't ever get a generic pointer. ---------------------------------------------------------------------- Comment By: Borut Ražem (borutr) Date: 2009-04-29 22:41 Message: In sdccman, section 1.4 Compatibility with previous versions, is written: "char type parameters to vararg functions are casted to int unless explicitly casted and --std-c89 and --std-c99 command line option are not defined , e.g.: char a=3; printf ("%d %c\n", a, (char)a); will push a as an int and as a char resp if --std-c89 and --std-c99 command line options are not defined, will push a as two ints if --std-c89 or --std-c99 command line option is defined." See also https://sourceforge.net/tracker/?func=detail&aid=1874922&group_id=599&atid=100599 For the pointers I'm more favorable to generic pointer passing in case of varargs. We could use --std-cXX approach too: pass generic pointer if --std-cXX is defined and pass the pointer type defined by caller if --std-cXX is not defined. Borut ---------------------------------------------------------------------- Comment By: Raphael Neider (tecodev) Date: 2009-04-29 21:47 Message: I think this case should be handled similar to passing 8-bit char's as int arguments to printf(). Do we promote them to int or are they passed as given? ---------------------------------------------------------------------- Comment By: Maarten Brock (maartenbrock) Date: 2009-04-29 21:01 Message: I already had the feeling it had to do with this change of mine. But I'm still uncertain if I should consider this a bug or a feature. Sending only as many bytes as required seems a good idea. I'm sure that if you add an explicit cast to a generic pointer it will send a generic pointer. And only the recipient knows what to expect, in this case probably a generic pointer due to using "%p" as the formatter. And printf does not (yet) support "%cp" for code pointers, "%xp" for xdata pointers, etc. I would like to hear other peoples opinion on this case. Should SDCC always send a generic pointer as argument to a function with a variable number of arguments? Or just send whatever you give to it? ---------------------------------------------------------------------- Comment By: Keith Packard (keithp) Date: 2009-04-29 17:14 Message: On 28 Dec 2008, Maarten Brock added RESULT_TYPE_GPTR as a distinct case from RESULT_TYPE_NONE, but it looks like that didn't include changes to make the varargs parameter passing code use RESULT_TYPE_GPTR in cases that involved passing pointers. I've attached a patch which passes RESULT_TYPE_GPTR for the two pointer cases in the varargs parameter type computation. ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=100599&aid=2783061&group_id=599 |