◐ Shell
reader mode source ↗
Skip to content

Includes of system headers are never implicitly relative to the source file#282

Merged
danmar merged 1 commit into
cppcheck-opensource:masterfrom
bavison:fix-angle-includes
Jan 18, 2023
Merged

Includes of system headers are never implicitly relative to the source file#282
danmar merged 1 commit into
cppcheck-opensource:masterfrom
bavison:fix-angle-includes

Conversation

@bavison

@bavison bavison commented Dec 20, 2022

Copy link
Copy Markdown
Contributor

Sometimes, #include directives with angle-bracket filespec delimiters are used (or abused) to defeat the preprocessor's behaviour where it tries to find a header file at a path relative to the file containing the directive.

Without this fix, any non-root header file, foo/bar.h, which does

  #include <bar.h>

while intending to include a root-level header file, will instead enter an infinite inclusion loop, terminating when the inclusion stack overflows with a #include nested too deeply error.

See also this cppcheck issue.

@danmar

danmar commented Dec 20, 2022

Copy link
Copy Markdown
Collaborator

is it possible to write some test for this? Something similar to this maybe:

static void nestedInclude()

@bavison

bavison commented Dec 21, 2022

Copy link
Copy Markdown
Contributor Author

Hope this will do - the test detects the difference between the old and new simplecpp behaviour. I found I had to create an empty limits.h file in the filedata map, since I guess simplecpp::preprocess doesn't know that's a standard header.

@firewave

Copy link
Copy Markdown
Collaborator

This is scary. I finally got around to checking why the issue I introduced in #276 and fixed in #281 did not trigger any test failures. And it turns out it is caused by the same code you just fixed.

simplecpp is completely void of tests with additional files at the moment. That has been a source of discussion in #261.

There's also tests lacking in cppcheck which I have partially added locally.

@danmar

danmar commented Jan 7, 2023

Copy link
Copy Markdown
Collaborator

hmm.. I feel I can merge this. However when I try it locally it does not seem to work.

I have this code in my file 1.c:

#include <1.h>

And 1.h contains:

int x;

when I run simplecpp with command simplecpp 1.c it includes the 1.h file.

It works as it should for you?

@firewave

firewave commented Jan 7, 2023

Copy link
Copy Markdown
Collaborator

hmm.. I feel I can merge this. However when I try it locally it does not seem to work.

That's why we need unit tests with headers/includes...

@danmar

danmar commented Jan 7, 2023

Copy link
Copy Markdown
Collaborator

The title of this PR says that "system headers are never relative to the source file". That is not true.

See:

$ gcc -E 1.c
1.c:1:10: fatal error: 1.h: No such file or directory

$ gcc -E -I. 1.c
=> 1.h is included.

…e file

Sometimes, #include directives with angle-bracket filespec delimiters are
used (or abused) to defeat the preprocessor's behaviour where it tries to
find a header file at a path relative to the file containing the directive.

Without this fix, any non-root header file, foo/bar.h, which does
  #include <bar.h>
while intending to include a root-level header file, will instead enter an
infinite inclusion loop, terminating when the inclusion stack overflows
with a "#include nested too deeply" error.
@bavison bavison force-pushed the fix-angle-includes branch from 2b73c45 to 81808f8 Compare January 10, 2023 16:04
@bavison

bavison commented Jan 10, 2023

Copy link
Copy Markdown
Contributor Author

when I run simplecpp with command simplecpp 1.c it includes the 1.h file.

That looks to have been caused by openHeader() also attempting to find a system header at a path relative to the source file. My latest push should have fixed that. Unfortunately, I haven't managed to work out how to make the unit test framework detect this change, but running the simplecpp binary on your 1.c now has the desired behaviour (it fails unless you explicitly use -I.).

The title of this PR says that "system headers are never relative to the source file". That is not true.

OK, I have added the word "implicitly" into the commit summary, hope this is sufficient.

For what it's worth, I found the following description in the gcc man page (I realise this isn't unversal to all compilers):

           The lookup order is as follows:

           1.  For the quote form of the include directive, the directory of
               the current file is searched first.

           2.  For the quote form of the include directive, the directories
               specified by -iquote options are searched in left-to-right
               order, as they appear on the command line.

           3.  Directories specified with -I options are scanned in left-to-
               right order.

           4.  Directories specified with -isystem options are scanned in
               left-to-right order.

           5.  Standard system directories are scanned.

           6.  Directories specified with -idirafter options are scanned in
               left-to-right order.

@bavison bavison changed the title Includes of system headers are never relative to the source file Jan 10, 2023
@firewave

Copy link
Copy Markdown
Collaborator

Unfortunately, I haven't managed to work out how to make the unit test framework detect this change

I will add such tests to Cppcheck soon with the referenced PR.

@danmar

danmar commented Jan 18, 2023

Copy link
Copy Markdown
Collaborator

Thanks I think this looks good. If CI is happy I'll merge it. Let's consider the testing later separately. I also think we could explore using pytest in simplecpp.

@danmar danmar merged commit 7c5b21d into cppcheck-opensource:master Jan 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants