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