michael_miller created this revision. michael_miller added reviewers: hokein, aaron.ballman, alexfh. michael_miller added a subscriber: cfe-commits.
Fixed a crash in cppcoreguidelines-pro-type-member-init when encountering a type that uses one of its template parameters as a base when compiling for C++98. http://reviews.llvm.org/D19539 Files: clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp test/clang-tidy/cppcoreguidelines-pro-type-member-init-cxx98.cpp Index: test/clang-tidy/cppcoreguidelines-pro-type-member-init-cxx98.cpp =================================================================== --- test/clang-tidy/cppcoreguidelines-pro-type-member-init-cxx98.cpp +++ test/clang-tidy/cppcoreguidelines-pro-type-member-init-cxx98.cpp @@ -70,26 +70,36 @@ int Z; }; -struct NonTrivialType { +struct TrivialType { int X; int Y; }; struct PositiveUninitializedBaseOrdering : public NegativeAggregateType, - public NonTrivialType { - PositiveUninitializedBaseOrdering() : NegativeAggregateType(), NonTrivialType(), B() {} + public TrivialType { + PositiveUninitializedBaseOrdering() : NegativeAggregateType(), TrivialType(), B() {} // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: A - // CHECK-FIXES: PositiveUninitializedBaseOrdering() : NegativeAggregateType(), NonTrivialType(), A(), B() {} + // CHECK-FIXES: PositiveUninitializedBaseOrdering() : NegativeAggregateType(), TrivialType(), A(), B() {} // This is somewhat pathological with the base class initializer at the end... - PositiveUninitializedBaseOrdering(int) : B(), NonTrivialType(), A() {} + PositiveUninitializedBaseOrdering(int) : B(), TrivialType(), A() {} // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these bases: NegativeAggregateType - // CHECK-FIXES: PositiveUninitializedBaseOrdering(int) : B(), NegativeAggregateType(), NonTrivialType(), A() {} + // CHECK-FIXES: PositiveUninitializedBaseOrdering(int) : B(), NegativeAggregateType(), TrivialType(), A() {} PositiveUninitializedBaseOrdering(float) : NegativeAggregateType(), A() {} - // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these bases: NonTrivialType + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these bases: TrivialType // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: constructor does not initialize these fields: B - // CHECK-FIXES: PositiveUninitializedBaseOrdering(float) : NegativeAggregateType(), NonTrivialType(), A(), B() {} + // CHECK-FIXES: PositiveUninitializedBaseOrdering(float) : NegativeAggregateType(), TrivialType(), A(), B() {} int A, B; }; + +template <class T> +class PositiveTemplateBase : T { +public: + PositiveTemplateBase() {} + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: X + // CHECK-FIXES: PositiveTemplateBase() : X() {} + + int X; +}; Index: clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp =================================================================== --- clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp +++ clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp @@ -208,8 +208,12 @@ void getInitializationsInOrder(const CXXRecordDecl *ClassDecl, SmallVectorImpl<const NamedDecl *> &Decls) { Decls.clear(); - for (const auto &Base : ClassDecl->bases()) - Decls.emplace_back(getCanonicalRecordDecl(Base.getType())); + for (const auto &Base : ClassDecl->bases()) { + // Decl may be null if the base class is a template parameter. + if (const NamedDecl *Decl = getCanonicalRecordDecl(Base.getType())) { + Decls.emplace_back(Decl); + } + } Decls.append(ClassDecl->fields().begin(), ClassDecl->fields().end()); }
Index: test/clang-tidy/cppcoreguidelines-pro-type-member-init-cxx98.cpp =================================================================== --- test/clang-tidy/cppcoreguidelines-pro-type-member-init-cxx98.cpp +++ test/clang-tidy/cppcoreguidelines-pro-type-member-init-cxx98.cpp @@ -70,26 +70,36 @@ int Z; }; -struct NonTrivialType { +struct TrivialType { int X; int Y; }; struct PositiveUninitializedBaseOrdering : public NegativeAggregateType, - public NonTrivialType { - PositiveUninitializedBaseOrdering() : NegativeAggregateType(), NonTrivialType(), B() {} + public TrivialType { + PositiveUninitializedBaseOrdering() : NegativeAggregateType(), TrivialType(), B() {} // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: A - // CHECK-FIXES: PositiveUninitializedBaseOrdering() : NegativeAggregateType(), NonTrivialType(), A(), B() {} + // CHECK-FIXES: PositiveUninitializedBaseOrdering() : NegativeAggregateType(), TrivialType(), A(), B() {} // This is somewhat pathological with the base class initializer at the end... - PositiveUninitializedBaseOrdering(int) : B(), NonTrivialType(), A() {} + PositiveUninitializedBaseOrdering(int) : B(), TrivialType(), A() {} // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these bases: NegativeAggregateType - // CHECK-FIXES: PositiveUninitializedBaseOrdering(int) : B(), NegativeAggregateType(), NonTrivialType(), A() {} + // CHECK-FIXES: PositiveUninitializedBaseOrdering(int) : B(), NegativeAggregateType(), TrivialType(), A() {} PositiveUninitializedBaseOrdering(float) : NegativeAggregateType(), A() {} - // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these bases: NonTrivialType + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these bases: TrivialType // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: constructor does not initialize these fields: B - // CHECK-FIXES: PositiveUninitializedBaseOrdering(float) : NegativeAggregateType(), NonTrivialType(), A(), B() {} + // CHECK-FIXES: PositiveUninitializedBaseOrdering(float) : NegativeAggregateType(), TrivialType(), A(), B() {} int A, B; }; + +template <class T> +class PositiveTemplateBase : T { +public: + PositiveTemplateBase() {} + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: X + // CHECK-FIXES: PositiveTemplateBase() : X() {} + + int X; +}; Index: clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp =================================================================== --- clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp +++ clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp @@ -208,8 +208,12 @@ void getInitializationsInOrder(const CXXRecordDecl *ClassDecl, SmallVectorImpl<const NamedDecl *> &Decls) { Decls.clear(); - for (const auto &Base : ClassDecl->bases()) - Decls.emplace_back(getCanonicalRecordDecl(Base.getType())); + for (const auto &Base : ClassDecl->bases()) { + // Decl may be null if the base class is a template parameter. + if (const NamedDecl *Decl = getCanonicalRecordDecl(Base.getType())) { + Decls.emplace_back(Decl); + } + } Decls.append(ClassDecl->fields().begin(), ClassDecl->fields().end()); }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits