Repository navigation
Conversation
|
please look at the CI issues.. |
|
sorry i did notice it at first, I pushed the fix, it was one indentation space. |
|
I think you will need to rebase from latest master. I made a CI fix with #707 |
748755d to
5a52bc3
Compare
|
Done |
dmcppcheck
left a comment
There was a problem hiding this comment.
AI review
One new problem: a floating literal in an #elif that gcc and clang never evaluate now makes simplecpp report an error. simplecpp evaluates #elif conditions even after an earlier branch has been taken. Until now a floating literal there evaluated quietly; with this PR it throws. So
#if 1
ok
#elif 1.0
bad
#endifnow gives syntax error: failed to evaluate #elif condition, floating point literal in preprocessor expression and no output. gcc and clang both print ok with no diagnostic. cppcheck would stop checking a file that compiles fine, for example #if __cplusplus >= 201103L … #elif VERSION >= 1.5.
This comes from existing behaviour: base already does the same for #elif 1/0 after a taken group. But the PR adds a new, more likely way to hit it. It should be fixed (by not evaluating #elif once a branch was taken) or at least covered by a test or a known-issue note before merging.
Otherwise the detection matches gcc/clang on every spelling I tried. That includes 1.0, .5, 1e3, 1E3, 1e+3, 0e0, -1.0, 1.f, 0x1p3, 0X1P3, 0x1.p1, and literals in short-circuited operands (1 || 1.0, 0 ? 1.5 : 1). Hex integers containing e/E (0xE, 0x1e), 1ULL, digit separators, '.', __has_include("a.h")/<a.h> and skipped #if 0 blocks are not affected.
Minor: some invalid integer literals now get the floating-point message, while gcc gives a different one. For 1_e gcc says "invalid suffix", for 012e "exponent has no digits", for 1..2 "too many decimal points". They are errors in both, so it is only the wording. The extra work per token is negligible.
Testing
Build: make -j8 testrunner simplecpp CXXOPTS=-Werror in pr/ built with no warnings. I also built base/.
Test suites: all pass.
./testrunner: exit 0, no failures.python3 run-tests.py: 176 tests, 0 failed, same as base.pytest integration_test.py: 128 passed../selfcheck.sh: exit 0.
Edge cases: I ran 25 #if <expr> variants through pr, base and gcc -E. Every floating spelling is now rejected, matching gcc's "floating constant in preprocessor expression". Integer and hex-with-e literals, char literals, digit separators, defined(A) with A defined as 2.0, __has_include with a dotted name, and floats inside skipped #if 0 blocks are unchanged.
Regression found:
printf '#if 1\nok\n#elif 1.0\nbad\n#endif\n' > f.c
/work/pr/simplecpp f.c
# f.c:3: syntax error: failed to evaluate #elif condition, floating point literal in preprocessor expression
/work/base/simplecpp f.c # ok
gcc -E -P f.c # ok (no diagnostic)
clang -E -P f.c # ok (no diagnostic)Base already behaves like this for #elif 1/0 after a taken group, so the root cause is that simplecpp evaluates #elif after a taken branch. The PR makes it more likely to happen.
Automated review of 5a52bc3 by Claude. The pull request was built and tested locally.
Fixes #612.
preprocessor conditional expressions only permit integral expressions, but simplecpp previously passed floating-point literals into integer constant folding. Integer conversion then consumed their integral prefix, allowing expressions such as
A == 1.0to evaluate successfully.Detect floating-point spellings before numeric simplification and report a syntax error. This covers decimal-point, decimal exponent, and hexadecimal exponent forms while preserving valid integer literals.
Tests cover:
A == 1.0reproducer;.5in#elif;1e3;1.f;0x1p3;