This is an archive of the discontinued LLVM Phabricator instance.

[clang-tidy] Add readability test for not allowing relative includes
AbandonedPublic

Authored by ErezAmihud on Jun 9 2023, 3:19 PM.

Details

Summary

This pr adds a check that warns if it finds a relative include. This is to allow people to easily conform to the canonical project structure - https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1204r0.html

tl;dr The check issue a warning for every relative include (e.g. any include that uses regular quotes).

Github issue:
https://github.com/llvm/llvm-project/issues/63226

Diff Detail

Event Timeline

ErezAmihud created this revision.Jun 9 2023, 3:19 PM
ErezAmihud created this object with edit policy "Administrators".
Herald added a project: Restricted Project. · View Herald TranscriptJun 9 2023, 3:19 PM
ErezAmihud requested review of this revision.Jun 9 2023, 3:19 PM
ErezAmihud edited the summary of this revision. (Show Details)Jun 9 2023, 3:19 PM
ErezAmihud updated this revision to Diff 530102.Jun 9 2023, 3:36 PM

Remove a line in absolute-includes-only.cpp (fix formatting)

ErezAmihud changed the edit policy from "Administrators" to "All Users".Jun 9 2023, 3:59 PM
Eugene.Zelenko edited reviewers, added: PiotrZSL, carlosgalvezp; removed: Restricted Project. Eugene.Zelenko removed 1 blocking reviewer(s): njames93.Jun 9 2023, 4:08 PM
Eugene.Zelenko set the repository for this revision to rG LLVM Github Monorepo.
Eugene.Zelenko added a subscriber: Eugene.Zelenko.
Eugene.Zelenko added inline comments.
clang-tools-extra/clang-tidy/readability/AbsoluteIncludesOnlyCheck.cpp
17

Excessive newline.

clang-tools-extra/docs/ReleaseNotes.rst
187

Please make it as first statement in documentation.

clang-tools-extra/docs/clang-tidy/checks/readability/absolute-includes-only.rst
9

Please highlight "" and <> with double back-ticks. Please follow 80-characters limit.

18

Please split example on right and wrong blocks.

clang-tools-extra/test/clang-tidy/checkers/readability/absolute-includes-only.cpp
14

Excessive newline.

18

Ditto.

Eugene.Zelenko retitled this revision from Add readability test for not allowing relative includes to [clang-tidy] Add readability test for not allowing relative includes.Jun 9 2023, 4:09 PM
PiotrZSL requested changes to this revision.Jun 10 2023, 12:19 AM

First this looks like "misc" check, not as "readability" one. So please move it to proper module. There is no "readability" aspect of it.
Second thing this is not an "absolute", absolute would be #include "/usr/includes/stdio", with this style you can still use relative paths like #include <../something>
Proper names then would be one of: misc-no-quote-includes or misc-use-angle-bracket-includes (this one looks to sound better), choose one, any.

and again naming, those are not relative and absolute, those are quote and angle-bracket, avoid confusion with path put into include.

clang-tools-extra/clang-tidy/readability/AbsoluteIncludesOnlyCheck.cpp
43

inline this method in AbsoluteIncludesOnlyPPCallbacks no need to keep it out of class.

48

i think that Imported!=nullptr should also do a trick, but this way shoud be fine. Check if getIdentifierInfo is not null to be sure

51

getLocWithOffset(0) does nothing, remove

53–54
  1. You could provide auto-fix here, but if you do not want to do that its fine.
  2. Warning is a default, no need to specify it.
  3. put included header name into message, it will make way easier for reader to find out whats going on
  4. consider excluding includes included from system headers on this level, otherwise check may generate lot of includes that going to be filter out later in process, but that still may be costly.
clang-tools-extra/docs/ReleaseNotes.rst
188

sounds like "do not eat cheese, eat cheese", align later this documentation with check name

clang-tools-extra/docs/clang-tidy/checks/readability/absolute-includes-only.rst
11

format this url properly, look into other checks how they do it in documentation

11

80 characters limit

17

uncomment those includes

18

whats wrong here ? check wont raise warning here

This revision now requires changes to proceed.Jun 10 2023, 12:19 AM

One more comment, according to this whitepaper you should actually check if include is relative, simply if current file directory + include exists and it's actually a file that is included, then its relative include.
Currently you checking only "" and its not a thing that should be done, because include like this `#include "hello/utility.hpp" is also valid.
Therefor you should be checking included path, not an include style, and this is main problem of this check.
In such case proper name for it would be misc-no-relative-includes, and entire implementation of the check should be updated.
Also note that some projects put header files in same folder as source file, and uses "" include for them, this is one of the ways to deal with private/public includes.

Even with that for me for example, I would consider #include "xyz" be fine, but #include "../xyz" would be a red flag, so please consider adding StrictMode option to check so if StrictMode is not set then includes from same directory, or subdirectory would be allowed, but includes that contain .. would not.
With that settings, I could use that check, and probably many other users could.

ErezAmihud added a comment.EditedJun 13 2023, 11:57 AM

Even with that for me for example, I would consider #include "xyz" be fine, but #include "../xyz" would be a red flag, so please consider adding StrictMode option to check so if StrictMode is not set then includes from same directory, or subdirectory would be allowed, but includes that contain .. would not.
With that settings, I could use that check, and probably many other users could.

I want to make sure I understand.
The ideal situation would be to create misc-no-relative-includes check that checks for .. in paths (meaning - relative paths), and have a StrictMode which does the check for angled-bracket includes?

BTW The reason I initially checked for angled-bracket includes is that according to this quote includes search in paths relative to the current file, and the angled-bracket includes check only in the defined include directories.
In this case there is no risk that the include would get a file that is not relative to the include directory the user specified in the compile flags.

PiotrZSL added a comment.EditedJun 13 2023, 12:03 PM

I want to make sure I understand.
The ideal situation would be to create misc-no-relative-includes check that checks for .. in paths (meaning - relative paths), and have a StrictMode which does the check for angled-bracket includes?

BTW The reason I initially checked for angled-bracket includes is that according to this quote includes search in paths relative to the current file, and the angled-bracket includes check only in the defined include directories.
In this case there is no risk that the include would get a file that is not relative to the include directory the user specified in the compile flags.

But according to paper you can also do -I<path to .cpp directory> and in .cpp you can do #include <header.hpp> and if that header.hpp exist near .cpp then this is still relative include.
For me we should do something like this:

path_to_cpp_directory = absolutepath(dirname(main-file))
include_file = argument to #include <> or #include ""
if (actually_included_file_is(path_to_cpp_directory  + include_file))
  if (StrictMode || !absolutepath(path_to_cpp_directory  + include_file).starts_with(path_to_cpp_directory))
       // relative include, generate warning
ErezAmihud abandoned this revision.Jul 21 2023, 1:55 AM

Closed, because I don't have time to work on it