Repository navigation
Fix #15193 Wrong type for hex literals that do not fit in 32-bit long - #9026
wjakobsson wants to merge 2 commits into
Conversation
fd8f65b to
e9f7fde
Compare
dmcppcheck
left a comment
There was a problem hiding this comment.
AI review
I found no problems in the change. Switching from value >> 2 to value >> 1 makes the "fits in unsigned int/long" check exact. For a biguint, value >> 1 <= INT_MAX is the same as value <= UINT_MAX. On unix32, unix64 and win64 every hex and binary literal I tried now gets the type the C standard gives it. The U and L suffixes work too.
One case is still wrong, and the PR does not cause it. MathLib::isDec() counts octal literals as decimal. So on unix32 037777777777 (= 0xFFFFFFFF) gets the type signed long long instead of unsigned int, in both base and PR. The bug is in the same !MathLib::isDec(tokStr) condition the PR edits, so it could be fixed here or in a separate ticket.
Testing
- Built
cppcheckandtestrunnerinpr/, andcppcheckinbase/. Both built cleanly. ./testrunner TestSymbolDatabase TestValueFlow TestType TestOther TestCondition: 863 tests, 0 failed.- Compared the
valueTypeof literals in--dumpoutput between base and PR on unix32, unix64 and win64, using:void f(void) { (void)0xFFFFFFFF; (void)0x1FFFFFFFF; (void)0x100000000; (void)0xFFFFFFFFU; (void)0x100000000U; (void)037777777777; (void)077777777777; (void)0x8000000000000000; (void)0xFFFFFFFFFFFFFFFFL; (void)0x100000000L; (void)0x80000000L; (void)0x8000000000000000L; }
- Base gave wrong types, for example
0x100000000→unsigned intand0x100000000L→unsigned longon unix32. - The PR gives the right types:
signed long longon unix32/win64 andsigned longon unix64.0x100000000U→unsigned long long/unsigned long.0xFFFFFFFFstaysunsigned int, and0x80000000Lstaysunsigned longon 32-bit long platforms. - Binary literals are also right, for example
0b1…1(32 ones) →unsigned int.
- Base gave wrong types, for example
- Older bug found again, the same in base and PR: octal
037777777777→signed long longon unix32. It should beunsigned int, becauseMathLib::isDectreats octal as decimal. - Older bug found again, the same in base and PR: an out-of-range literal
0x10000000000000000givesinternalErrorfromMathLib::toBigUNumber.
Automated review of e9f7fde by Claude. The pull request was built and tested locally.
| if (type <= ValueType::Type::INT && mSettings.platform.isIntValue(unsignedSuffix ? (value >> 1) : value)) | ||
| type = ValueType::Type::INT; | ||
| else if (type <= ValueType::Type::INT && !MathLib::isDec(tokStr) && mSettings.platform.isIntValue(value >> 2)) { | ||
| else if (type <= ValueType::Type::INT && !MathLib::isDec(tokStr) && mSettings.platform.isIntValue(value >> 1)) { |
There was a problem hiding this comment.
AI review
This is not caused by the PR, but it is the same condition: MathLib::isDec() returns true for octal literals. Octal literals follow the same type rules as hex (C11 6.4.4.1), but they never reach this branch. For example, with --platform=unix32 the literal 037777777777 (= 0xFFFFFFFF) gets the type signed long long instead of unsigned int, in both base and PR. You could fix it here, or open a follow-up ticket.
|
Test results for commit e9f7fde (tools/test-my-pr.py, main compared to this PR): Test: http://ec2-16-170-140-253.eu-north-1.compute.amazonaws.com/pr-9026/ Posted automatically by the cppcheck PR test runner. +N: warnings only with this PR, -N: warnings only with main. The AI review is written by Claude and can be wrong. |
No description provided.