Repository navigation
Conversation
dmcppcheck
left a comment
There was a problem hiding this comment.
AI review
The change to the #if/#elif condition is correct. An #if is still evaluated only when the enclosing group is active (as before), and an #elif is now evaluated only when its state is ElseIsTrue. The state handling after the evaluation still gives the right result. I found no wrong preprocessor output, and the reported case now matches gcc and clang.
New findings:
- Side effect on the
macroUsageandifCondoutputs, which cppcheck uses. An#elifafter a taken group is no longer evaluated, so macros in its condition are no longer reported inmacroUsage, and the#elifno longer gets anIfCondentry. Take#define A 1/#if 1/#elif A/#endif. Before the PR,Awas reported as used at line 4. With the PR,Ais not reported at all. Tools built on macro usage (for example the unused-macro check / MISRA 2.5 through the dump) may now see such macros as unused. If this is intended, it should be a deliberate decision with a test. Otherwise, recordmaybeUsedMacrosfor the skipped#elif. - The fix is incomplete for an empty condition. The check
!sameline(rawtok,rawtok->next)("Syntax error in #elif") runs before the new skip logic. So#if 1 / #elif / #endifstill aborts with an error and empty output, while gcc and clang accept it. This is not a regression; the base version behaves the same.
Testing
- I built
/work/prwithmake -j8 testrunner simplecpp CXXOPTS=-Werrorwithout warnings../testrunnerexits with 0.run-tests.pyshows 0 failed (21 skipped, 16 todos).pytest integration_test.pyshows 128 passed../selfcheck.shexits with 0. - I also built
/work/basefor comparison. - Combined input (scratch/a.c) with these cases:
#elif 1/0and#elif garbage(after a taken group#elif 1/0after a taken#elif- a nested
#if/#elif 1/0inside a skipped group #elif defined(after a false#ifdef- Results: gcc and clang print
a f i j(and report errors for the malformeddefined(, which is in a group that must be evaluated). Base aborts withdivision/modulo by zero. The PR stops at an empty#elifdefwith no name (line 7).
- Empty
#elifafter a taken group (not a regression; base is the same):#if 1 a #elif b #endif
/work/pr/simplecpp b.cprintsb.c:3: syntax error: Syntax error in #elifand no code.gcc -E -P b.candclang -E -P b.cprintawithout diagnostics. The same happens when the#if 1 / #elifis nested inside#if 0(c.c); gcc and clang printx. - Macro usage and IfCond through the API. I wrote a small driver, scratch/dm.cpp, that calls
simplecpp::preprocess(out,raw,files,cache,dui,&ol,&mu,&ic)and printsmuandic. Input d.c:Base output:#define A 1 #define B 1 #if 1 #elif A #elifdef B #endif
PR output:usage A line 4 usage A line 4 ifcond line 3 1=1 ifcond line 4 1=1ifcond line 3 1=1
Comments
simplecpp.cpp:3829
This check runs before the new skip logic, so an empty #elif after a taken group still aborts preprocessing:
#if 1
a
#elif
b
#endifsimplecpp prints Syntax error in #elif and gives no output. gcc and clang print a. The same happens when the #if 1/#elif is inside an #if 0 group. Since the PR is about not evaluating such #elif lines, consider applying the check only when the condition will actually be evaluated.
Automated review of a3e956c by Claude. The pull request was built and tested locally.
No description provided.