"reimplementation of class %0")
DIAG(err_conflicting_ivar_type, ERROR,
"instance variable %0 has conflicting type: %1 vs %2")
+DIAG(err_conflicting_ivar_bitwidth, ERROR,
+ "instance variable %0 has conflicting bitfield width")
DIAG(err_conflicting_ivar_name, ERROR,
"conflicting instance variable names: %0 vs %1")
DIAG(err_inconsistant_ivar_count, ERROR,
//===----------------------------------------------------------------------===//
#include "Sema.h"
+#include "clang/AST/Expr.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclObjC.h"
#include "clang/Parse/DeclSpec.h"
ObjCIvarDecl* ClsIvar = *IVI;
assert (ImplIvar && "missing implementation ivar");
assert (ClsIvar && "missing class ivar");
+
+ // First, make sure the types match.
if (Context.getCanonicalType(ImplIvar->getType()) !=
Context.getCanonicalType(ClsIvar->getType())) {
Diag(ImplIvar->getLocation(), diag::err_conflicting_ivar_type)
<< ImplIvar->getIdentifier()
<< ImplIvar->getType() << ClsIvar->getType();
Diag(ClsIvar->getLocation(), diag::note_previous_definition);
- }
- // TODO: Two mismatched (unequal width) Ivar bitfields should be diagnosed
- // as error.
- else if (ImplIvar->getIdentifier() != ClsIvar->getIdentifier()) {
+ } else if (ImplIvar->isBitField() && ClsIvar->isBitField()) {
+ Expr *ImplBitWidth = ImplIvar->getBitWidth();
+ Expr *ClsBitWidth = ClsIvar->getBitWidth();
+ if (ImplBitWidth->getIntegerConstantExprValue(Context).getZExtValue() !=
+ ClsBitWidth->getIntegerConstantExprValue(Context).getZExtValue()) {
+ Diag(ImplBitWidth->getLocStart(), diag::err_conflicting_ivar_bitwidth)
+ << ImplIvar->getIdentifier();
+ Diag(ClsBitWidth->getLocStart(), diag::note_previous_definition);
+ }
+ }
+ // Make sure the names are identical.
+ if (ImplIvar->getIdentifier() != ClsIvar->getIdentifier()) {
Diag(ImplIvar->getLocation(), diag::err_conflicting_ivar_name)
<< ImplIvar->getIdentifier() << ClsIvar->getIdentifier();
Diag(ClsIvar->getLocation(), diag::note_previous_definition);
- return;
}
--numIvars;
}
}
@end
+@interface Base {
+ int i;
+}
+@end
+
+@interface WithBitfields: Base {
+ void *isa; // expected-note {{previous definition is here}}
+ unsigned a: 5;
+ signed b: 4;
+ int c: 5; // expected-note {{previous definition is here}}
+}
+@end
+
+@implementation WithBitfields {
+ char *isa; // expected-error {{instance variable 'isa' has conflicting type: 'char *' vs 'void *'}}
+ unsigned a: 5;
+ signed b: 4;
+ int c: 3; // expected-error {{instance variable 'c' has conflicting bitfield width}}
+}
+@end