diff options
author | Daniel Dunbar <daniel@zuster.org> | 2008-08-26 00:41:39 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2008-08-26 00:41:39 +0000 |
commit | a56f7460baf475151e03b1249a1343349328e39c (patch) | |
tree | 2db3102706c90d07a7d4c09a97bb80eaa408e460 /lib/Sema/SemaExpr.cpp | |
parent | eb4b7051a596560ef4a1846e3714707f44e9dc30 (diff) |
In incompatible pointer-typed ?: expressions, add implicit conversion
of RHSs to id type instead of void* if either has Objective-C object
type.
- This ensures the result can still be used in normal places an
object can be used, like a message send.
Add implicit conversions for ?: applied to qualified id types to
ensure that the RHSs are compatible.
- This prevents a codegen crash (creating invalid PHI nodes).
- Again, this relates to the fact that qualified id types have no
canonical types.
- Note that the implicit type casted to is incorrect, however this
doesn't currently cause problems because of the flexibility of the
id type.
Test cases for above.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@55346 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExpr.cpp')
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 33 |
1 files changed, 23 insertions, 10 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 9a544a2e05..5169ce1311 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -1248,13 +1248,21 @@ inline QualType Sema::CheckConditionalOperands( // C99 6.5.15 Diag(questionLoc, diag::warn_typecheck_cond_incompatible_pointers, lexT.getAsString(), rexT.getAsString(), lex->getSourceRange(), rex->getSourceRange()); - // In this situation, we assume void* type. No especially good - // reason, but this is what gcc does, and we do have to pick - // to get a consistent AST. - QualType voidPtrTy = Context.getPointerType(Context.VoidTy); - ImpCastExprToType(lex, voidPtrTy); - ImpCastExprToType(rex, voidPtrTy); - return voidPtrTy; + // In this situation, assume a conservative type; in general + // we assume void* type. No especially good reason, but this + // is what gcc does, and we do have to pick to get a + // consistent AST. However, if either type is an Objective-C + // object type then use id. + QualType incompatTy; + if (Context.isObjCObjectPointerType(lexT) || + Context.isObjCObjectPointerType(rexT)) { + incompatTy = Context.getObjCIdType(); + } else { + incompatTy = Context.getPointerType(Context.VoidTy); + } + ImpCastExprToType(lex, incompatTy); + ImpCastExprToType(rex, incompatTy); + return incompatTy; } // The pointer types are compatible. // C99 6.5.15p6: If both operands are pointers to compatible types *or* to @@ -1271,10 +1279,15 @@ inline QualType Sema::CheckConditionalOperands( // C99 6.5.15 } // Need to handle "id<xx>" explicitly. Unlike "id", whose canonical type // evaluates to "struct objc_object *" (and is handled above when comparing - // id with statically typed objects). FIXME: Do we need an ImpCastExprToType? + // id with statically typed objects). if (lexT->isObjCQualifiedIdType() || rexT->isObjCQualifiedIdType()) { - if (ObjCQualifiedIdTypesAreCompatible(lexT, rexT, true)) - return Context.getObjCIdType(); + if (ObjCQualifiedIdTypesAreCompatible(lexT, rexT, true)) { + // FIXME: This is not the correct composite type. + QualType compositeType = Context.getObjCIdType(); + ImpCastExprToType(lex, compositeType); + ImpCastExprToType(rex, compositeType); + return compositeType; + } } // Otherwise, the operands are not compatible. Diag(questionLoc, diag::err_typecheck_cond_incompatible_operands, |