[PATCH] D25942: Fix crash in implicit default constructor creation for a template record specialization that has a field declaration with an initializer expression
Alex Lorenz via cfe-commits
cfe-commits at lists.llvm.org
Tue Oct 25 07:47:08 PDT 2016
arphaman created this revision.
arphaman added reviewers: rjmccall, rsmith.
arphaman added a subscriber: cfe-commits.
arphaman set the repository for this revision to rL LLVM.
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.
Repository:
rL LLVM
https://reviews.llvm.org/D25942
Files:
lib/AST/DeclCXX.cpp
test/CodeGenCXX/cxx11-crashes.cpp
Index: test/CodeGenCXX/cxx11-crashes.cpp
===================================================================
--- /dev/null
+++ test/CodeGenCXX/cxx11-crashes.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -std=c++11 %s -o - | FileCheck %s
+
+namespace rd28886662 {
+
+template<typename T>
+class A {
+public:
+ template<int i>
+ struct Inner;
+};
+
+template<>
+template<int i>
+struct A<int>::Inner {
+ int member = 42; // should be ok
+};
+
+int foo(void) {
+ return A<int>::Inner<0>().member;
+}
+
+// CHECK: _ZN10rd288866621AIiE5InnerILi0EEC2Ev
+// CHECK: store i32 42, i32* %member
+
+}
Index: lib/AST/DeclCXX.cpp
===================================================================
--- lib/AST/DeclCXX.cpp
+++ lib/AST/DeclCXX.cpp
@@ -1347,7 +1347,8 @@
auto From = TD->getInstantiatedFrom();
if (auto *CTD = From.dyn_cast<ClassTemplateDecl *>()) {
while (auto *NewCTD = CTD->getInstantiatedFromMemberTemplate()) {
- if (NewCTD->isMemberSpecialization())
+ if (NewCTD->isMemberSpecialization() ||
+ !NewCTD->isThisDeclarationADefinition())
break;
CTD = NewCTD;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D25942.75697.patch
Type: text/x-patch
Size: 1171 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20161025/44f114a5/attachment.bin>
More information about the cfe-commits
mailing list