[ObjC] Boxed strings should use the nullability from stringWithUTF8String's return type

Objective-C NSString has a class method stringWithUTF8String that creates a new
NSString from a C string. Objective-C box expression @(...) can be used to
create an NSString instead of invoking the stringWithUTF8String method directly
(The compiler lowers it down to the invocation though). This commit ensures that
the type of @(string-value) gets the same nullability attributes as the return
type of stringWithUTF8String to ensure that the diagnostics are consistent
between the two.

rdar://33847186

Differential Revision: https://reviews.llvm.org/D39762

llvm-svn: 317727
This commit is contained in:
Alex Lorenz 2017-11-08 21:33:15 +00:00
parent 7adb2fdbba
commit 49370ac7e2
2 changed files with 35 additions and 0 deletions

View File

@ -564,6 +564,13 @@ ExprResult Sema::BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {
BoxingMethod = StringWithUTF8StringMethod;
BoxedType = NSStringPointer;
// Transfer the nullability from method's return type.
Optional<NullabilityKind> Nullability =
BoxingMethod->getReturnType()->getNullability(Context);
if (Nullability)
BoxedType = Context.getAttributedType(
AttributedType::getNullabilityAttrKind(*Nullability), BoxedType,
BoxedType);
}
} else if (ValueType->isBuiltinType()) {
// The other types we support are numeric, char and BOOL/bool. We could also

View File

@ -0,0 +1,28 @@
// RUN: %clang_cc1 -fblocks -fobjc-arc -Wnullable-to-nonnull-conversion -fsyntax-only -verify -Wno-objc-root-class %s
// RUN: %clang_cc1 -fblocks -fobjc-arc -Wnullable-to-nonnull-conversion -fsyntax-only -verify -Wno-objc-root-class -DNOWARN %s
@interface NSString
+ (NSString*
#ifndef NOWARN
_Nullable
#else
_Nonnull
#endif
) stringWithUTF8String:(const char*)x;
@end
void takesNonNull(NSString * _Nonnull ptr);
void testBoxedString() {
const char *str = "hey";
takesNonNull([NSString stringWithUTF8String:str]);
takesNonNull(@(str));
#ifndef NOWARN
// expected-warning@-3 {{implicit conversion from nullable pointer 'NSString * _Nullable' to non-nullable pointer type 'NSString * _Nonnull'}}
// expected-warning@-3 {{implicit conversion from nullable pointer 'NSString * _Nullable' to non-nullable pointer type 'NSString * _Nonnull'}}
#else
// expected-no-diagnostics
#endif
}