From 42dddbeadb82a918d83c14bdcce47ba8c0ed6fba Mon Sep 17 00:00:00 2001 From: Sebastian Redl Date: Sun, 8 Nov 2009 10:16:43 +0000 Subject: [PATCH] Don't reprocess non-dependent initializers of non-dependent VarDecls. Fixes PR5426. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@86460 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaTemplateInstantiateDecl.cpp | 9 +++++++++ test/SemaTemplate/instantiate-decl-init.cpp | 22 +++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 test/SemaTemplate/instantiate-decl-init.cpp diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 5ae7289ea5..641ea24427 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -186,6 +186,15 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) { = SemaRef.SubstExpr(D->getInit(), TemplateArgs); if (Init.isInvalid()) Var->setInvalidDecl(); + else if (!D->getType()->isDependentType() && + !D->getInit()->isTypeDependent() && + !D->getInit()->isValueDependent()) { + // If neither the declaration's type nor its initializer are dependent, + // we don't want to redo all the checking, especially since the + // initializer might have been wrapped by a CXXConstructExpr since we did + // it the first time. + Var->setInit(SemaRef.Context, Init.takeAs()); + } else if (ParenListExpr *PLE = dyn_cast((Expr *)Init.get())) { // FIXME: We're faking all of the comma locations, which is suboptimal. // Do we even need these comma locations? diff --git a/test/SemaTemplate/instantiate-decl-init.cpp b/test/SemaTemplate/instantiate-decl-init.cpp new file mode 100644 index 0000000000..d957f2de7d --- /dev/null +++ b/test/SemaTemplate/instantiate-decl-init.cpp @@ -0,0 +1,22 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +// PR5426 - the non-dependent obj would be fully processed and wrapped in a +// CXXConstructExpr at definition time, which would lead to a failure at +// instantiation time. +struct arg { + arg(); +}; + +struct oldstylemove { + oldstylemove(oldstylemove&); + oldstylemove(const arg&); +}; + +template +void fn(T t, const arg& arg) { + oldstylemove obj(arg); +} + +void test() { + fn(1, arg()); +}