From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mimir.eigenstate.org ([206.124.132.107]) by ewsd; Sun Aug 2 12:38:29 EDT 2020 Received: from abbatoir.fios-router.home (pool-74-101-2-6.nycmny.fios.verizon.net [74.101.2.6]) by mimir.eigenstate.org (OpenSMTPD) with ESMTPSA id f6f3ab9d (TLSv1.2:ECDHE-RSA-AES256-SHA:256:NO) for <9front@9front.org>; Sun, 2 Aug 2020 09:38:21 -0700 (PDT) Message-ID: To: 9front@9front.org Subject: Re: [9front] cc: fix c99 integer conversions Date: Sun, 02 Aug 2020 09:38:20 -0700 From: ori@eigenstate.org In-Reply-To: MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit List-ID: <9front.9front.org> List-Help: X-Glyph: ➈ X-Bullshit: flexible lossless persistence general-purpose just-in-time API frontend > The C99 standard, section 6.4.4.1 paragraph 5 says that integer > constants should be converted as follows: > > If they fit in an int, they should be an int. > > If they're written in decimal, they should be converted > to the smallest signed type that can hold the value. > > If they're written as oct or hex, they should be converted > to the smallest signed *or* unsigned type that can hold the > value. > > Right now, we don't widen to vlong when appropriate. This > fixes the issue. > > This bug/quirk was discovered by Amavect, and they wrote > the test code: > New revision of the patch, which doesn't touch types with explicit suffixes, and warns when you fall off of the int sizes, to catch behavior changes in existing code. There's just one place in our tree where the change matters, so this patch shuts up that one warning. I'm also happy to remove the warning, since it doesn't seem to be an issue in practice. diff -r 39206a734718 sys/src/cmd/8c/txt.c --- a/sys/src/cmd/8c/txt.c Sat Aug 01 10:54:03 2020 -0700 +++ b/sys/src/cmd/8c/txt.c Sun Aug 02 09:36:22 2020 -0700 @@ -865,7 +865,7 @@ gmove(f, &fregnode0); gins(AFADDD, nodfconst(-2147483648.), &fregnode0); gins(AFMOVLP, f, &nod); - gins(ASUBL, nodconst(-2147483648), &nod); + gins(ASUBL, nodconst(-0x80000000), &nod); gmove(&nod, t); return; diff -r 39206a734718 sys/src/cmd/cc/lex.c --- a/sys/src/cmd/cc/lex.c Sat Aug 01 10:54:03 2020 -0700 +++ b/sys/src/cmd/cc/lex.c Sun Aug 02 09:36:22 2020 -0700 @@ -444,7 +444,7 @@ yylex(void) { vlong vv; - long c, c1, t; + long c, c1, t, w; char *cp; Rune rune; Sym *s; @@ -844,7 +844,16 @@ yyerror("overflow in constant"); vv = yylval.vval; - if(c1 & Numvlong) { + /* + * c99 is silly. Decimap 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<