This is an archive of the discontinued LLVM Phabricator instance.

[clang-tidy] DefinitionsInHeadersCheck: Added option for checking C Code
Needs ReviewPublic

Authored by schrc3b6 on Oct 15 2021, 2:41 PM.

Details

Summary

Eventhough there are no OCR rules in the C standard, to my
knowledge, it is recommended to not include definitions in header files.
This Patch introduces the CheckCCode Option which add C99 to the
language check. Since this checker was original written for C++ it
is off by default.

Diff Detail

Event Timeline

schrc3b6 created this revision.Oct 15 2021, 2:41 PM
schrc3b6 updated this revision to Diff 380104.Oct 15 2021, 3:01 PM

fixed typo

schrc3b6 published this revision for review.Oct 15 2021, 3:25 PM
Herald added a project: Restricted Project. · View Herald TranscriptOct 15 2021, 3:25 PM
Herald added a subscriber: cfe-commits. · View Herald Transcript

This is my first PR here, so if I missed something, I will be more than happy to change anything if you point me in the right direction.

I didn't add an extra test so far, because check_clang_tidy.py doesn't support the .h extension so far. And before adding C support to the test helper, I wanted to get feedback if this is something that would even get mainlined, since clang-tidy is mainly for c++.

It would be interesting to add a test for this. I've recently came across the fact that Clang doesn't support common linkage definitions, namely that in C (but not in C++), if you do the following:

int I;
void f1(void) {}
int I;
void f2(void) {}

and compile these two source files and link them together, the two Is will refer in the resulting binary to the same symbol. (You must not put an initialiser here!) Will int I; being in a header, with no initialiser, be caught?

clang-tools-extra/clang-tidy/misc/DefinitionsInHeadersCheck.h
26
clang-tools-extra/docs/clang-tidy/checks/misc-definitions-in-headers.rst
109

Will int I; being in a header, with no initialiser, be caught?

Currently it will be caught.

1 warning generated.
./foo.h:1:5: warning: variable 'i' defined in a header file; variable definitions in header files can lead to ODR violations [misc-definitions-in-headers]
int i;

I guess you don't want that to be cought if it is actually a tentative definition. If I remember correctly for clang and gcc -fno-common is the default.
I think we could do one of two things here either create no warning if there is a VarDelc without initialization or we could try to detect common linkage.
I will have a look if I can detect a change from inside the checker if the linkage of the variable changes via the fcommon compiler flag.

It would be interesting to add a test for this.

I will do so.

Thanks for the feedback.

I guess you don't want that to be cought if it is actually a tentative definition. If I remember correctly for clang and gcc -fno-common is the default.
I think we could do one of two things here either create no warning if there is a VarDelc without initialization or we could try to detect common linkage.
I will have a look if I can detect a change from inside the checker if the linkage of the variable changes via the fcommon compiler flag.

My personal belief after having encountered common linkage is that it is disgusting and it's good that Clang doesn't support them (by default).

But I do not have any stake or practical experience with working long term on C programs to have a well-educated opinion on this.