This patch fixes a NULL pointer crash that happens when clang is trying to create an implicit default constructor for a specialization of a record template which is defined in a specialization of a parent record template and has a field declaration with an initializer expression.
The following piece of code reproduces this problem:
template<typename T> class A { public: template<int i> struct Inner; }; template<> template<int i> struct A<int>::Inner { int member = 42; }; int main(void) { return A<int>::Inner<0>().member; }
The crash happens because CXXRecordDecl::getTemplateInstantiationPattern returns nil when instantiating A<int>::Inner<0>, because it tries to get the instantiation pattern from the declaration of Inner (which has no definition and thus no instantiation pattern), rather than the specialized definition of Inner. This patch fixes this by making sure that the instantiation pattern comes from the definition rather than the declaration of the record template.
We should be stopping at A<int>::Inner because it's a member specialization; whether the primary template had a declaration or a definition is irrelevant. It looks like the problem is that the member specialization check is checking the wrong declaration; we should be checking CTD not NewCTD here.