[PATCH] D15710: [clang-tidy] Add non-inline function definition and variable definition check in header files.
Aaron Ballman via cfe-commits
cfe-commits at lists.llvm.org
Sun Dec 27 07:04:38 PST 2015
aaron.ballman added a subscriber: aaron.ballman.
================
Comment at: clang-tidy/misc/DefinitionsInHeadersCheck.cpp:22
@@ +21,3 @@
+
+bool inHeaderFile(const SourceManager* SM, SourceLocation Location) {
+ StringRef Filename = SM->getFilename(SM->getExpansionLoc(Location));
----------------
This should use isInMainFile() instead of checking the file extension.
================
Comment at: clang-tidy/misc/DefinitionsInHeadersCheck.cpp:30
@@ +29,3 @@
+void DefinitionsInHeadersCheck::registerMatchers(MatchFinder *Finder) {
+ Finder->addMatcher(
+ decl(anyOf(functionDecl(isDefinition()),
----------------
I wonder if you could use an AST matcher to weed out definitions that are in the main file to make the matcher a bit more narrow.
================
Comment at: clang-tidy/misc/DefinitionsInHeadersCheck.cpp:36
@@ +35,3 @@
+void DefinitionsInHeadersCheck::check(const MatchFinder::MatchResult &Result) {
+ // C++ [basic.def.odr]:
+ // There can be more than one definition of a class type, enumeration type,
----------------
Please quote the paragraph as well (p6, in this case).
================
Comment at: clang-tidy/misc/DefinitionsInHeadersCheck.cpp:44
@@ +43,3 @@
+ // satisfy the following requirements.
+ const auto* ND = Result.Nodes.getNodeAs<NamedDecl>("decl");
+ if (!ND)
----------------
Should be declared: `const auto *ND` (note the position of the *). May want to run clang-format over your patch, as this applies elsewhere as well.
================
Comment at: clang-tidy/misc/DefinitionsInHeadersCheck.cpp:49
@@ +48,3 @@
+ return;
+ // Internal linkage variable and function definitions are allowed:
+ // const int a = 1;
----------------
Why are these allowed? They can result in ODR violations if they are in a header file.
================
Comment at: clang-tidy/misc/DefinitionsInHeadersCheck.cpp:69
@@ +68,3 @@
+ return;
+ // Member function of a class template and member function of a nest class
+ // in a class template are allowed.
----------------
nest -> nested
================
Comment at: clang-tidy/misc/DefinitionsInHeadersCheck.cpp:77
@@ +76,3 @@
+ return;
+ DC = DC->getLookupParent();
+ }
----------------
Why the lookup parent instead of getParent()? Also, can this ever return a nullptr?
================
Comment at: clang-tidy/misc/DefinitionsInHeadersCheck.cpp:85
@@ +84,3 @@
+ } else if (const auto* VD = dyn_cast<VarDecl>(ND)) {
+ // static data member of a class template is allowed.
+ if (VD->getDeclContext()->isDependentContext() &&
----------------
static -> Static
================
Comment at: clang-tidy/misc/DefinitionsInHeadersCheck.h:19
@@ +18,3 @@
+
+// Finds non-extern non-inline function dand variable definitions in header
+// files, which can lead to potential ODR violations.
----------------
dand -> and
================
Comment at: docs/clang-tidy/checks/misc-definitions-in-headers.rst:17
@@ +16,3 @@
+ namespace {
+ int c = 2; // ok
+ }
----------------
I don't think that this should be okay (same with static/const int examples above). See https://www.securecoding.cert.org/confluence/display/cplusplus/DCL59-CPP.+Do+not+define+an+unnamed+namespace+in+a+header+file for more details.
================
Comment at: unittests/clang-tidy/MiscModuleTest.cpp:38
@@ -36,1 +37,3 @@
+class DefinitionsInHeadersCheckTest : public ::testing::Test {
+protected:
----------------
Is there a reason this is under unittests instead of as actual clang-tidy test files? I would prefer to see this run through clang-tidy on the shell instead of in the unit tests, unless there's something we cannot otherwise test.
http://reviews.llvm.org/D15710
More information about the cfe-commits
mailing list