diff options
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 3 | ||||
-rw-r--r-- | clang/test/SemaObjC/arc.m | 1 | ||||
-rw-r--r-- | clang/test/SemaObjCXX/arc-ptr-comparison.mm | 29 |
3 files changed, 33 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 51b1ebe0b17..5f4071924d3 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -11055,6 +11055,9 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS, diagnoseDistinctPointerComparison(*this, Loc, LHS, RHS, /*isError*/false); } + // FIXME: If LPtrToVoid, we should presumably convert the LHS rather than + // the RHS, but we have test coverage for this behavior. + // FIXME: Consider using convertPointersToCompositeType in C++. if (LHSIsNull && !RHSIsNull) { Expr *E = LHS.get(); if (getLangOpts().ObjCAutoRefCount) diff --git a/clang/test/SemaObjC/arc.m b/clang/test/SemaObjC/arc.m index b87f294eef5..dea3ba5e9b7 100644 --- a/clang/test/SemaObjC/arc.m +++ b/clang/test/SemaObjC/arc.m @@ -295,6 +295,7 @@ void test11(id op, void *vp) { b = (vp == nil); b = (nil == vp); + // FIXME: Shouldn't these be consistent? b = (vp == op); // expected-error {{implicit conversion of Objective-C pointer type 'id' to C pointer type 'void *' requires a bridged cast}} expected-note {{use __bridge}} expected-note {{use CFBridgingRetain call}} b = (op == vp); } diff --git a/clang/test/SemaObjCXX/arc-ptr-comparison.mm b/clang/test/SemaObjCXX/arc-ptr-comparison.mm index 8571a817959..b3af26c1f84 100644 --- a/clang/test/SemaObjCXX/arc-ptr-comparison.mm +++ b/clang/test/SemaObjCXX/arc-ptr-comparison.mm @@ -22,3 +22,32 @@ int testObjCComparisonRules(void *v, id x, id y) { return v == (void *)0; return x == y; } + +@class A; + +int testMixedQualComparisonRules(void *v, const void *cv, A *a, const A *ca) { + return cv == ca; +#ifndef NOARC +// expected-error@-2 {{implicit conversion of Objective-C pointer type 'const A *' to C pointer type 'const void *' requires a bridged cast}} +// expected-note@-3 {{use __bridge to convert directly (no change in ownership)}} +// expected-note@-4 {{use __bridge_retained to make an ARC object available as a +1 'const void *'}} +#endif + // FIXME: The "to" type in this diagnostic is wrong; we should convert to "const void *". + return v == ca; +#ifndef NOARC +// expected-error@-2 {{implicit conversion of Objective-C pointer type 'const A *' to C pointer type 'void *' requires a bridged cast}} +// expected-note@-3 {{use __bridge to convert directly (no change in ownership)}} +// expected-note@-4 {{use __bridge_retained to make an ARC object available as a +1 'void *'}} +#endif + return cv == a; +#ifndef NOARC +// expected-error@-2 {{implicit conversion of Objective-C pointer type 'A *' to C pointer type 'const void *' requires a bridged cast}} +// expected-note@-3 {{use __bridge to convert directly (no change in ownership)}} +// expected-note@-4 {{use __bridge_retained to make an ARC object available as a +1 'const void *'}} +#endif + + // FIXME: Shouldn't these be rejected in ARC mode too? + return ca == cv; + return a == cv; + return ca == v; +} |