forked from OSchip/llvm-project
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. llvm-svn: 132530
This commit is contained in:
parent
2f157c9ae2
commit
57d4f972b7
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -73,3 +73,26 @@ namespace PR10001 {
|
|||
|
||||
int x = S<int>::f();
|
||||
}
|
||||
|
||||
namespace PR7985 {
|
||||
template<int N> struct integral_c { };
|
||||
|
||||
template <typename T, int N>
|
||||
integral_c<N> array_lengthof(T (&x)[N]) { return integral_c<N>(); }
|
||||
|
||||
struct Data {
|
||||
int x;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct Description {
|
||||
static const Data data[];
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
const Data Description<T>::data[] = {{ 0 }};
|
||||
|
||||
void test() {
|
||||
integral_c<1> ic1 = array_lengthof(Description<int>::data);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue