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

* Re: [9fans] Conversion of constants in C compiler
  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
  1 sibling, 1 reply; 15+ messages in thread
From: Charles Forsyth @ 2022-04-20 11:38 UTC (permalink / raw)
  To: 9fans

[-- Attachment #1: Type: text/plain, Size: 838 bytes --]

The short answer is whatever the historical reasons for the current
interpretation(s), it should follow C99 rules to avoid confusion.
One potential catch is that the compilers don't implement C99 rules when
signed and unsigned values meet, but something closer to the original
convention
(which frankly was simpler) that the result (or comparison) is unsigned,
portably, regardless of word size. I suspect things will break if that is
changed,
although again using the C99 rule is probably less confusing in the end,
because both people and new incoming programs will expect the C99
interpretation.

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

[-- Attachment #2: Type: text/html, Size: 1320 bytes --]

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

* Re: [9fans] Conversion of constants in C compiler
  2022-04-20 11:38 ` Charles Forsyth
@ 2022-04-20 14:37   ` adr
  0 siblings, 0 replies; 15+ messages in thread
From: adr @ 2022-04-20 14:37 UTC (permalink / raw)
  To: 9fans

On Wed, 20 Apr 2022, Charles Forsyth wrote:

> The short answer is whatever the historical reasons for the current interpretation(s), it
> should follow C99 rules to avoid confusion.

This should do the trick. I hope to not have to send another patch in half an hour...

Charles, you are part of the p9f board, if you serve the 9legacy
sources there it would be really easy to send you a patch. In my
opinion it makes more sense to let the editions be archived as isos
and substitute the sources 9p service with a 9legacy one.

Just a suggestion,
adr.
/sys/src/cmd/cc/lex.c:
[...]
        vv = yylval.vval;
        if(c1 & Numvlong ||
          convvtox(vv, TUVLONG) > convvtox(vv, TULONG) ||
          (c1 & (Numdec|Numuns)) == Numdec && convvtox(vv, TLONG) < 0) {
                if((c1 & Numuns) || convvtox(vv, TVLONG) < 0) {
                        c = LUVLCONST;
                        t = TUVLONG;
                        goto nret;
                }
                c = LVLCONST;
                t = TVLONG;
                goto nret;
        }
        if(c1 & Numlong ||
          convvtox(vv, TULONG) > convvtox(vv, TUINT) ||
          (c1 & (Numdec|Numuns)) == Numdec && convvtox(vv, TINT) < 0) {
                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;
[...]

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

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

* Re: [9fans] Conversion of constants in C compiler
  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 ` ori
  2022-04-21  7:54   ` adr
  1 sibling, 1 reply; 15+ messages in thread
From: ori @ 2022-04-20 14:37 UTC (permalink / raw)
  To: 9fans

Quoth adr <adr@SDF.ORG>:
> Some thoughts to help me decide what to do in my dist?

The c99 rule is probably the one to follow, along side
the plan9 unsigned preserving rule.

When you have a patch, let me know -- I'll happily test
and apply to 9front.


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

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

* Re: [9fans] Conversion of constants in C compiler
  2022-04-20 14:37 ` ori
@ 2022-04-21  7:54   ` adr
  2022-04-21 15:29     ` ori
                       ` (2 more replies)
  0 siblings, 3 replies; 15+ messages in thread
From: adr @ 2022-04-21  7:54 UTC (permalink / raw)
  To: 9fans

[-- Attachment #1: Type: text/plain, Size: 1946 bytes --]

On Wed, 20 Apr 2022, ori@eigenstate.org wrote:
> When you have a patch, let me know -- I'll happily test
> and apply to 9front.

Hi ori, this patch applyes to the sources served at 9front.org.
By the way, do you plan to keep in sync
http://only9fans.com/ori/git9/HEAD/info.html or should I forget
about that repo?

Regards,
adr.

--- /n/9front/sys/src/cmd/cc/lex.c      Wed Apr  6 14:45:26 2022
+++ /tmp/lex.c  Thu Apr 21 08:39:14 2022
@@ -848,16 +848,9 @@
                yyerror("overflow in constant");

        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 & Numvlong ||
+         convvtox(vv, TUVLONG) > convvtox(vv, TULONG) ||
+         (c1 & (Numdec|Numuns)) == Numdec && convvtox(vv, TLONG) < 0) {
                if((c1 & Numuns) || convvtox(vv, TVLONG) < 0) {
                        c = LUVLCONST;
                        t = TUVLONG;
@@ -867,7 +860,9 @@
                t = TVLONG;
                goto nret;
        }
-       if(c1 & Numlong) {
+       if(c1 & Numlong ||
+         convvtox(vv, TULONG) > convvtox(vv, TUINT) ||
+         (c1 & (Numdec|Numuns)) == Numdec && convvtox(vv, TINT) < 0) {
                if((c1 & Numuns) || convvtox(vv, TLONG) < 0) {
                        c = LULCONST;
                        t = TULONG;
------------------------------------------
9fans: 9fans
Permalink: https://9fans.topicbox.com/groups/9fans/T22754f10b241991c-Mefe97ddcd27aad8f1a072269
Delivery options: https://9fans.topicbox.com/groups/9fans/subscription

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: Type: text/x-diff; name=c99_int_constants_representation.diff, Size: 1086 bytes --]

--- /n/9front/sys/src/cmd/cc/lex.c	Wed Apr  6 14:45:26 2022
+++ /tmp/lex.c	Thu Apr 21 08:39:14 2022
@@ -848,16 +848,9 @@
 		yyerror("overflow in constant");
 
 	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 & Numvlong ||
+	  convvtox(vv, TUVLONG) > convvtox(vv, TULONG) ||
+	  (c1 & (Numdec|Numuns)) == Numdec && convvtox(vv, TLONG) < 0) {
 		if((c1 & Numuns) || convvtox(vv, TVLONG) < 0) {
 			c = LUVLCONST;
 			t = TUVLONG;
@@ -867,7 +860,9 @@
 		t = TVLONG;
 		goto nret;
 	}
-	if(c1 & Numlong) {
+	if(c1 & Numlong ||
+	  convvtox(vv, TULONG) > convvtox(vv, TUINT) ||
+	  (c1 & (Numdec|Numuns)) == Numdec && convvtox(vv, TINT) < 0) {
 		if((c1 & Numuns) || convvtox(vv, TLONG) < 0) {
 			c = LULCONST;
 			t = TULONG;

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

* Re: [9fans] Conversion of constants in C compiler
  2022-04-21  7:54   ` adr
@ 2022-04-21 15:29     ` ori
  2022-04-28  1:10     ` ori
  2022-04-28  2:43     ` ori
  2 siblings, 0 replies; 15+ messages in thread
From: ori @ 2022-04-21 15:29 UTC (permalink / raw)
  To: 9fans

Quoth adr <adr@SDF.ORG>:
> On Wed, 20 Apr 2022, ori@eigenstate.org wrote:
> > When you have a patch, let me know -- I'll happily test
> > and apply to 9front.
> 
> Hi ori, this patch applyes to the sources served at 9front.org.

Highly appreciated -- I'm busy this week, but I'll take a look
in the coming week.

> By the way, do you plan to keep in sync
> http://only9fans.com/ori/git9/HEAD/info.html or should I forget
> about that repo?

I'll update it. There are a few changes in flight that are being
worked on, and once I commit them to 9front I'll sync back.


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

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

* Re: [9fans] Conversion of constants in C compiler
  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
  2 siblings, 1 reply; 15+ messages in thread
From: ori @ 2022-04-28  1:10 UTC (permalink / raw)
  To: 9fans

Quoth adr <adr@SDF.ORG>:
> 
> Hi ori, this patch applyes to the sources served at 9front.org.
> By the way, do you plan to keep in sync
> http://only9fans.com/ori/git9/HEAD/info.html or should I forget
> about that repo?

it's synced.


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

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

* Re: [9fans] Conversion of constants in C compiler
  2022-04-21  7:54   ` adr
  2022-04-21 15:29     ` ori
  2022-04-28  1:10     ` ori
@ 2022-04-28  2:43     ` ori
  2022-04-28  3:12       ` ori
  2022-05-01 12:35       ` adr
  2 siblings, 2 replies; 15+ messages in thread
From: ori @ 2022-04-28  2:43 UTC (permalink / raw)
  To: 9fans

Quoth adr <adr@SDF.ORG>:
> On Wed, 20 Apr 2022, ori@eigenstate.org wrote:
> > When you have a patch, let me know -- I'll happily test
> > and apply to 9front.
> 
> Hi ori, this patch applyes to the sources served at 9front.org.
> By the way, do you plan to keep in sync
> http://only9fans.com/ori/git9/HEAD/info.html or should I forget
> about that repo?
> 
> Regards,
> adr.
> 
> --- /n/9front/sys/src/cmd/cc/lex.c      Wed Apr  6 14:45:26 2022
> +++ /tmp/lex.c  Thu Apr 21 08:39:14 2022
> @@ -848,16 +848,9 @@
>                 yyerror("overflow in constant");
> 
>         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 & Numvlong ||
> +         convvtox(vv, TUVLONG) > convvtox(vv, TULONG) ||
> +         (c1 & (Numdec|Numuns)) == Numdec && convvtox(vv, TLONG) < 0) {
>                 if((c1 & Numuns) || convvtox(vv, TVLONG) < 0) {
>                         c = LUVLCONST;
>                         t = TUVLONG;

Thanks for the patch!

I think this gets the condition slightly wrong. For a decimal
number, we should promote:

        int -> long -> vlong.

For a hex number, though, we want

        int -> uint -> long -> ulong -> vlong -> uvlong

however with the condition above,

        18446744073709551615

will get converted to a uvlong:

        c1 & Numvlong == 0:
                false -> no explicit conversion
        convvtox(vv, TUVLONG) > convvtox(vv, TULONG)
                true -> vv fits into a uvlong, but not a ulong,
                so we enter this.

so then, we end up in this branch:

        if((c1 & Numuns) || convvtox(vv, TVLONG) < 0) {

                true, because convvtox(vv, TVLONG) < 0.

I think we want:

        if(c1 & Numvlong ||
          convvtox(vv, TUVLONG) != convvtox(vv, TULONG) ||
          convvtox(vv, TLONG) < 0) {
                if((c1 & (Numdec|Numuns)) == 0 &&
                  ((c1 & Numuns) || convvtox(vv, TVLONG) < 0)) {
                        c = LUVLCONST;
                        t = TUVLONG;
                        goto nret;
                }
                c = LVLCONST;
                t = TVLONG;
                goto nret;
        }
        if(c1 & Numlong ||
          convvtox(vv, TULONG) > convvtox(vv, TUINT) ||
          convvtox(vv, TINT) < 0) {
                if((c1 & (Numdec|Numuns)) == 0 && 
                  ((c1 & Numuns) || convvtox(vv, TLONG) < 0)) {
                        c = LULCONST;
                        t = TULONG;
                        goto nret;
                }
                c = LLCONST;
                t = TLONG;
                goto nret;
        }


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

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

* Re: [9fans] Conversion of constants in C compiler
  2022-04-28  2:43     ` ori
@ 2022-04-28  3:12       ` ori
  2022-05-01 12:35       ` adr
  1 sibling, 0 replies; 15+ messages in thread
From: ori @ 2022-04-28  3:12 UTC (permalink / raw)
  To: 9fans

Quoth ori@eigenstate.org:
> I think we want:

I mean:

        if(c1 & Numvlong ||
          convvtox(vv, TUVLONG) > convvtox(vv, TULONG) ||
          (c1 & (Numdec|Numuns)) == Numdec && convvtox(vv, TLONG) < 0) {
                if((c1 & (Numdec|Numuns)) == 0 &&
                  ((c1 & Numuns) || convvtox(vv, TVLONG) < 0)) {
                        c = LUVLCONST;
                        t = TUVLONG;
                        goto nret;
                }
                c = LVLCONST;
                t = TVLONG;
                goto nret;
        }
        if(c1 & Numlong ||
          convvtox(vv, TULONG) > convvtox(vv, TUINT) ||
          (c1 & (Numdec|Numuns)) == Numdec && convvtox(vv, TINT) < 0) {
                if((c1 & (Numdec|Numuns)) == 0 && 
                  ((c1 & Numuns) || convvtox(vv, TLONG) < 0)) {
                        c = LULCONST;
                        t = TULONG;
                        goto nret;
                }
                c = LLCONST;
                t = TLONG;
                goto nret;
        }


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

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

* Re: [9fans] Conversion of constants in C compiler
  2022-04-28  1:10     ` ori
@ 2022-05-01 12:03       ` adr
  0 siblings, 0 replies; 15+ messages in thread
From: adr @ 2022-05-01 12:03 UTC (permalink / raw)
  To: 9fans

> it's synced.
Nice.

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

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

* Re: [9fans] Conversion of constants in C compiler
  2022-04-28  2:43     ` ori
  2022-04-28  3:12       ` ori
@ 2022-05-01 12:35       ` adr
  2022-05-09 19:31         ` adr
  1 sibling, 1 reply; 15+ messages in thread
From: adr @ 2022-05-01 12:35 UTC (permalink / raw)
  To: 9fans

> I think this gets the condition slightly wrong. For a decimal
> number, we should promote:
>
>        int -> long -> vlong.

Yeah, i was thinking
    int -> long -> vlong -> uvlong
when I wrote that, nice catch!

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

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

* Re: [9fans] Conversion of constants in C compiler
  2022-05-01 12:35       ` adr
@ 2022-05-09 19:31         ` adr
  2022-05-10 13:06           ` adr
  0 siblings, 1 reply; 15+ messages in thread
From: adr @ 2022-05-09 19:31 UTC (permalink / raw)
  To: 9fans

On Sun, 1 May 2022, adr wrote:

> Yeah, i was thinking
>   int -> long -> vlong -> uvlong

No, it was a mistake, I forgot to check again that the conversion to
unsigned when the constant is using the sign bit doesn't occurs to
decimal constants.

Also, reading 9front's mailing list I noticed the mess ignoring
that convvtox will return vlong, type casting should do the trick:

[...]
        vv = yylval.vval;
        if(c1 & Numvlong ||
          (uvlong)convvtox(vv, TUVLONG) > convvtox(vv, TULONG) ||
          (c1 & (Numdec|Numuns)) == Numdec && convvtox(vv, TLONG) < 0) {
                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 ||
          convvtox(vv, TULONG) > convvtox(vv, TUINT) ||
          (c1 & (Numdec|Numuns)) == Numdec && convvtox(vv, TINT) < 0) {
                if((c1 & Numuns) || convvtox(vv, TLONG) < 0 && (c1 & Numdec) == 0) {
                        c = LULCONST;
                        t = TULONG;
                        goto nret;
                }
                c = LLCONST;
                t = TLONG;
                goto nret;
        }
        if((c1 & Numuns) || convvtox(vv, TINT) < 0 && (c1 & Numdec) == 0) {
                c = LUCONST;
                t = TUINT;
                goto nret;
        }
        c = LCONST;
        t = TINT;
        goto nret;
[...]

It looks complex at first, but each line is telling you the reason
to expand the constant, and when to use unsigned types first. For
me is absolutely better than insert size assumptions in a piece of
code which is making a great effort to let that to machine dependent
code well kept in another place.

I'll make some tests.

adr

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

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

* Re: [9fans] Conversion of constants in C compiler
  2022-05-09 19:31         ` adr
@ 2022-05-10 13:06           ` adr
  2022-05-10 14:48             ` adr
  0 siblings, 1 reply; 15+ messages in thread
From: adr @ 2022-05-10 13:06 UTC (permalink / raw)
  To: 9fans

I think I got it right at last:

[...]
        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) == 0) {
                        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) == 0) {
                c = LLCONST;
                t = TLONG;
                goto nret;
        }
        c = LCONST;
        t = TINT;
        goto nret;
[...]

I used the cast also in (uvlong)convvtox(vv, TULONG) because the
standard only specifies that long long can't be smaller than long.

After playing with this I'm thinking about using the original code
and substituting the warning for an error when a constant is
truncated. Makes sense to me and Plan9's C isn't C99 anyway.

adr.

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

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

* Re: [9fans] Conversion of constants in C compiler
  2022-05-10 13:06           ` adr
@ 2022-05-10 14:48             ` adr
  0 siblings, 0 replies; 15+ messages in thread
From: adr @ 2022-05-10 14:48 UTC (permalink / raw)
  To: 9fans

Arrrg!

[...]
        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)) {
                c = LLCONST;
                t = TLONG;
                goto nret;
        }
        c = LCONST;
        t = TINT;
        goto nret;
[...]

------------------------------------------
9fans: 9fans
Permalink: https://9fans.topicbox.com/groups/9fans/T22754f10b241991c-M489f3936d41217db381e8d09
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).