зеркало из https://github.com/microsoft/clang.git
Type of a conditional expression with two distinct objective-c
class pointer is the most derived common class of the two. This is <rdar://problem/7334235>. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@85337 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
c4c9045dab
Коммит
db07b3f7cd
|
@ -1019,7 +1019,9 @@ public:
|
|||
bool canAssignObjCInterfaces(const ObjCInterfaceType *LHS,
|
||||
const ObjCInterfaceType *RHS);
|
||||
bool areComparableObjCPointerTypes(QualType LHS, QualType RHS);
|
||||
|
||||
QualType areCommonBaseCompatible(const ObjCObjectPointerType *LHSOPT,
|
||||
const ObjCObjectPointerType *RHSOPT);
|
||||
|
||||
// Functions for calculating composite types
|
||||
QualType mergeTypes(QualType, QualType);
|
||||
QualType mergeFunctionTypes(QualType, QualType);
|
||||
|
|
|
@ -3846,6 +3846,28 @@ bool ASTContext::canAssignObjCInterfaces(const ObjCObjectPointerType *LHSOPT,
|
|||
return false;
|
||||
}
|
||||
|
||||
/// areCommonBaseCompatible - Returns common base class of the two classes if
|
||||
/// one found. Note that this is O'2 algorithm. But it will be called as the
|
||||
/// last type comparison in a ?-exp of ObjC pointer types before a
|
||||
/// warning is issued. So, its invokation is extremely rare.
|
||||
QualType ASTContext::areCommonBaseCompatible(
|
||||
const ObjCObjectPointerType *LHSOPT,
|
||||
const ObjCObjectPointerType *RHSOPT) {
|
||||
const ObjCInterfaceType* LHS = LHSOPT->getInterfaceType();
|
||||
const ObjCInterfaceType* RHS = RHSOPT->getInterfaceType();
|
||||
if (!LHS || !RHS)
|
||||
return QualType();
|
||||
|
||||
while (const ObjCInterfaceDecl *LHSIDecl = LHS->getDecl()->getSuperClass()) {
|
||||
QualType LHSTy = getObjCInterfaceType(LHSIDecl);
|
||||
LHS = LHSTy->getAs<ObjCInterfaceType>();
|
||||
if (canAssignObjCInterfaces(LHS, RHS))
|
||||
return getObjCObjectPointerType(LHSTy);
|
||||
}
|
||||
|
||||
return QualType();
|
||||
}
|
||||
|
||||
bool ASTContext::canAssignObjCInterfaces(const ObjCInterfaceType *LHS,
|
||||
const ObjCInterfaceType *RHS) {
|
||||
// Verify that the base decls are compatible: the RHS must be a subclass of
|
||||
|
|
|
@ -3525,7 +3525,10 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
|
|||
compositeType = Context.getObjCIdType();
|
||||
} else if (LHSTy->isObjCIdType() || RHSTy->isObjCIdType()) {
|
||||
compositeType = Context.getObjCIdType();
|
||||
} else {
|
||||
} else if (!(compositeType =
|
||||
Context.areCommonBaseCompatible(LHSOPT, RHSOPT)).isNull())
|
||||
;
|
||||
else {
|
||||
Diag(QuestionLoc, diag::ext_typecheck_cond_incompatible_operands)
|
||||
<< LHSTy << RHSTy
|
||||
<< LHS->getSourceRange() << RHS->getSourceRange();
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
// RUN: clang-cc -fsyntax-only -verify %s
|
||||
|
||||
@interface NSObject @end
|
||||
|
||||
@interface NSInterm : NSObject
|
||||
@end
|
||||
|
||||
@interface NSArray : NSInterm
|
||||
@end
|
||||
|
||||
@interface NSSet : NSObject
|
||||
@end
|
||||
|
||||
|
||||
NSObject* test (int argc) {
|
||||
NSArray *array = ((void*)0);
|
||||
NSSet *set = ((void*)0);
|
||||
return (argc) ? set : array ;
|
||||
}
|
||||
|
||||
|
||||
NSObject* test1 (int argc) {
|
||||
NSArray *array = ((void*)0);
|
||||
NSSet *set = ((void*)0);
|
||||
return (argc) ? array : set;
|
||||
}
|
Загрузка…
Ссылка в новой задаче