isuckatcs wrote: I ran the checker on LLVM, Clang and Clang-Tidy (`run-clang-tidy.py` in my build directory). There are a total of 33 warnings by the checker, which can be found below. I omitted the use site, where the template parameter says `Derived`, because I think that makes it obvious that it's a CRTP.
```c++ template <typename Derived, typename KeyType, typename UnversionedDataType> class VersionedTableInfo { ... }; ``` ``` .../llvm-project/clang/lib/APINotes/APINotesReader.cpp:49:7: warning: the implicit default constructor of the CRTP is publicly accessible; consider making it private and declaring the derived class as friend [bugprone-crtp-constructor-accessibility] 49 | class VersionedTableInfo { | ^ ``` ```c++ template <typename ImplT, typename IteratorT, typename CollectionT> class CalcLiveRangeUtilBase { protected: LiveRange *LR; protected: CalcLiveRangeUtilBase(LiveRange *LR) : LR(LR) {} ... } class CalcLiveRangeUtilVector; using CalcLiveRangeUtilVectorBase = CalcLiveRangeUtilBase<CalcLiveRangeUtilVector, LiveRange::iterator, LiveRange::Segments>; class CalcLiveRangeUtilVector : public CalcLiveRangeUtilVectorBase { ... } ``` ``` .../llvm-project/llvm/lib/CodeGen/LiveInterval.cpp:70:3: warning: protected contructor allows the CRTP to be inherited from as a regular template class; consider making it private and declaring the derived class as friend [bugprone-crtp-constructor-accessibility] 70 | CalcLiveRangeUtilBase(LiveRange *LR) : LR(LR) {} | ^ ``` ```c++ template <typename T> class TestVisitor : public clang::RecursiveASTVisitor<T> { ... } class ClassDeclXVisitor : public TestVisitor<ClassDeclXVisitor> { ... } ``` ``` .../llvm-project/clang/unittests/Tooling/RefactoringTest.cpp:652:7: warning: the implicit default constructor of the CRTP is publicly accessible; consider making it private and declaring the derived class as friend [bugprone-crtp-constructor-accessibility] 652 | class TestVisitor : public clang::RecursiveASTVisitor<T> { | ^ ``` ```c++ template <class Derived> struct DiagTextVisitor { ... } ``` ``` .../llvm-project/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp:725:3: warning: public contructor allows the CRTP to be constructed as a regular template class; consider making it private and declaring the derived class as friend [bugprone-crtp-constructor-accessibility] 725 | DiagTextVisitor(DiagnosticTextBuilder &Builder) : Builder(Builder) {} | ^ ``` ```c++ template <typename Derived> class OpSplitter { ... } ``` ``` .../llvm-project/llvm/lib/Transforms/Scalar/SROA.cpp:3765:5: warning: protected contructor allows the CRTP to be inherited from as a regular template class; consider making it private and declaring the derived class as friend [bugprone-crtp-constructor-accessibility] 3765 | OpSplitter(Instruction *InsertionPoint, Value *Ptr, Type *BaseTy, | ^ ``` ```c++ template <typename Derived> class Class5Tmpl : private llvm::TrailingObjects<Derived, float, int> { ... } ``` ``` .../llvm-project/llvm/unittests/Support/TrailingObjectsTest.cpp:243:7: warning: the implicit default constructor of the CRTP is publicly accessible; consider making it private and declaring the derived class as friend [bugprone-crtp-constructor-accessibility] 243 | class Class5Tmpl : private llvm::TrailingObjects<Derived, float, int> { | ^ ``` ```c++ template <typename Derived> struct SimpleTransformVisitor : public TypeVisitor<Derived, QualType> { ... } ``` ``` .../llvm-project/clang/lib/AST/Type.cpp:888:12: warning: public contructor allows the CRTP to be constructed as a regular template class; consider making it private and declaring the derived class as friend [bugprone-crtp-constructor-accessibility] 888 | explicit SimpleTransformVisitor(ASTContext &ctx) : Ctx(ctx) {} | ^ ``` ```c++ template <typename DERIVED> class ClusterAnalysis { ... } ``` ``` .../llvm-project/clang/lib/StaticAnalyzer/Core/RegionStore.cpp:721:3: warning: public contructor allows the CRTP to be constructed as a regular template class; consider making it private and declaring the derived class as friend [bugprone-crtp-constructor-accessibility] 721 | ClusterAnalysis(RegionStoreManager &rm, ProgramStateManager &StateMgr, | ^ ``` ```c++ template <typename DerivedCCG, typename FuncTy, typename CallTy> class CallsiteContextGraph { ... } ``` ``` .../llvm-project/llvm/lib/Transforms/IPO/MemProfContextDisambiguation.cpp:150:3: warning: public contructor allows the CRTP to be constructed as a regular template class; consider making it private and declaring the derived class as friend [bugprone-crtp-constructor-accessibility] 150 | CallsiteContextGraph() = default; | ^ .../llvm-project/llvm/lib/Transforms/IPO/MemProfContextDisambiguation.cpp:151:3: warning: public contructor allows the CRTP to be constructed as a regular template class; consider making it private and declaring the derived class as friend [bugprone-crtp-constructor-accessibility] 151 | CallsiteContextGraph(const CallsiteContextGraph &) = default; | ^ .../llvm-project/llvm/lib/Transforms/IPO/MemProfContextDisambiguation.cpp:152:3: warning: public contructor allows the CRTP to be constructed as a regular template class; consider making it private and declaring the derived class as friend [bugprone-crtp-constructor-accessibility] 152 | CallsiteContextGraph(CallsiteContextGraph &&) = default; | ^ ``` ```c++ template <typename DerivedT, typename IRUnitT, typename AnalysisManagerT = AnalysisManager<IRUnitT>, typename... ExtraArgTs> class MockAnalysisHandleBase { ... } ``` ``` .../llvm-project/llvm/unittests/Transforms/Scalar/LoopPassManagerTest.cpp:43:7: warning: the implicit default constructor of the CRTP is publicly accessible; consider making it private and declaring the derived class as friend [bugprone-crtp-constructor-accessibility] 43 | class MockAnalysisHandleBase { | ^ ``` ```c++ template <typename DerivedT, typename IRUnitT, typename AnalysisManagerT = AnalysisManager<IRUnitT>, typename... ExtraArgTs> class MockPassHandleBase { ... } ``` ``` .../llvm-project/llvm/unittests/Transforms/Scalar/LoopPassManagerTest.cpp:154:7: warning: the implicit default constructor of the CRTP is publicly accessible; consider making it private and declaring the derived class as friend [bugprone-crtp-constructor-accessibility] 154 | class MockPassHandleBase { | ^ ``` ```c++ template <class Derived> struct StructVisitor { ... } ``` ``` .../llvm-project/clang/lib/CodeGen/CGNonTrivialStruct.cpp:37:3: warning: public contructor allows the CRTP to be constructed as a regular template class; consider making it private and declaring the derived class as friend [bugprone-crtp-constructor-accessibility] 37 | StructVisitor(ASTContext &Ctx) : Ctx(Ctx) {} | ^ ``` In this next one there are no warnings for `CopiedTypeVisitor`, but there should be. ```c++ template <class Derived, bool IsMove> struct CopyStructVisitor : StructVisitor<Derived>, CopiedTypeVisitor<Derived, IsMove> { ... } ``` ``` .../llvm-project/clang/lib/CodeGen/CGNonTrivialStruct.cpp:83:3: warning: public contructor allows the CRTP to be constructed as a regular template class; consider making it private and declaring the derived class as friend [bugprone-crtp-constructor-accessibility] 83 | CopyStructVisitor(ASTContext &Ctx) : StructVisitor<Derived>(Ctx) {} | ^ ``` ``` .../llvm-project/clang/lib/CodeGen/CGNonTrivialStruct.cpp:150:33: warning: the implicit default constructor of the CRTP is publicly accessible; consider making it private and declaring the derived class as friend [bugprone-crtp-constructor-accessibility] 150 | template <class Derived> struct GenFuncNameBase { | ^ ``` ```c++ template <class Derived> struct GenUnaryFuncName : StructVisitor<Derived>, GenFuncNameBase<Derived> { ... } ``` ``` .../llvm-project/clang/lib/CodeGen/CGNonTrivialStruct.cpp:220:3: warning: public contructor allows the CRTP to be constructed as a regular template class; consider making it private and declaring the derived class as friend [bugprone-crtp-constructor-accessibility] 220 | GenUnaryFuncName(StringRef Prefix, CharUnits DstAlignment, ASTContext &Ctx) | ^ ``` ``` .../llvm-project/clang/lib/CodeGen/CGNonTrivialStruct.cpp:335:33: warning: the implicit default constructor of the CRTP is publicly accessible; consider making it private and declaring the derived class as friend [bugprone-crtp-constructor-accessibility] 335 | template <class Derived> struct GenFuncBase { | ^ ``` ```c++ struct GenBinaryFunc : CopyStructVisitor<Derived, IsMove>, GenFuncBase<Derived> { ... } ``` ``` .../llvm-project/clang/lib/CodeGen/CGNonTrivialStruct.cpp:509:3: warning: public contructor allows the CRTP to be constructed as a regular template class; consider making it private and declaring the derived class as friend [bugprone-crtp-constructor-accessibility] 509 | GenBinaryFunc(ASTContext &Ctx) : CopyStructVisitor<Derived, IsMove>(Ctx) {} | ^ ``` ``` .../llvm-project/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp:1983:32: warning: the implicit default constructor of the CRTP is publicly accessible; consider making it private and declaring the derived class as friend [bugprone-crtp-constructor-accessibility] 1983 | template <class Derived> class ConstraintAssignorBase { | ^ ``` ```c++ template <typename DerivedT, typename IRUnitT, typename AnalysisManagerT = AnalysisManager<IRUnitT>, typename... ExtraArgTs> class MockAnalysisHandleBase { ... } ``` ``` .../llvm-project/llvm/unittests/IR/PassBuilderCallbacksTest.cpp:44:7: warning: the implicit default constructor of the CRTP is publicly accessible; consider making it private and declaring the derived class as friend [bugprone-crtp-constructor-accessibility] 44 | class MockAnalysisHandleBase { | ^ ``` ```c++ template <typename DerivedT, typename IRUnitT, typename AnalysisManagerT = AnalysisManager<IRUnitT>, typename... ExtraArgTs> class MockPassHandleBase { ... } ``` ``` .../llvm-project/llvm/unittests/IR/PassBuilderCallbacksTest.cpp:121:7: warning: the implicit default constructor of the CRTP is publicly accessible; consider making it private and declaring the derived class as friend [bugprone-crtp-constructor-accessibility] 121 | class MockPassHandleBase { | ^ ``` In the above base class there is one use of a CRTP, `PassInfoMixin<>`, for which the check fails to report warnings, but it should be. ```c++ class MockPassHandleBase { public: class Pass : public PassInfoMixin<Pass> { ... } ... } ``` ```c++ template <class Derived> struct DestroyNRVOVariable : EHScopeStack::Cleanup { ... } ``` ``` .../llvm-project/clang/lib/CodeGen/CGDecl.cpp:518:5: warning: public contructor allows the CRTP to be constructed as a regular template class; consider making it private and declaring the derived class as friend [bugprone-crtp-constructor-accessibility] 518 | DestroyNRVOVariable(Address addr, QualType type, llvm::Value *NRVOFlag) | ^ ``` Here there are no warnings for `ConstStmtVisitor<>`, but there should be. ```c++ template <class Derived> class ExprEvaluatorBase : public ConstStmtVisitor<Derived, bool> { ... } ``` ``` .../llvm-project/clang/lib/AST/ExprConstant.cpp:7673:3: warning: public contructor allows the CRTP to be constructed as a regular template class; consider making it private and declaring the derived class as friend [bugprone-crtp-constructor-accessibility] 7673 | ExprEvaluatorBase(EvalInfo &Info) : Info(Info) {} | ^ ``` ```c++ template<class Derived> class LValueExprEvaluatorBase : public ExprEvaluatorBase<Derived> { ... } ``` ``` /home/danny/llvm-project/clang/lib/AST/ExprConstant.cpp:8311:3: warning: public contructor allows the CRTP to be constructed as a regular template class; consider making it private and declaring the derived class as friend [bugprone-crtp-constructor-accessibility] 8311 | LValueExprEvaluatorBase(EvalInfo &Info, LValue &Result, bool InvalidBaseOK) | ^ ``` ```c++ template <typename Derived, typename KeyType, typename UnversionedDataType> class VersionedTableInfo { ... } ``` ``` .../llvm-project/clang/lib/APINotes/APINotesWriter.cpp:458:7: warning: the implicit default constructor of the CRTP is publicly accessible; consider making it private and declaring the derived class as friend [bugprone-crtp-constructor-accessibility] 458 | class VersionedTableInfo { | ^ ``` ```c++ template <typename Derived, typename UnversionedDataType> class CommonTypeTableInfo : public VersionedTableInfo<Derived, ContextTableKey, UnversionedDataType> { ... } ``` ``` .../llvm-project/clang/lib/APINotes/APINotesWriter.cpp:1093:7: warning: the implicit default constructor of the CRTP is publicly accessible; consider making it private and declaring the derived class as friend [bugprone-crtp-constructor-accessibility] 1093 | class CommonTypeTableInfo | ^ ``` ```c++ template <typename Derived, typename UnversionedDataType> class CommonTypeTableInfo : public VersionedTableInfo<Derived, ContextTableKey, UnversionedDataType> { ... } ``` ``` .../llvm-project/clang/lib/APINotes/APINotesWriter.cpp:1093:7: warning: the implicit default constructor of the CRTP is publicly accessible; consider making it private and declaring the derived class as friend [bugprone-crtp-constructor-accessibility] 1093 | class CommonTypeTableInfo | ^ ``` ```c++ /// A CRTP base class for emitting expressions of retainable object /// pointer type in ARC. template <typename Impl, typename Result> class ARCExprEmitter { ... } ``` ``` .../llvm-project/clang/lib/CodeGen/CGObjC.cpp:3104:3: warning: protected contructor allows the CRTP to be inherited from as a regular template class; consider making it private and declaring the derived class as friend [bugprone-crtp-constructor-accessibility] 3104 | ARCExprEmitter(CodeGenFunction &CGF) : CGF(CGF) {} | ^ ``` ```c++ template<typename Derived, typename ResultList, typename Result, typename Subobject> class DefaultedComparisonVisitor { ... } ``` ``` .../llvm-project/clang/lib/Sema/SemaDeclCXX.cpp:7949:3: warning: public contructor allows the CRTP to be constructed as a regular template class; consider making it private and declaring the derived class as friend [bugprone-crtp-constructor-accessibility] 7949 | DefaultedComparisonVisitor(Sema &S, CXXRecordDecl *RD, FunctionDecl *FD, | ^ ``` ```c++ /// CRTP base class for visiting operations performed by a special member /// function (or inherited constructor). template<typename Derived> struct SpecialMemberVisitor { ... } ``` ``` .../llvm-project/clang/lib/Sema/SemaDeclCXX.cpp:9269:3: warning: public contructor allows the CRTP to be constructed as a regular template class; consider making it private and declaring the derived class as friend [bugprone-crtp-constructor-accessibility] 9269 | SpecialMemberVisitor(Sema &S, CXXMethodDecl *MD, Sema::CXXSpecialMember CSM, | ^ ``` ``` .../llvm-project/llvm/unittests/MIR/PassBuilderCallbacksTest.cpp:175:36: warning: the implicit default constructor of the CRTP is publicly accessible; consider making it private and declaring the derived class as friend [bugprone-crtp-constructor-accessibility] 175 | template <typename DerivedT> class MockAnalysisHandleBase { | ^ ``` ``` .../llvm-project/llvm/unittests/MIR/PassBuilderCallbacksTest.cpp:238:36: warning: the implicit default constructor of the CRTP is publicly accessible; consider making it private and declaring the derived class as friend [bugprone-crtp-constructor-accessibility] 238 | template <typename DerivedT> class MockPassHandleBase { | ^ ``` ```c++ template <typename Derived, typename KeyType, typename UnversionedDataType> class VersionedTableInfo { ... } ``` ``` .../llvm-project/clang/lib/APINotes/APINotesReader.cpp:49:7: warning: the implicit default constructor of the CRTP is publicly accessible; consider making it private and declaring the derived class as friend [bugprone-crtp-constructor-accessibility] 49 | class VersionedTableInfo { | ^ ``` TLDR, we have some false negatives, but the possitives look correct. https://github.com/llvm/llvm-project/pull/82403 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits