diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2008-08-22 00:56:42 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2008-08-22 00:56:42 +0000 |
commit | 3d815e7eb56c25d7ed812eced32e41df43039f9a (patch) | |
tree | 25fe2d71c1f33a5920ccf73ffe3641c1734efc06 /lib/Sema/SemaExpr.cpp | |
parent | d8bfe7f25a695ca947effbccdf9ecbe3e018e221 (diff) |
Rewrite type compatibility testing to do type merging rather than just
testing compatibility. This is necessary for some constructs, like merging
redeclarations.
Also, there are some ObjC changes to make sure that
typesAreCompatible(a,b) == typesAreCompatible(b,a). I don't have any
ObjC code beyond the testsuite, so please tell me if there are any cases
where this doesn't behave as expected.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@55158 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExpr.cpp')
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 33 |
1 files changed, 31 insertions, 2 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index c7db342ae4..9a544a2e05 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -1354,7 +1354,20 @@ Sema::CheckPointerTypesForAssignment(QualType lhsType, QualType rhsType) { assert(lhptee->isFunctionType()); return FunctionVoidPointer; } - + + // Check for ObjC interfaces + const ObjCInterfaceType* LHSIface = lhptee->getAsObjCInterfaceType(); + const ObjCInterfaceType* RHSIface = rhptee->getAsObjCInterfaceType(); + if (LHSIface && RHSIface && + Context.canAssignObjCInterfaces(LHSIface, RHSIface)) + return ConvTy; + + // ID acts sort of like void* for ObjC interfaces + if (LHSIface && Context.isObjCIdType(rhptee)) + return ConvTy; + if (RHSIface && Context.isObjCIdType(lhptee)) + return ConvTy; + // C99 6.5.16.1p1 (constraint 3): both operands are pointers to qualified or // unqualified versions of compatible types, ... if (!Context.typesAreCompatible(lhptee.getUnqualifiedType(), @@ -1701,6 +1714,21 @@ QualType Sema::CheckShiftOperands(Expr *&lex, Expr *&rex, SourceLocation loc, return lex->getType(); } +static bool areComparableObjCInterfaces(QualType LHS, QualType RHS, + ASTContext& Context) { + const ObjCInterfaceType* LHSIface = LHS->getAsObjCInterfaceType(); + const ObjCInterfaceType* RHSIface = RHS->getAsObjCInterfaceType(); + // ID acts sort of like void* for ObjC interfaces + if (LHSIface && Context.isObjCIdType(RHS)) + return true; + if (RHSIface && Context.isObjCIdType(LHS)) + return true; + if (!LHSIface || !RHSIface) + return false; + return Context.canAssignObjCInterfaces(LHSIface, RHSIface) || + Context.canAssignObjCInterfaces(RHSIface, LHSIface); +} + // C99 6.5.8 QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation loc, bool isRelational) { @@ -1756,7 +1784,8 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation loc, if (!LHSIsNull && !RHSIsNull && // C99 6.5.9p2 !LCanPointeeTy->isVoidType() && !RCanPointeeTy->isVoidType() && !Context.typesAreCompatible(LCanPointeeTy.getUnqualifiedType(), - RCanPointeeTy.getUnqualifiedType())) { + RCanPointeeTy.getUnqualifiedType()) && + !areComparableObjCInterfaces(LCanPointeeTy, RCanPointeeTy, Context)) { Diag(loc, diag::ext_typecheck_comparison_of_distinct_pointers, lType.getAsString(), rType.getAsString(), lex->getSourceRange(), rex->getSourceRange()); |