aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaExpr.cpp
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2008-08-26 00:41:39 +0000
committerDaniel Dunbar <daniel@zuster.org>2008-08-26 00:41:39 +0000
commita56f7460baf475151e03b1249a1343349328e39c (patch)
tree2db3102706c90d07a7d4c09a97bb80eaa408e460 /lib/Sema/SemaExpr.cpp
parenteb4b7051a596560ef4a1846e3714707f44e9dc30 (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.cpp33
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,