1 //===--- ProTypeMemberInitCheck.h - clang-tidy-------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_TYPE_MEMBER_INIT_H 10 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_TYPE_MEMBER_INIT_H 11 12 #include "../ClangTidyCheck.h" 13 #include "llvm/ADT/DenseSet.h" 14 15 namespace clang { 16 namespace tidy { 17 namespace cppcoreguidelines { 18 19 /// Implements C++ Core Guidelines Type.6. 20 /// 21 /// Checks that every user-provided constructor value-initializes all class 22 /// members and base classes that would have undefined behavior otherwise. Also 23 /// check that any record types without user-provided default constructors are 24 /// value-initialized where used. 25 /// 26 /// Members initialized through function calls in the body of the constructor 27 /// will result in false positives. 28 /// 29 /// For the user-facing documentation see: 30 /// http://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidelines/pro-type-member-init.html 31 /// TODO: See if 'fixes' for false positives are optimized away by the compiler. 32 /// TODO: For classes with multiple constructors, make sure that we don't offer 33 /// multiple in-class initializer fixits for the same member. 34 class ProTypeMemberInitCheck : public ClangTidyCheck { 35 public: 36 ProTypeMemberInitCheck(StringRef Name, ClangTidyContext *Context); isLanguageVersionSupported(const LangOptions & LangOpts)37 bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { 38 return LangOpts.CPlusPlus; 39 } 40 void registerMatchers(ast_matchers::MatchFinder *Finder) override; 41 void check(const ast_matchers::MatchFinder::MatchResult &Result) override; 42 void storeOptions(ClangTidyOptions::OptionMap &Opts) override; 43 44 private: 45 // Checks Type.6 part 1: 46 // Issue a diagnostic for any constructor of a non-trivially-constructible 47 // type that does not initialize all member variables. 48 // 49 // To fix: Write a data member initializer, or mention it in the member 50 // initializer list. 51 void checkMissingMemberInitializer(ASTContext &Context, 52 const CXXRecordDecl &ClassDecl, 53 const CXXConstructorDecl *Ctor); 54 55 // A subtle side effect of Type.6 part 2: 56 // Make sure to initialize trivially constructible base classes. 57 void checkMissingBaseClassInitializer(const ASTContext &Context, 58 const CXXRecordDecl &ClassDecl, 59 const CXXConstructorDecl *Ctor); 60 61 // Checks Type.6 part 2: 62 // Issue a diagnostic when constructing an object of a trivially constructible 63 // type without () or {} to initialize its members. 64 // 65 // To fix: Add () or {}. 66 void checkUninitializedTrivialType(const ASTContext &Context, 67 const VarDecl *Var); 68 69 // Whether arrays need to be initialized or not. Default is false. 70 bool IgnoreArrays; 71 72 // Whether fix-its for initialization of fundamental type use assignment 73 // instead of brace initialization. Only effective in C++11 mode. Default is 74 // false. 75 bool UseAssignment; 76 77 // Record the member variables that have been initialized to prevent repeated 78 // initialization. 79 llvm::DenseSet<const FieldDecl *> HasRecordClassMemberSet; 80 }; 81 82 } // namespace cppcoreguidelines 83 } // namespace tidy 84 } // namespace clang 85 86 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_TYPE_MEMBER_INIT_H 87