This is an archive of the discontinued LLVM Phabricator instance.

Fix crash in implicit default constructor creation for a template record specialization that has a field declaration with an initializer expression
AbandonedPublic

Authored by arphaman on Oct 25 2016, 7:47 AM.

Details

Reviewers
rjmccall
rsmith
Summary

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.

Diff Detail

Repository
rL LLVM

Event Timeline

arphaman updated this revision to Diff 75697.Oct 25 2016, 7:47 AM
arphaman retitled this revision from to Fix crash in implicit default constructor creation for a template record specialization that has a field declaration with an initializer expression.
arphaman updated this object.
arphaman added reviewers: rjmccall, rsmith.
arphaman set the repository for this revision to rL LLVM.
arphaman added a subscriber: cfe-commits.
rsmith added inline comments.Oct 27 2016, 12:28 AM
lib/AST/DeclCXX.cpp
1348–1349

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.

arphaman updated this revision to Diff 76029.Oct 27 2016, 7:39 AM
arphaman marked an inline comment as done.

The updated patch follows Richard's explanation and fixes the problem by checking if CTD is a member specialization without irrelevant definition checks.

lib/AST/DeclCXX.cpp
1348–1349

Yes, you're right. Thanks for pointing me in the right direction!

arphaman abandoned this revision.Oct 28 2016, 3:46 AM

Abandoning since I discovered that another patch (https://reviews.llvm.org/D13419) that's currently in review fixes this issue.