diff options
author | Sebastian Redl <sebastian.redl@getdesigned.at> | 2009-10-17 19:37:06 +0000 |
---|---|---|
committer | Sebastian Redl <sebastian.redl@getdesigned.at> | 2009-10-17 19:37:06 +0000 |
commit | d75191f0d100b596281f99ea8f2f0a0d0560d969 (patch) | |
tree | 8b48fa43990e6f6c9937e219ded669f13ee56f16 /lib/Sema/SemaDecl.cpp | |
parent | 12356b119032edd64e9c32f9f01920d12c2acc57 (diff) |
In some dependent contexts, incomplete array types persist into FinalizeDeclaratorGroup. Don't require them to have a complete type. This allows us to compile Hello World with the Apache stdcxx library. If you don't use endl, it even links and runs.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@84347 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 35 |
1 files changed, 31 insertions, 4 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 0ec247958c..2893abbad2 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -3527,10 +3527,37 @@ Sema::DeclGroupPtrTy Sema::FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS, // Block scope. C99 6.7p7: If an identifier for an object is declared with // no linkage (C99 6.2.2p6), the type for the object shall be complete... if (IDecl->isBlockVarDecl() && !IDecl->hasExternalStorage()) { - if (!IDecl->isInvalidDecl() && - RequireCompleteType(IDecl->getLocation(), T, - diag::err_typecheck_decl_incomplete_type)) - IDecl->setInvalidDecl(); + if (T->isDependentType()) { + // If T is dependent, we should not require a complete type. + // (RequireCompleteType shouldn't be called with dependent types.) + // But we still can at least check if we've got an array of unspecified + // size without an initializer. + if (!IDecl->isInvalidDecl() && T->isIncompleteArrayType() && + !IDecl->getInit()) { + Diag(IDecl->getLocation(), diag::err_typecheck_decl_incomplete_type) + << T; + IDecl->setInvalidDecl(); + } + } else if (!IDecl->isInvalidDecl()) { + // If T is an incomplete array type with an initializer list that is + // dependent on something, its size has not been fixed. We could attempt + // to fix the size for such arrays, but we would still have to check + // here for initializers containing a C++0x vararg expansion, e.g. + // template <typename... Args> void f(Args... args) { + // int vals[] = { args }; + // } + const IncompleteArrayType *IAT = T->getAs<IncompleteArrayType>(); + Expr *Init = IDecl->getInit(); + if (IAT && Init && + (Init->isTypeDependent() || Init->isValueDependent())) { + // Check that the member type of the array is complete, at least. + if (RequireCompleteType(IDecl->getLocation(), IAT->getElementType(), + diag::err_typecheck_decl_incomplete_type)) + IDecl->setInvalidDecl(); + } else if (RequireCompleteType(IDecl->getLocation(), T, + diag::err_typecheck_decl_incomplete_type)) + IDecl->setInvalidDecl(); + } } // File scope. C99 6.9.2p2: A declaration of an identifier for an // object that has file scope without an initializer, and without a |