Index: lib/Sema/SemaExprCXX.cpp =================================================================== --- lib/Sema/SemaExprCXX.cpp +++ lib/Sema/SemaExprCXX.cpp @@ -2487,8 +2487,22 @@ MismatchingNewDeleteDetector::MismatchResult MismatchingNewDeleteDetector::analyzeInClassInitializer() { assert(Field != nullptr && "This should be called only for members"); - if (const CXXNewExpr *NE = - getNewExprFromInitListOrExpr(Field->getInClassInitializer())) { + const Expr *InitExpr = Field->getInClassInitializer(); + if (!InitExpr) { + CXXRecordDecl *ParentRD = cast(Field->getParent()); + TemplateSpecializationKind TSK = ParentRD->getTemplateSpecializationKind(); + if (isTemplateInstantiation(TSK)) { + CXXRecordDecl *ClassPattern = ParentRD->getTemplateInstantiationPattern(); + if (Field->hasInClassInitializer() && TSK == TSK_ImplicitInstantiation) { + DeclContext::lookup_result Lookup = + ClassPattern->lookup(Field->getDeclName()); + assert(Lookup.size() == 1); + FieldDecl *Pattern = cast(Lookup[0]); + InitExpr = Pattern->getInClassInitializer(); + } + } + } + if (const CXXNewExpr *NE = getNewExprFromInitListOrExpr(InitExpr)) { if (NE->isArray() != IsArrayForm) { NewExprs.push_back(NE); return MemberInitMismatches; Index: test/SemaCXX/delete.cpp =================================================================== --- test/SemaCXX/delete.cpp +++ test/SemaCXX/delete.cpp @@ -120,6 +120,22 @@ DELETE(d); // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}} } } + +namespace MissingInitializer { +template +struct Base { + struct S { + const T *p1 = nullptr; + const T *p2 = new T[3]; // expected-note {{allocated with 'new[]' here}} + }; +}; + +void null_init(Base::S s) { + delete s.p1; + delete s.p2; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}} +} +} + #ifndef WITH_PCH pch_test::X::X() : a(new int[1]) // expected-note{{allocated with 'new[]' here}}