Repository navigation
cc: an `L' suffix is a floor on a constant's type, not a ceiling - #615
Merged
Merged
Conversation
Rebuilding chicken with -DC_SIXTY_FOUR answered `runtime.c:12525 duplicate cases in switch 0' eight times -- and the value in that message is the evidence: not a collision between two numbers, every label in both of decode_literal2's switches had become 0. chicken.h spells its fourteen header type tags 0x0n00000000000000L, one L, which is correct on any LP64 system. cc/lex.c's widening path was guarded by `(c1 & Numlong) == 0', so it ran only for constants with no suffix at all; an L-suffixed constant too big for a 32-bit long fell to the TLONG arm and convvtox() threw away every significant bit. C99 6.4.4.1 says an l/L constant takes the first of long, unsigned long, long long, unsigned long long in which its value can be represented, so L is a floor on the type and not a ceiling. Guard removed; the threshold is the same `w' as for an unsuffixed constant, because long and int are both 32 bits here. The "int constant widened to vlong" warning now excludes Numlong, since such a constant was never an int. Not a chicken fix: every LP64 upstream header in the tree that writes a 64-bit constant with one L -- the normal spelling there -- has been truncating. longconst-test.c is the regression test. Section 3 is the control: 0x80000000L must stay 32 bits, because unsigned long can represent it, so a patch that widened on the first L passes sections 1 and 2 and fails there. 0 failures on gcc, which says the test is written correctly and nothing more -- the host's long is 64 bits, so sections 1 and 2 are true there because nothing overflows. Section 0 prints sizeof(long) so the two runs tell themselves apart. Not compiled anywhere yet: kencc needs Plan 9's <u.h>/<libc.h>, so the first build is the VM's. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WGAwvvTwDg2yknFkmZ3qzs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Rebuilding chicken with -DC_SIXTY_FOUR answered
`runtime.c:12525 duplicate cases in switch 0' eight times -- and the value in that message is the evidence: not a collision between two numbers, every label in both of decode_literal2's switches had become 0. chicken.h spells its fourteen header type tags 0x0n00000000000000L, one L, which is correct on any LP64 system.
cc/lex.c's widening path was guarded by
(c1 & Numlong) == 0', so it ran only for constants with no suffix at all; an L-suffixed constant too big for a 32-bit long fell to the TLONG arm and convvtox() threw away every significant bit. C99 6.4.4.1 says an l/L constant takes the first of long, unsigned long, long long, unsigned long long in which its value can be represented, so L is a floor on the type and not a ceiling. Guard removed; the threshold is the samew' as for an unsuffixed constant, because long and int are both 32 bits here. The "int constant widened to vlong" warning now excludes Numlong, since such a constant was never an int.Not a chicken fix: every LP64 upstream header in the tree that writes a 64-bit constant with one L -- the normal spelling there -- has been truncating.
longconst-test.c is the regression test. Section 3 is the control: 0x80000000L must stay 32 bits, because unsigned long can represent it, so a patch that widened on the first L passes sections 1 and 2 and fails there. 0 failures on gcc, which says the test is written correctly and nothing more -- the host's long is 64 bits, so sections 1 and 2 are true there because nothing overflows. Section 0 prints sizeof(long) so the two runs tell themselves apart.
Not compiled anywhere yet: kencc needs Plan 9's <u.h>/<libc.h>, so the first build is the VM's.
Claude-Session: https://claude.ai/code/session_01WGAwvvTwDg2yknFkmZ3qzs