[cfe-commits] r66210 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.def lib/Sema/Sema.h lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp test/Sema/bitfield.c test/SemaCXX/class.cpp
Chris Lattner
sabre at nondot.org
Thu Mar 5 14:45:59 PST 2009
Author: lattner
Date: Thu Mar 5 16:45:59 2009
New Revision: 66210
URL: http://llvm.org/viewvc/llvm-project?rev=66210&view=rev
Log:
fix PR3607 and a fixme, by checking bitfield constraints
more consistently.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/test/Sema/bitfield.c
cfe/trunk/test/SemaCXX/class.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def?rev=66210&r1=66209&r2=66210&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def Thu Mar 5 16:45:59 2009
@@ -249,7 +249,7 @@
DIAG(err_static_not_bitfield, ERROR,
"static member %0 cannot be a bit-field")
DIAG(err_not_integral_type_bitfield, ERROR,
- "bit-field %0 with non-integral type")
+ "bit-field %0 has non-integral type")
DIAG(err_member_initialization, ERROR,
"%0 can only be initialized if it is a static const integral data member")
DIAG(err_member_function_initialization, ERROR,
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=66210&r1=66209&r2=66210&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Thu Mar 5 16:45:59 2009
@@ -361,6 +361,10 @@
llvm::SmallVectorImpl<DeclTy*> &Decls);
virtual DeclTy *ActOnField(Scope *S, DeclTy *TagD, SourceLocation DeclStart,
Declarator &D, ExprTy *BitfieldWidth);
+
+ FieldDecl *HandleField(Scope *S, RecordDecl *TagD, SourceLocation DeclStart,
+ Declarator &D, Expr *BitfieldWidth);
+
virtual DeclTy *ActOnIvar(Scope *S, SourceLocation DeclStart,
Declarator &D, ExprTy *BitfieldWidth,
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=66210&r1=66209&r2=66210&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Mar 5 16:45:59 2009
@@ -2575,7 +2575,8 @@
}
}
if (isa<DeclStmt>(*i)) continue;
- RecursiveCalcJumpScopes(LabelScopeMap, PopScopeMap, GotoScopeMap, ScopeStack, *i);
+ RecursiveCalcJumpScopes(LabelScopeMap, PopScopeMap, GotoScopeMap,
+ ScopeStack, *i);
}
while (ScopeStack.size() && PopScopeMap[ScopeStack.back()] == CurStmt) {
@@ -3150,7 +3151,14 @@
bool Sema::VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName,
QualType FieldTy, const Expr *BitWidth) {
- // FIXME: 6.7.2.1p4 - verify the field type.
+ // C99 6.7.2.1p4 - verify the field type.
+
+ if (!FieldTy->isIntegralType()) {
+ // Handle incomplete types with specific error.
+ if (FieldTy->isIncompleteType())
+ return Diag(FieldLoc, diag::err_field_incomplete) << FieldTy;
+ return Diag(FieldLoc, diag::err_not_integral_type_bitfield) << FieldName;
+ }
llvm::APSInt Value;
if (VerifyIntegerConstantExpression(BitWidth, &Value))
@@ -3177,15 +3185,19 @@
Sema::DeclTy *Sema::ActOnField(Scope *S, DeclTy *TagD,
SourceLocation DeclStart,
Declarator &D, ExprTy *BitfieldWidth) {
+ return HandleField(S, static_cast<RecordDecl*>(TagD), DeclStart, D,
+ static_cast<Expr*>(BitfieldWidth));
+}
+
+/// HandleField - Analyze a field of a C struct or a C++ data member.
+///
+FieldDecl *Sema::HandleField(Scope *S, RecordDecl *Record,
+ SourceLocation DeclStart,
+ Declarator &D, Expr *BitWidth) {
IdentifierInfo *II = D.getIdentifier();
- Expr *BitWidth = (Expr*)BitfieldWidth;
SourceLocation Loc = DeclStart;
- RecordDecl *Record = (RecordDecl *)TagD;
if (II) Loc = D.getIdentifierLoc();
- // FIXME: Unnamed fields can be handled in various different ways, for
- // example, unnamed unions inject all members into the struct namespace!
-
QualType T = GetTypeForDeclarator(D, S);
assert(!T.isNull() && "GetTypeForDeclarator() returned null type");
bool InvalidDecl = false;
@@ -3210,8 +3222,11 @@
}
if (BitWidth) {
- if (VerifyBitField(Loc, II, T, BitWidth))
+ if (VerifyBitField(Loc, II, T, BitWidth)) {
InvalidDecl = true;
+ DeleteExpr(BitWidth);
+ BitWidth = 0;
+ }
} else {
// Not a bitfield.
@@ -3290,8 +3305,11 @@
if (BitWidth) {
// 6.7.2.1p3, 6.7.2.1p4
- if (VerifyBitField(Loc, II, T, BitWidth))
+ if (VerifyBitField(Loc, II, T, BitWidth)) {
InvalidDecl = true;
+ DeleteExpr(BitWidth);
+ BitWidth = 0;
+ }
} else {
// Not a bitfield.
@@ -3373,6 +3391,11 @@
// Remember all fields written by the user.
RecFields.push_back(FD);
}
+
+ // If the field is already invalid for some reason, don't emit more
+ // diagnostics about it.
+ if (FD->isInvalidDecl())
+ continue;
// C99 6.7.2.1p2 - A field may not be a function type.
if (FDTy->isFunctionType()) {
@@ -3466,7 +3489,8 @@
IVE = ID->ivar_end(); IVI != IVE; ++IVI) {
ObjCIvarDecl* Ivar = (*IVI);
IdentifierInfo *II = Ivar->getIdentifier();
- ObjCIvarDecl* prevIvar = ID->getSuperClass()->lookupInstanceVariable(II);
+ ObjCIvarDecl* prevIvar =
+ ID->getSuperClass()->lookupInstanceVariable(II);
if (prevIvar) {
Diag(Ivar->getLocation(), diag::err_duplicate_member) << II;
Diag(prevIvar->getLocation(), diag::note_previous_declaration);
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=66210&r1=66209&r2=66210&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Mar 5 16:45:59 2009
@@ -547,11 +547,15 @@
Decl *Member;
bool InvalidDecl = false;
- if (isInstField)
- Member = static_cast<Decl*>(ActOnField(S, cast<CXXRecordDecl>(CurContext),
- Loc, D, BitWidth));
- else
+ if (isInstField) {
+ FieldDecl *FD =
+ HandleField(S, cast<CXXRecordDecl>(CurContext), Loc, D, BitWidth);
+ // Refresh our notion of bitwidth.
+ BitWidth = FD->getBitWidth();
+ Member = FD;
+ } else {
Member = static_cast<Decl*>(ActOnDeclarator(S, D, LastInGroup));
+ }
if (!Member) return LastInGroup;
Modified: cfe/trunk/test/Sema/bitfield.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/bitfield.c?rev=66210&r1=66209&r2=66210&view=diff
==============================================================================
--- cfe/trunk/test/Sema/bitfield.c (original)
+++ cfe/trunk/test/Sema/bitfield.c Thu Mar 5 16:45:59 2009
@@ -1,4 +1,5 @@
// RUN: clang %s -fsyntax-only -verify
+enum e0;
struct a {
int a : -1; // expected-error{{bit-field 'a' has negative width}}
@@ -11,4 +12,10 @@
// rdar://6138816
int e : 0; // expected-error {{bit-field 'e' has zero width}}
+
+ float xx : 4; // expected-error {{bit-field 'xx' has non-integral type}}
+
+ // PR3607
+ enum e0 f : 1; // expected-error {{field has incomplete type 'enum e0'}}
};
+
Modified: cfe/trunk/test/SemaCXX/class.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/class.cpp?rev=66210&r1=66209&r2=66210&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/class.cpp (original)
+++ cfe/trunk/test/SemaCXX/class.cpp Thu Mar 5 16:45:59 2009
@@ -27,8 +27,8 @@
typedef int func();
func tm;
func *ptm;
- func btm : 1; // expected-error {{error: bit-field 'btm' with non-integral type}}
- NestedC bc : 1; // expected-error {{error: bit-field 'bc' with non-integral type}}
+ func btm : 1; // expected-error {{error: bit-field 'btm' has non-integral type}}
+ NestedC bc : 1; // expected-error {{error: bit-field 'bc' has non-integral type}}
enum E1 { en1, en2 };
More information about the cfe-commits
mailing list