forked from OSchip/llvm-project
Weaken the type-matching rules for methods that return aggregates when
complaining about mismatches in the global method pool. llvm-svn: 133123
This commit is contained in:
parent
b00e8c0cad
commit
54507ab83c
|
@ -1652,6 +1652,10 @@ Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
|
|||
return CDecl;
|
||||
}
|
||||
|
||||
static bool tryMatchRecordTypes(ASTContext &Context,
|
||||
Sema::MethodMatchStrategy strategy,
|
||||
const Type *left, const Type *right);
|
||||
|
||||
static bool matchTypes(ASTContext &Context, Sema::MethodMatchStrategy strategy,
|
||||
QualType leftQT, QualType rightQT) {
|
||||
const Type *left =
|
||||
|
@ -1681,10 +1685,11 @@ static bool matchTypes(ASTContext &Context, Sema::MethodMatchStrategy strategy,
|
|||
if (isa<VectorType>(right)) return false;
|
||||
|
||||
// - references should only match references of identical type
|
||||
// - structs, unions, and Objective-C objects must match exactly
|
||||
// - structs, unions, and Objective-C objects must match more-or-less
|
||||
// exactly
|
||||
// - everything else should be a scalar
|
||||
if (!left->isScalarType() || !right->isScalarType())
|
||||
return false;
|
||||
return tryMatchRecordTypes(Context, strategy, left, right);
|
||||
|
||||
// Make scalars agree in kind, except count bools as chars.
|
||||
Type::ScalarTypeKind leftSK = left->getScalarTypeKind();
|
||||
|
@ -1698,6 +1703,36 @@ static bool matchTypes(ASTContext &Context, Sema::MethodMatchStrategy strategy,
|
|||
return (leftSK == rightSK);
|
||||
}
|
||||
|
||||
static bool tryMatchRecordTypes(ASTContext &Context,
|
||||
Sema::MethodMatchStrategy strategy,
|
||||
const Type *lt, const Type *rt) {
|
||||
assert(lt && rt && lt != rt);
|
||||
|
||||
if (!isa<RecordType>(lt) || !isa<RecordType>(rt)) return false;
|
||||
RecordDecl *left = cast<RecordType>(lt)->getDecl();
|
||||
RecordDecl *right = cast<RecordType>(rt)->getDecl();
|
||||
|
||||
// Require union-hood to match.
|
||||
if (left->isUnion() != right->isUnion()) return false;
|
||||
|
||||
// Require an exact match if either is non-POD.
|
||||
if ((isa<CXXRecordDecl>(left) && !cast<CXXRecordDecl>(left)->isPOD()) ||
|
||||
(isa<CXXRecordDecl>(right) && !cast<CXXRecordDecl>(right)->isPOD()))
|
||||
return false;
|
||||
|
||||
// Require size and alignment to match.
|
||||
if (Context.getTypeInfo(lt) != Context.getTypeInfo(rt)) return false;
|
||||
|
||||
// Require fields to match.
|
||||
RecordDecl::field_iterator li = left->field_begin(), le = left->field_end();
|
||||
RecordDecl::field_iterator ri = right->field_begin(), re = right->field_end();
|
||||
for (; li != le && ri != re; ++li, ++ri) {
|
||||
if (!matchTypes(Context, strategy, li->getType(), ri->getType()))
|
||||
return false;
|
||||
}
|
||||
return (li == le && ri == re);
|
||||
}
|
||||
|
||||
/// MatchTwoMethodDeclarations - Checks that two methods have matching type and
|
||||
/// returns true, or false, accordingly.
|
||||
/// TODO: Handle protocol list; such as id<p1,p2> in type comparisons
|
||||
|
|
|
@ -55,3 +55,19 @@ void f5(id a0, Abstract *a1) {
|
|||
void f6(id<A> a0) {
|
||||
Abstract *l = [a0 x];
|
||||
}
|
||||
|
||||
struct test3a { int x, y; };
|
||||
struct test3b { unsigned x, y; };
|
||||
@interface Test3A - (struct test3a) test3; @end
|
||||
@interface Test3B - (struct test3b) test3; @end
|
||||
void test3(id x) {
|
||||
(void) [x test3];
|
||||
}
|
||||
|
||||
struct test4a { int x, y; };
|
||||
struct test4b { float x, y; };
|
||||
@interface Test4A - (struct test4a) test4; @end //expected-note{{using}}
|
||||
@interface Test4B - (struct test4b) test4; @end //expected-note{{also found}}
|
||||
void test4(id x) {
|
||||
(void) [x test4]; //expected-warning {{multiple methods named 'test4' found}}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue