From 49c774717c475d2a77cdc59c066ee2e2085d3edf Mon Sep 17 00:00:00 2001 From: Ilya Biryukov Date: Thu, 28 Dec 2017 13:05:46 +0000 Subject: [PATCH] [Frontend] Correctly handle instantiating ctors with skipped bodies Summary: Previsouly clang tried instantiating member initializers even if ctor body was skipped, this caused spurious errors (see the test). Reviewers: sepavloff, klimek Reviewed By: sepavloff Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D41492 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@321520 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaTemplateInstantiateDecl.cpp | 26 ++++++++++++------------ test/Index/skipped-bodies-ctors.cpp | 16 +++++++++++++++ 2 files changed, 29 insertions(+), 13 deletions(-) create mode 100644 test/Index/skipped-bodies-ctors.cpp diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 1deb863875..d8af8f3453 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -3932,22 +3932,22 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, TemplateArgs)) return; - if (CXXConstructorDecl *Ctor = dyn_cast(Function)) { - // If this is a constructor, instantiate the member initializers. - InstantiateMemInitializers(Ctor, cast(PatternDecl), - TemplateArgs); - - // If this is an MS ABI dllexport default constructor, instantiate any - // default arguments. - if (Context.getTargetInfo().getCXXABI().isMicrosoft() && - Ctor->isDefaultConstructor()) { - InstantiateDefaultCtorDefaultArgs(*this, Ctor); - } - } - if (PatternDecl->hasSkippedBody()) { ActOnSkippedFunctionBody(Function); } else { + if (CXXConstructorDecl *Ctor = dyn_cast(Function)) { + // If this is a constructor, instantiate the member initializers. + InstantiateMemInitializers(Ctor, cast(PatternDecl), + TemplateArgs); + + // If this is an MS ABI dllexport default constructor, instantiate any + // default arguments. + if (Context.getTargetInfo().getCXXABI().isMicrosoft() && + Ctor->isDefaultConstructor()) { + InstantiateDefaultCtorDefaultArgs(*this, Ctor); + } + } + // Instantiate the function body. StmtResult Body = SubstStmt(Pattern, TemplateArgs); diff --git a/test/Index/skipped-bodies-ctors.cpp b/test/Index/skipped-bodies-ctors.cpp new file mode 100644 index 0000000000..8a559ee0c7 --- /dev/null +++ b/test/Index/skipped-bodies-ctors.cpp @@ -0,0 +1,16 @@ +// RUN: env CINDEXTEST_SKIP_FUNCTION_BODIES=1 c-index-test -test-load-source all %s 2>&1 \ +// RUN: | FileCheck --implicit-check-not "error:" %s + + +template +struct Foo { + template + Foo(int &a) : a(a) { + } + + int &a; +}; + + +int bar = Foo(bar).a + Foo(bar).a; +// CHECK-NOT: error: constructor for 'Foo' must explicitly initialize the reference -- 2.50.1