Cope with an amusingly little anomaly with dependent types and
incomplete array initialization, where we have the following in a
template:
int a[] = { 1, 2, something-value-dependent };
// ...
sizeof(a);
The type of "a" appears to be a non-dependent IncompleteArrayType, but
treating it as such makes the sizeof(a) fail at template definition
time. We now correctly handle this by morphing the IncompleteArrayType
into a DependentSizedArrayType with a NULL expression, indicating that
its size has no corresponding expression (and, therefore, the type is
distinct from others).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89366 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index 0f973d6..fbc4680 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -136,8 +136,29 @@
SourceLocation InitLoc,
DeclarationName InitEntity, bool DirectInit) {
if (DeclType->isDependentType() ||
- Init->isTypeDependent() || Init->isValueDependent())
+ Init->isTypeDependent() || Init->isValueDependent()) {
+ // We have either a dependent type or a type- or value-dependent
+ // initializer, so we don't perform any additional checking at
+ // this point.
+
+ // If the declaration is a non-dependent, incomplete array type
+ // that has an initializer, then its type will be completed once
+ // the initializer is instantiated, meaning that the type is
+ // dependent. Morph the declaration's type into a
+ // dependently-sized array type.
+ if (!DeclType->isDependentType()) {
+ if (const IncompleteArrayType *ArrayT
+ = Context.getAsIncompleteArrayType(DeclType)) {
+ DeclType = Context.getDependentSizedArrayType(ArrayT->getElementType(),
+ /*NumElts=*/0,
+ ArrayT->getSizeModifier(),
+ ArrayT->getIndexTypeCVRQualifiers(),
+ SourceRange());
+ }
+ }
+
return false;
+ }
// C++ [dcl.init.ref]p1:
// A variable declared to be a T& or T&&, that is "reference to type T"