From: Douglas Gregor Date: Fri, 3 Jun 2011 03:35:07 +0000 (+0000) Subject: When performing template argument deduction given a function argument X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f15748a28c8443eef2924ef83689c358c661e9c5;p=clang When performing template argument deduction given a function argument of incomplete array type, attempt to complete the array type. This was made much easier by Chandler's addition of RequireCompleteExprType(), which I've tweaked (slightly) to improve the consistency of the DeclRefExpr. Fixes PR7985. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@132530 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index ed1b671bf4..7d0ce8b2e7 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/lib/Sema/SemaTemplateDeduction.cpp @@ -2500,6 +2500,12 @@ static bool AdjustFunctionParmAndArgTypesForDeduction(Sema &S, if (ParamRefType) { QualType PointeeType = ParamRefType->getPointeeType(); + // If the argument has incomplete array type, try to complete it's type. + if (ArgType->isIncompleteArrayType() && + !S.RequireCompleteExprType(Arg, S.PDiag(), + std::make_pair(SourceLocation(), S.PDiag()))) + ArgType = Arg->getType(); + // [C++0x] If P is an rvalue reference to a cv-unqualified // template parameter and the argument is an lvalue, the type // "lvalue reference to A" is used in place of A for type diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index cd08b1e3df..22db4c8f61 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -2555,6 +2555,10 @@ void Sema::InstantiateStaticDataMemberDefinition( == TSK_ExplicitInstantiationDeclaration) return; + // If we already have a definition, we're done. + if (Var->getDefinition()) + return; + InstantiatingTemplate Inst(*this, PointOfInstantiation, Var); if (Inst) return; diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 9fccdb11c5..02bcb2b89e 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -3280,9 +3280,13 @@ bool Sema::RequireCompleteExprType(Expr *E, const PartialDiagnostic &PD, InstantiateStaticDataMemberDefinition(E->getExprLoc(), Var); // Update the type to the newly instantiated definition's type both // here and within the expression. - T = Var->getDefinition()->getType(); - E->setType(T); - + if (VarDecl *Def = Var->getDefinition()) { + DRE->setDecl(Def); + T = Def->getType(); + DRE->setType(T); + E->setType(T); + } + // We still go on to try to complete the type independently, as it // may also require instantiations or diagnostics if it remains // incomplete. diff --git a/test/SemaTemplate/instantiate-init.cpp b/test/SemaTemplate/instantiate-init.cpp index d5711ddf5a..ce2c1633b1 100644 --- a/test/SemaTemplate/instantiate-init.cpp +++ b/test/SemaTemplate/instantiate-init.cpp @@ -73,3 +73,26 @@ namespace PR10001 { int x = S::f(); } + +namespace PR7985 { + template struct integral_c { }; + + template + integral_c array_lengthof(T (&x)[N]) { return integral_c(); } + + struct Data { + int x; + }; + + template + struct Description { + static const Data data[]; + }; + + template + const Data Description::data[] = {{ 0 }}; + + void test() { + integral_c<1> ic1 = array_lengthof(Description::data); + } +}