1: Sample code that reproduces the problem.
#ifdef __SDCC
#define TEST_INT_MAX 32767
#else
#include <limits.h>
#define TEST_INT_MAX INT_MAX
#endif
enum { unrepresentable_int = TEST_INT_MAX + 1 }; /* ERROR */
2: Exact command used to run SDCC on this sample code
./bin/sdcc -c bug.c
3: SDCC version tested
Git f68fca8a4368ece9fe93b21f2e0341282b104359, SDCC 4.6.3 #0 (Linux).
Affected in valdiag testing on mcs51, mcs51-large, mcs51-stack-auto, ds390, z80, z180, r2k, r4k, sm83, tlcs90, hc08, s08, mos6502, huc6280, stm8, f8, pdk13, pdk14, and pdk15.
4: Copy of the error message or incorrect output, or a clear description of the observed versus expected behavior.
N3886 6.6.1p20 says that each constant expression shall evaluate to a constant that is in the range of representable values for its type. According to the ISO C standard, all constraint violations must be diagnosed. SDCC, for which int has a maximum value of 32767 on the tested ports, accepts this expression without a diagnostic and folds it as if signed integer arithmetic had wrapped. The conditional definition makes the same test use the host implementation's INT_MAX with the comparison compilers.
GCC 13.3.0 and Clang 18.1.3 diagnose the overflow. TCC 0.9.28rc (mob 9db1105, 2026-09-26) accepts it without a diagnostic and therefore has the same bug.
Attaching a candidate patch to fix this bug.
This is one of eight independent patches against SDCC commit
c8cee3a5b4656a3d7ef97ef6078c38a016a02cfb(2026-09-28).The patches were also applied together to the baseline commit and built with the PIC14 and PIC16 ports disabled. The full device library build completed successfully. Focused valdiag testing of the eight new files passed on all 19 valdiag targets: 27 checks per target, zero failures.
make -C support/regression -j2 test-ucz80:Last edit: Christopher Bazley 2026-09-29
This doesn't look wrong at first sight (though I didn't check very closely yet), but I the patch looks like it only fixes the missing diagnostic for signed int, but not for unsigned int, long, etc despite the language in N3886 6.6.1p20 apparently also requiring a diagnostic for those.
P.S.: I don't see anything about
_BitIntin valPlus, is that a problem (but if it is, it is probably outside the scope of this ticket)?Hi Philipp, thanks for reviewing the patch. I agree that the fix is very incomplete. I have a patch that tries to fix all cases of overflow for constant integer expressions, but it is rather big and complicated. Instead of attaching that, I have split it into separate bug reports that will require separate bug fixes.
Please see bug [#4100], [#4101] and [#4102]. I think those are preconditions for fixing this bug properly.
Related
Bugs:
#4100Bugs:
#4101Bugs:
#4102Last edit: Maarten Brock 2026-10-04
Hi Philipp,
Please find a revised candidate patch attached. The original patch only added an overflow check for signed
intaddition. This replacement broadens that coverage and applies directly to r16984.Regarding
_BitInt, the revised patch checks the computed result type before theint,longand sharedlong long/_BitIntbranches, usingbitsForTypefor the actual width. Tests cover signed_BitIntoverflow at 2, 17 and 64 bits and preserve unsigned wrapping.The changes are:
Use one overflow-checking helper for signed addition, subtraction, multiplication, division, remainder, unary negation and left shift. It checks the computed result type, covering
int,long,long longand signed_BitInt, rather than assuming the result isint. The tests include promotions and mixed types where the operation is valid in the resulting type.Check before performing the invalid arithmetic. The original patch computed the result first and checked whether narrowing changed it. That approach cannot safely handle the widest signed type, because the calculation itself may overflow on the host. The replacement uses unsigned arithmetic for the boundary checks, emits warning 165 and returns zero with the computed type for error recovery. That also avoids a second diagnostic caused by converting an invalid result.
Suppress the overflow warning in unevaluated operands:
sizeof,typeof,typeof_unqual, the controlling expression of_Generic, short-circuited logical operands and unselected conditional branches. Evaluated branches still warn.Leave valid unsigned wrapping unchanged. The fixes for [#4100], [#4101] and [#4102] are now upstream, so this patch does not include them. It preserves the existing unsigned multiplication warning. Conditional-branch suppression uses the same truth test as the [#4101] fix, with tests for wide integer and fractional conditions.
Expand
bug-4093.cfrom four test groups to 35, covering overflow, valid boundaries, unsigned wrapping and unevaluated operands. The overflow examples use initialisers rather than enum declarations to isolate arithmetic diagnostics from enum-specific constraints.The complete valdiag suite passed across 8 configurations. A focused run with
SDCCval.candSDCCast.cinstrumented by undefined behaviour sanitiser also passed all 280 test-group runs without errors. Three existing regression files compiled on six targets and completed successfully on Z80. The full runtime regression suite was not run yet.Related
Bugs:
#4100Bugs:
#4101Bugs:
#4102Sorry, I need to rework the patch again. There are many existing cases of overflow where it is unacceptable to implement anything other than wrapping behaviour.
Hi @spth
Please consider the attached revised version of the candidate bugfix.
Compared to the previous candidate patch:
Related
Bugs:
#4119I think the fix for this bug should depend on the fix for [#4119], as well as all of its previous dependencies.
Related
Bugs:
#4119