diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-03-10 21:58:27 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-03-10 21:58:27 +0000 |
commit | a03aca82de5259846d4ef38db11b8116398d2222 (patch) | |
tree | 997bfd92f2d48870f696768c2cf2c9ce2bc48609 /lib/Sema/SemaDecl.cpp | |
parent | fbe899f7143d85f11d16423568fee5ebd99beab1 (diff) |
Partial fix for PR3310, concerning type-checking for tentative
definitions. We were rejecting tentative definitions of incomplete
(which is bad), and now we don't.
This fix is partial because we don't do the end-of-translation-unit
initialization for tentative definitions that don't ever have any
initializers specified.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66584 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 34 |
1 files changed, 24 insertions, 10 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 049c939452..c5768fd73a 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -1749,6 +1749,13 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC, } } + if (!InvalidDecl && R->isVoidType() && !NewVD->hasExternalStorage()) { + Diag(NewVD->getLocation(), diag::err_typecheck_decl_incomplete_type) + << R; + InvalidDecl = true; + } + + // If this is a locally-scoped extern C variable, update the map of // such variables. if (CurContext->isFunctionOrMethod() && NewVD->isExternC(Context) && @@ -2342,17 +2349,25 @@ Sema::DeclTy *Sema::FinalizeDeclaratorGroup(Scope *S, DeclTy *group) { // storage-class specifier or with the storage-class specifier "static", // constitutes a tentative definition. Note: A tentative definition with // external linkage is valid (C99 6.2.2p5). - if (isTentativeDefinition(IDecl)) { - if (T->isIncompleteArrayType()) { - // C99 6.9.2 (p2, p5): Implicit initialization causes an incomplete - // array to be completed. Don't issue a diagnostic. - } else if (!IDecl->isInvalidDecl() && - RequireCompleteType(IDecl->getLocation(), T, - diag::err_typecheck_decl_incomplete_type)) + if (!getLangOptions().CPlusPlus && isTentativeDefinition(IDecl)) { + QualType CheckType = T; + unsigned DiagID = diag::err_typecheck_decl_incomplete_type; + + const IncompleteArrayType *ArrayT = Context.getAsIncompleteArrayType(T); + if (ArrayT) { + CheckType = ArrayT->getElementType(); + DiagID = diag::err_illegal_decl_array_incomplete_type; + } + + if (IDecl->isInvalidDecl()) { + // Do nothing with invalid declarations + } else if ((ArrayT || IDecl->getStorageClass() == VarDecl::Static) && + RequireCompleteType(IDecl->getLocation(), CheckType, DiagID)) { // C99 6.9.2p3: If the declaration of an identifier for an object is // a tentative definition and has internal linkage (C99 6.2.2p3), the // declared type shall not be an incomplete type. IDecl->setInvalidDecl(); + } } if (IDecl->isFileVarDecl()) CheckForFileScopedRedefinitions(S, IDecl); @@ -3243,9 +3258,8 @@ bool Sema::VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName, // C++ 9.6p3: A bit-field shall have integral or enumeration type. if (!FieldTy->isIntegralType()) { // Handle incomplete types with specific error. - if (FieldTy->isIncompleteType()) - return Diag(FieldLoc, diag::err_field_incomplete) - << FieldTy << BitWidth->getSourceRange(); + if (RequireCompleteType(FieldLoc, FieldTy, diag::err_field_incomplete)) + return true; return Diag(FieldLoc, diag::err_not_integral_type_bitfield) << FieldName << BitWidth->getSourceRange(); } |