9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
* [9fans] Conversion of constants in C compiler
@ 2022-04-20 10:19 adr
  2022-04-20 11:38 ` Charles Forsyth
  2022-04-20 14:37 ` ori
  0 siblings, 2 replies; 15+ messages in thread
From: adr @ 2022-04-20 10:19 UTC (permalink / raw)
  To: 9fans

Hi.

I've been tinkering again with the dist I shared before in
http://adr.freeshell.org/plan9, basically 9legacy + Miller's 9pi
+ 9front's libseq. Importing ori's git9 I noticed that the compiler
was truncating a constant without the correspondent suffix.

According to C99, the type of a constant should be the first in
which its value can be represented following this table:

Suffix     Decimal                 0 or 0x
----------------------------------------------------------
none       int                     int
            long int                unsigned int
            long long int           long int
                                    unsigned long int
                                    unsigned long long int
----------------------------------------------------------
u|U        unsigned int            unsigned int
            unsigned long int       unsigned long int
            unsigned long long int  unsigned long long int
----------------------------------------------------------
l|L        long int                long int
            long long int           unsigned long int
                                    long long int
                                    unsigned long long int
----------------------------------------------------------
u|U & l|L  unsigned long int       unsigned long int
            unsigned long long int  unsigned long long int
----------------------------------------------------------
ll|LL      long long int           long long int
                                    unsigned long long int
----------------------------------------------------------
u|U & ll|LL        unsigned long long int
----------------------------------------------------------

Which follows the K&R description at "A.2.5.1 Integer Constants", just adding LL.

Now, in plan9 constants are of type int if there is no suffix, or
of the one specified by the suffix. The only change made is from
a signed type to an unsigned one if it is necessary to fit the
constant's value. The rest is truncated:

/sys/src/cmd/cc/lex.c:
[...]
        vv = yylval.vval;
        if(c1 & Numvlong) {
                if((c1 & Numuns) || convvtox(vv, TVLONG) < 0) {
                        c = LUVLCONST;
                        t = TUVLONG;
                        goto nret;
                }
                c = LVLCONST;
                t = TVLONG;
                goto nret;
        }
        if(c1 & Numlong) {
                if((c1 & Numuns) || convvtox(vv, TLONG) < 0) {
                        c = LULCONST;
                        t = TULONG;
                        goto nret;
                }
                c = LLCONST;
                t = TLONG;
                goto nret;
        }
        if((c1 & Numuns) || convvtox(vv, TINT) < 0) {
                c = LUCONST;
                t = TUINT;
                goto nret;
        }
        c = LCONST;
        t = TINT;
        goto nret;

nret:
        yylval.vval = convvtox(vv, t);
        if(yylval.vval != vv){
                nearln = lineno;
                warn(Z, "truncated constant: %T %s", types[t], symb);
        }
        return c;
[...]

9front introduces some widening:
[...]
        vv = yylval.vval;
        /*
         * c99 is silly: decimal constants stay signed,
         * hex and octal go unsigned before widening.
         */
        w = 32;
        if((c1 & (Numdec|Numuns)) == Numdec)
                w = 31;
        if(c1 & Numvlong || (c1 & Numlong) == 0 && (uvlong)vv >= 1ULL<<w){
                if((c1&(Numdec|Numvlong)) == Numdec && vv < 1ULL<<32)
                        warn(Z, "int constant widened to vlong: %s", symb);
                if((c1 & Numuns) || convvtox(vv, TVLONG) < 0) {
                        c = LUVLCONST;
                        t = TUVLONG;
                        goto nret;
                }
                c = LVLCONST;
                t = TVLONG;
                goto nret;
        }
        if(c1 & Numlong) {
[...]

It doesn't follow c99. Constants with explicit L prefix which
doesn't fit in a ulong type will not be promoted to vlong but
truncated as ulong. Removing '(c1 & Numlong) == 0' should do the
trick, I think, but I don't like the code.  The promotion of type
from int to vlong only occurs just because all the compilers define
int and long with the same width, and because that width is precisely
4 bytes. The rest of the original code is clearly not taking that
fact into account which is in my opinion the correct approach.

Forcing to specify explicitly the type if a different one from an
int is desired is interesting, but the automatic conversion to an
unsigned one already brakes the idea, doesn't it?.

Some thoughts to help me decide what to do in my dist?

Regards,
adr.

------------------------------------------
9fans: 9fans
Permalink: https://9fans.topicbox.com/groups/9fans/T22754f10b241991c-Mb38696f1b928920ec2c4d16d
Delivery options: https://9fans.topicbox.com/groups/9fans/subscription

^ permalink raw reply	[flat|nested] 15+ messages in thread
* [9fans] Conversion of constants in C compiler
@ 2022-06-06  0:35 adr
  0 siblings, 0 replies; 15+ messages in thread
From: adr @ 2022-06-06  0:35 UTC (permalink / raw)
  To: 9fans

Building cmd I noticed that the case of sizeof(int) = sizeof(long)
(which is the case in all compilers) wasn't managed with my changes.
I wonder if this logic mess could be shortened without making
impossible to read the 'if' conditions without throwing up (I've
tried).

I've compiled on arm the libraries, cmd and kernel (except ape)
without any problem.

adr.

/sys/src/cmd/cc/lex.c
[...]
        vv = yylval.vval;
        if(c1 & Numvlong ||
          (uvlong)convvtox(vv, TUVLONG) > convvtox(vv, TULONG)){
                /* unsigned suffix or hex occupying the sing bit */
                if((c1 & Numuns) || convvtox(vv, TVLONG) < 0 && (c1 & Numdec) == 0) {
                        c = LUVLCONST;
                        t = TUVLONG;
                        goto nret;
                }
                c = LVLCONST;
                t = TVLONG;
                goto nret;
        }
        if(c1 & Numlong ||
          (uvlong)convvtox(vv, TULONG) > convvtox(vv, TUINT)){
                if((c1 & Numuns) || convvtox(vv, TLONG) < 0 && (c1 & Numdec) == 0) {
                        c = LULCONST;
                        t = TULONG;
                        goto nret;
                }
                /* decimal occupying the sing bit */
                if(convvtox(vv, TLONG) < 0 && (c1 & Numdec)) {
                        c = LVLCONST;
                        t = TVLONG;
                        goto nret;
                }
                c = LLCONST;
                t = TLONG;
                goto nret;
        }
        if((c1 & Numuns) || convvtox(vv, TINT) < 0 && (c1 & Numdec) == 0) {
                c = LUCONST;
                t = TUINT;
                goto nret;
        }
        if(convvtox(vv, TINT) < 0 && (c1 & Numdec)) {
                /* size(int) = size(long) */
                if(convvtox(vv, TLONG) < 0) {
                        c = LVLCONST;
                        t = TVLONG;
                        goto nret;
                }
                c = LLCONST;
                t = TLONG;
                goto nret;
        }
        c = LCONST;
        t = TINT;
        goto nret;
[...]


------------------------------------------
9fans: 9fans
Permalink: https://9fans.topicbox.com/groups/9fans/T4bced580971a40a2-Mda3d0c619c734bb0e1cf708c
Delivery options: https://9fans.topicbox.com/groups/9fans/subscription

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2022-06-06  0:36 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-20 10:19 [9fans] Conversion of constants in C compiler adr
2022-04-20 11:38 ` Charles Forsyth
2022-04-20 14:37   ` adr
2022-04-20 14:37 ` ori
2022-04-21  7:54   ` adr
2022-04-21 15:29     ` ori
2022-04-28  1:10     ` ori
2022-05-01 12:03       ` adr
2022-04-28  2:43     ` ori
2022-04-28  3:12       ` ori
2022-05-01 12:35       ` adr
2022-05-09 19:31         ` adr
2022-05-10 13:06           ` adr
2022-05-10 14:48             ` adr
2022-06-06  0:35 adr

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).