summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/Sema/SemaDecl.cpp34
-rw-r--r--clang/test/Sema/bitfield.c2
-rw-r--r--clang/test/Sema/enum.c6
-rw-r--r--clang/test/Sema/incomplete-decl.c4
-rw-r--r--clang/test/Sema/tentative-decls.c8
5 files changed, 37 insertions, 17 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 049c9394526..c5768fd73a3 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/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();
}
diff --git a/clang/test/Sema/bitfield.c b/clang/test/Sema/bitfield.c
index 2e4df476503..7a70fe8de83 100644
--- a/clang/test/Sema/bitfield.c
+++ b/clang/test/Sema/bitfield.c
@@ -1,5 +1,5 @@
// RUN: clang %s -fsyntax-only -verify
-enum e0;
+enum e0; // expected-note{{forward declaration of 'enum e0'}}
struct a {
int a : -1; // expected-error{{bit-field 'a' has negative width}}
diff --git a/clang/test/Sema/enum.c b/clang/test/Sema/enum.c
index ce49f3064d3..37c9a1e7cf9 100644
--- a/clang/test/Sema/enum.c
+++ b/clang/test/Sema/enum.c
@@ -21,13 +21,11 @@ int test() {
return sizeof(enum e) ;
}
-enum gccForwardEnumExtension ve; // expected-error {{variable has incomplete type 'enum gccForwardEnumExtension'}} \
- // expected-warning{{ISO C forbids forward references to 'enum' types}} \
- // expected-note{{forward declaration of 'enum gccForwardEnumExtension'}}
+enum gccForwardEnumExtension ve; // expected-warning{{ISO C forbids forward references to 'enum' types}}
int test2(int i)
{
- ve + i;
+ ve + i; // expected-error{{invalid operands to binary expression}}
}
// PR2020
diff --git a/clang/test/Sema/incomplete-decl.c b/clang/test/Sema/incomplete-decl.c
index be52cfd7075..7ec436acce8 100644
--- a/clang/test/Sema/incomplete-decl.c
+++ b/clang/test/Sema/incomplete-decl.c
@@ -1,9 +1,9 @@
// RUN: clang -fsyntax-only -verify %s
-struct foo; // expected-note 4 {{forward declaration of 'struct foo'}}
+struct foo; // expected-note 3 {{forward declaration of 'struct foo'}}
void b; // expected-error {{variable has incomplete type 'void'}}
-struct foo f; // expected-error {{variable has incomplete type 'struct foo'}}
+struct foo f; // // FIXME: error because 'struct foo' is never defined
static void c; // expected-error {{variable has incomplete type 'void'}}
static struct foo g; // expected-error {{variable has incomplete type 'struct foo'}}
diff --git a/clang/test/Sema/tentative-decls.c b/clang/test/Sema/tentative-decls.c
index 12ce181e0f1..3c1ab0e6587 100644
--- a/clang/test/Sema/tentative-decls.c
+++ b/clang/test/Sema/tentative-decls.c
@@ -1,5 +1,12 @@
// RUN: clang %s -fsyntax-only -verify
+// PR3310
+struct a x1; // expected-note 2{{forward declaration of 'struct a'}}
+static struct a x2; // expected-error{{variable has incomplete type 'struct a'}}
+struct a x3[10]; // expected-error{{array has incomplete element type 'struct a'}}
+struct a {int x;};
+struct b x4; // FIXME: error because 'struct b' is never defined
+
const int a [1] = {1};
extern const int a[];
@@ -43,3 +50,4 @@ void func2(void)
extern double *p;
extern double *p;
}
+
OpenPOWER on IntegriCloud