Opened 10 years ago

Last modified 10 months ago

#7840 reopened defect

False positive: #include nested too deeply (preprocessorErrorDirective)

Reported by: 9fcc Owned by: noone
Priority: Normal Milestone:
Component: False positive Version:
Keywords: simplecpp preprocessorErrorDirective Cc:

Description

We have two config.h files. One is in project directory and another is in every subdirectory.
Config file from subfolder includes main config file.

False positive appeared in 1.76.1 version. Version 1.75 didn't have such issue.

Attachments (1)

0001-Includes-of-system-headers-are-never-relative-to-the.patch (1.8 KB ) - added by bavison 4 years ago.
Proposed fix

Download all attachments as: .zip

Change History (7)

comment:1 by orbitcowboy, 10 years ago

Thank your for your report. Could you please provide a minimal example? We need that to reproduce the described behavior.

Last edited 10 years ago by orbitcowboy (previous) (diff)

comment:2 by Daniel Marjamäki, 9 years ago

Resolution: worksforme
Status: newclosed

I fail to reproduce.

I created these files:

  • 7840/config.h (no include)
  • 7840/a/config.h (includes ../config.h)
  • 7840/a/1.c (includes config.h)

Output:

daniel@debian:~/cppcheck/7840/a$ ~/cppcheck/cppcheck -E 1.c
Checking 1.c ...

#line 2 "../config.h"
X
#line 4 "config.h"
 A
daniel@debian:~/cppcheck/7840/a$ cd ..
daniel@debian:~/cppcheck/7840$ ~/cppcheck/cppcheck -E a/1.c
Checking a/1.c ...

#line 2 "a/../config.h"
X
#line 4 "a/config.h"
 A

I would like to have a minimal example. A zipped folder with source files maybe.

comment:3 by bavison, 4 years ago

Resolution: worksforme
Status: closedreopened

I am having a similar problem with #include nested too deeply and although the version numbers are slightly off, I think this ticket is referring to the same issue. Hopefully I can provide a useful test case:

$ [ -d subdir ] || mkdir subdir; touch config.h; echo "#include <config.h>" > subdir/config.h; echo "#include \"subdir/config.h\"" | cppcheck -I. /dev/stdin
Checking /dev/stdin ...
subdir/config.h:2:0: error: #include nested too deeply [preprocessorErrorDirective]
#include <config.h>
^

I think the problem is due to cppcheck's preprocessor failing to replicate a quirk of a typical compiler's preprocessor (confirmed with GCC and MSVC). The filespec in a #include is tried relative to the directory containing the source file, in addition to the include path from the command line, but only if the filespec is surrounded by double quotes, not angle brackets.

So while this command line also results in infinite recursion:

$ [ -d subdir ] || mkdir subdir; echo "#warning in outer config.h" > config.h; echo "#warning in inner config.h" > subdir/config.h; echo "#include \"config.h\"" >> subdir/config.h; echo "#include \"subdir/config.h\"" | gcc -x c -o /dev/null -c - -I.
In file included from <stdin>:1:
subdir/config.h:1:2: warning: #warning in inner config.h [-Wcpp]
    1 | #warning in inner config.h
      |  ^~~~~~~
In file included from subdir/config.h:2,
                 from <stdin>:1:
subdir/config.h:1:2: warning: #warning in inner config.h [-Wcpp]
    1 | #warning in inner config.h
      |  ^~~~~~~
In file included from subdir/config.h:2,
                 from subdir/config.h:2,
                 from <stdin>:1:
subdir/config.h:1:2: warning: #warning in inner config.h [-Wcpp]
    1 | #warning in inner config.h
      |  ^~~~~~~
In file included from subdir/config.h:2,
                 from subdir/config.h:2,
                 from subdir/config.h:2,
                 from <stdin>:1:
subdir/config.h:1:2: warning: #warning in inner config.h [-Wcpp]
    1 | #warning in inner config.h
      |  ^~~~~~~
[...]
subdir/config.h:2:20: error: #include nested too deeply
    2 | #include "config.h"
      |                    ^

This one doesn't:

$ [ -d subdir ] || mkdir subdir; echo "#warning in outer config.h" > config.h; echo "#warning in inner config.h" > subdir/config.h; echo "#include <config.h>" >> subdir/config.h; echo "#include \"subdir/config.h\"" | gcc -x c -o /dev/null -c - -I.
In file included from <stdin>:1:
subdir/config.h:1:2: warning: #warning in inner config.h [-Wcpp]
    1 | #warning in inner config.h
      |  ^~~~~~~
In file included from subdir/config.h:2,
                 from <stdin>:1:
./config.h:1:2: warning: #warning in outer config.h [-Wcpp]
    1 | #warning in outer config.h
      |  ^~~~~~~

By using git bisect, I believe cppcheck started producing the diagnostic at commit b6246ecc "bump simplecpp and update Preprocessor to handle new simplecpp::Output enum constants", although since commit 03d2829f "Merge simplecpp branch", cppcheck had simply entered an infinite loop, never completing analysis! Both of these commits fell between versions 1.74 and 1.75.

comment:4 by chrchr, 4 years ago

Keywords: simplecpp added

You might also consider opening an issue here: https://github.com/danmar/simplecpp

Last edited 4 years ago by chrchr (previous) (diff)

comment:5 by bavison, 4 years ago

Thanks for the pointer!

comment:6 by kidkat, 10 months ago

Keywords: preprocessorErrorDirective added
Note: See TracTickets for help on using tickets.