aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td2
-rw-r--r--lib/Sema/SemaExpr.cpp16
-rw-r--r--test/SemaObjC/arc-type-conversion.m6
3 files changed, 24 insertions, 0 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index b961e0961a..7311756de8 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3622,6 +3622,8 @@ def ext_typecheck_comparison_of_distinct_pointers : ExtWarn<
"comparison of distinct pointer types (%0 and %1)">;
def ext_typecheck_cond_incompatible_operands : ExtWarn<
"incompatible operand types (%0 and %1)">;
+def err_cond_voidptr_arc : Error <
+ "operands to conditional of types %0 and %1 are incompatible in ARC mode">;
def err_typecheck_comparison_of_distinct_pointers : Error<
"comparison of distinct pointer types (%0 and %1)">;
def ext_typecheck_comparison_of_distinct_pointers_nonstandard : ExtWarn<
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 2868b822e6..987ce55c2a 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -4728,6 +4728,14 @@ QualType Sema::FindCompositeObjCPointerType(ExprResult &LHS, ExprResult &RHS,
}
// Check Objective-C object pointer types and 'void *'
if (LHSTy->isVoidPointerType() && RHSTy->isObjCObjectPointerType()) {
+ if (getLangOptions().ObjCAutoRefCount) {
+ // ARC forbids the implicit conversion of object pointers to 'void *',
+ // so these types are not compatible.
+ Diag(QuestionLoc, diag::err_cond_voidptr_arc) << LHSTy << RHSTy
+ << LHS.get()->getSourceRange() << RHS.get()->getSourceRange();
+ LHS = RHS = true;
+ return QualType();
+ }
QualType lhptee = LHSTy->getAs<PointerType>()->getPointeeType();
QualType rhptee = RHSTy->getAs<ObjCObjectPointerType>()->getPointeeType();
QualType destPointee
@@ -4740,6 +4748,14 @@ QualType Sema::FindCompositeObjCPointerType(ExprResult &LHS, ExprResult &RHS,
return destType;
}
if (LHSTy->isObjCObjectPointerType() && RHSTy->isVoidPointerType()) {
+ if (getLangOptions().ObjCAutoRefCount) {
+ // ARC forbids the implicit conversion of object pointers to 'void *',
+ // so these types are not compatible.
+ Diag(QuestionLoc, diag::err_cond_voidptr_arc) << LHSTy << RHSTy
+ << LHS.get()->getSourceRange() << RHS.get()->getSourceRange();
+ LHS = RHS = true;
+ return QualType();
+ }
QualType lhptee = LHSTy->getAs<ObjCObjectPointerType>()->getPointeeType();
QualType rhptee = RHSTy->getAs<PointerType>()->getPointeeType();
QualType destPointee
diff --git a/test/SemaObjC/arc-type-conversion.m b/test/SemaObjC/arc-type-conversion.m
index 8d8ff984fe..5cf2cf4b74 100644
--- a/test/SemaObjC/arc-type-conversion.m
+++ b/test/SemaObjC/arc-type-conversion.m
@@ -90,3 +90,9 @@ void ownership_transfer_in_cast(void *vp, Block *pblk) {
(void)(Block)&lv; // expected-error {{cast of an indirect pointer to an Objective-C pointer to 'Block'}}
(void)(Block*)lv; // expected-error {{cast of an Objective-C pointer to '__strong Block *'}}
}
+
+// <rdar://problem/10486347>
+void conversion_in_conditional(id a, void* b) {
+ id c = 1 ? a : b; // expected-error {{operands to conditional of types 'id' and 'void *' are incompatible in ARC mode}}
+ id d = 1 ? b : a; // expected-error {{operands to conditional of types 'void *' and 'id' are incompatible in ARC mode}}
+}