From cf1b9c790ad9c944131e7150ef13e2d421f79e88 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Wed, 2 Sep 2009 23:02:57 +0000 Subject: [PATCH] Referenced instatiated default constructors must be defined. Fixed pr4853. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@80846 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaDeclCXX.cpp | 20 ++++++++++++++++++- test/CodeGenCXX/constructor-template.cpp | 25 +++++++++++++++++++++++- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index f80a0b88e5..a0b6e2c2f8 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -1003,7 +1003,25 @@ void Sema::ActOnMemInitializers(DeclPtrTy ConstructorDecl, if (Constructor->isDependentContext()) return; - + // Mark all constructors used in initialization of class's members + // as referenced. + // FIXME. We can do this while building the initializer list. But + // MarkDeclarationReferenced is not accessible in ASTContext. + for (CXXConstructorDecl::init_const_iterator B = Constructor->init_begin(), + E = Constructor->init_end(); + B != E; ++B) { + CXXBaseOrMemberInitializer *Member = (*B); + if (!Member->isMemberInitializer()) + continue; + FieldDecl *Field = Member->getMember(); + QualType FT = Context.getBaseElementType(Field->getType()); + if (const RecordType* RT = FT->getAs()) { + CXXConstructorDecl *Ctor = + cast(RT->getDecl())->getDefaultConstructor(Context); + if (Ctor && !FT->isDependentType()) + MarkDeclarationReferenced(Ctor->getLocation(), Ctor); + } + } if (Diags.getDiagnosticLevel(diag::warn_base_initialized) == Diagnostic::Ignored && Diags.getDiagnosticLevel(diag::warn_field_initialized) == diff --git a/test/CodeGenCXX/constructor-template.cpp b/test/CodeGenCXX/constructor-template.cpp index 10577e9766..43abda435b 100644 --- a/test/CodeGenCXX/constructor-template.cpp +++ b/test/CodeGenCXX/constructor-template.cpp @@ -1,4 +1,8 @@ -// RUN: clang-cc %s -emit-llvm -o - +// RUN: clang-cc -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s && +// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s && +// RUN: clang-cc -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s && +// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s && +// RUN: true // PR4826 struct A { @@ -13,6 +17,25 @@ struct B { A nodes; }; + +// PR4853 +template class List { +public: + List(){ } // List*>::List() remains undefined. +}; + +template class BinomialNode { +public: + BinomialNode(T value) {} + List*> nodes; +}; + int main() { B *n = new B(4); + BinomialNode *node = new BinomialNode(1); } + +// CHECK-LP64: __ZN4ListIP12BinomialNodeIiEEC1Ev: + +// CHECK-LP32:__ZN4ListIP12BinomialNodeIiEEC1Ev: + -- 2.40.0