[PATCH] D18584: Complete support for C++ Core Guidelines Type.6: Always initialize a member variable.
Aaron Ballman via cfe-commits
cfe-commits at lists.llvm.org
Tue Apr 5 09:29:37 PDT 2016
aaron.ballman added a subscriber: aaron.ballman.
aaron.ballman requested changes to this revision.
aaron.ballman added a reviewer: aaron.ballman.
This revision now requires changes to proceed.
================
Comment at: clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp:25
@@ -24,3 +24,3 @@
-namespace {
----------------
Please do not remove the unnamed namespace; it is preferable to using static functions.
================
Comment at: clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp:30
@@ +29,3 @@
+ const auto *ClassDecl = dyn_cast<CXXRecordDecl>(&RecordDecl);
+ // Non-C++ records are always trivially constructible
+ if (!ClassDecl)
----------------
Missing a period at the end of the sentence.
================
Comment at: clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp:33
@@ +32,3 @@
+ return true;
+ // A class is trivially constructible if it has a default constructor.
+ if (ClassDecl->hasUserProvidedDefaultConstructor())
----------------
This comment doesn't match the behavior of the code below.
================
Comment at: clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp:104
@@ -35,3 +103,3 @@
QualType Type = F->getType();
- if (Type->isPointerType() || Type->isBuiltinType())
+ if (!F->hasInClassInitializer() and isTriviallyConstructible(Context, Type))
FieldsToInit.insert(F);
----------------
Please use `&&` instead of `and`.
================
Comment at: clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp:152
@@ +151,3 @@
+
+AST_MATCHER(CXXConstructorDecl, isUserProvided) {
+ return Node.isUserProvided();
----------------
This should probably be made more generally available as an AST matcher.
================
Comment at: clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp:156
@@ +155,3 @@
+
+AST_MATCHER(RecordDecl, isTriviallyDefaultConstructible) {
+ return isTriviallyConstructible(Finder->getASTContext(), Node);
----------------
I think this matcher logic should go into utils\TypeTraits.cpp as it seems more generally useful than just this check.
================
Comment at: clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp:160
@@ +159,3 @@
+
+AST_MATCHER(CXXConstructorDecl, isDelegatingConstructor) {
+ return Node.isDelegatingConstructor();
----------------
As should this.
================
Comment at: clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp:187
@@ -87,5 +186,3 @@
const CXXConstructorDecl &Constructor) const {
- if (InitializerBefore != nullptr) {
- return Lexer::getLocForEndOfToken(InitializerBefore->getRParenLoc(), 0,
- Context.getSourceManager(),
- Context.getLangOpts());
+ assert(Where != nullptr or Placement == InitializerPlacement::New);
+ SourceLocation Location;
----------------
Please use `||` instead of `or`. Also, asserts should usually have `&& "Some explanatory text"` for when the assert is triggered.
================
Comment at: clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp:243
@@ +242,3 @@
+// initializer.
+static const NamedDecl *getInitializerDecl(const CXXCtorInitializer *Init) {
+ if (Init->isMemberInitializer())
----------------
Since this function is only used once, I think it should be lowered into its use as a ternary conditional.
================
Comment at: clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp:256
@@ +255,3 @@
+ SmallVector<IntializerInsertion, 16> Insertions;
+ Insertions.push_back({InitializerPlacement::New, nullptr, {}});
+
----------------
Please do not use an initializer list like this, I believe it won't work in MSVC 2013. (Here and elsewhere as well.)
================
Comment at: clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp:258
@@ -142,1 +257,3 @@
+
+ auto Decl = std::begin(OrderedDecls);
for (const CXXCtorInitializer *Init : Inits) {
----------------
Please only use `auto` when the type name is spelled out as part of the initializer, or it is used as a for-range initializer.
================
Comment at: clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp:296
@@ +295,3 @@
+ Decls.clear();
+ for (const CXXBaseSpecifier &Base : ClassDecl->bases())
+ Decls.emplace_back(getRecordDecl(Base.getType()));
----------------
Can use `const auto &` here instead.
================
Comment at: clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp:323
@@ -171,5 +322,3 @@
void ProTypeMemberInitCheck::registerMatchers(MatchFinder *Finder) {
- Finder->addMatcher(cxxConstructorDecl(isDefinition(), isUserProvided(),
- unless(isInstantiated()))
- .bind("ctor"),
- this);
+ auto IsUserProvidedNonDelegatingConstructor =
+ allOf(isUserProvided(),
----------------
Since this is a C++ core guideline, I think the matchers should only be registered when compiling for C++. It may make sense to use a similar check in C mode, but we can cross that bridge when we come to it (and have tests for it).
================
Comment at: clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp:486
@@ +485,3 @@
+
+ // Do not propose fixes in macros since we cannot place them correctly.
+ if (Ctor->getLocStart().isMacroID())
----------------
I think this code belongs in `fixInitializerList` then, doesn't it?
================
Comment at: clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp:497
@@ +496,3 @@
+ diag(Var->getLocStart(), "uninitialized record type: %0")
+ << Var->getName().str();
+
----------------
You should be able to pass in `Var` directly.
================
Comment at: test/clang-tidy/cppcoreguidelines-pro-type-member-init.cpp:285
@@ +284,3 @@
+union NegativeUnionInClass {
+ NegativeUnionInClass() {} // No message as a union can only initialize on member
+ int X = 0;
----------------
s/on/one
================
Comment at: test/clang-tidy/cppcoreguidelines-pro-type-member-init.cpp:291
@@ +290,3 @@
+union PositiveUnion {
+ PositiveUnion() : X() {} // No message as a union can only initialize on member
+ PositiveUnion(int) {}
----------------
s/on/one
================
Comment at: test/clang-tidy/cppcoreguidelines-pro-type-member-init.cpp:334
@@ +333,2 @@
+ // CHECK-FIXES: int X{};
+};
----------------
I'd like to see how we handle the following test:
```
struct S {
S(int i);
};
struct T {
T(float f);
};
union U {
S s;
T t;
};
```
http://reviews.llvm.org/D18584
More information about the cfe-commits
mailing list