forked from OSchip/llvm-project
Perform Objective-C lifetime adjustments before comparing deduced lambda result types.
Objective-C ARC lifetime qualifiers are dropped when canonicalizing function types. Perform the same adjustment before comparing the deduced result types of lambdas. Fixes rdar://problem/22344904. llvm-svn: 249065
This commit is contained in:
parent
57e40deb8d
commit
a602a153de
|
@ -968,6 +968,9 @@ public:
|
|||
const FunctionType *adjustFunctionType(const FunctionType *Fn,
|
||||
FunctionType::ExtInfo EInfo);
|
||||
|
||||
/// Adjust the given function result type.
|
||||
CanQualType getCanonicalFunctionResultType(QualType ResultType) const;
|
||||
|
||||
/// \brief Change the result type of a function type once it is deduced.
|
||||
void adjustDeducedFunctionResultType(FunctionDecl *FD, QualType ResultType);
|
||||
|
||||
|
|
|
@ -2990,6 +2990,21 @@ static bool isCanonicalResultType(QualType T) {
|
|||
T.getObjCLifetime() == Qualifiers::OCL_ExplicitNone);
|
||||
}
|
||||
|
||||
CanQualType
|
||||
ASTContext::getCanonicalFunctionResultType(QualType ResultType) const {
|
||||
CanQualType CanResultType = getCanonicalType(ResultType);
|
||||
|
||||
// Canonical result types do not have ARC lifetime qualifiers.
|
||||
if (CanResultType.getQualifiers().hasObjCLifetime()) {
|
||||
Qualifiers Qs = CanResultType.getQualifiers();
|
||||
Qs.removeObjCLifetime();
|
||||
return CanQualType::CreateUnsafe(
|
||||
getQualifiedType(CanResultType.getUnqualifiedType(), Qs));
|
||||
}
|
||||
|
||||
return CanResultType;
|
||||
}
|
||||
|
||||
QualType
|
||||
ASTContext::getFunctionType(QualType ResultTy, ArrayRef<QualType> ArgArray,
|
||||
const FunctionProtoType::ExtProtoInfo &EPI) const {
|
||||
|
@ -3027,14 +3042,8 @@ ASTContext::getFunctionType(QualType ResultTy, ArrayRef<QualType> ArgArray,
|
|||
CanonicalEPI.HasTrailingReturn = false;
|
||||
CanonicalEPI.ExceptionSpec = FunctionProtoType::ExceptionSpecInfo();
|
||||
|
||||
// Result types do not have ARC lifetime qualifiers.
|
||||
QualType CanResultTy = getCanonicalType(ResultTy);
|
||||
if (ResultTy.getQualifiers().hasObjCLifetime()) {
|
||||
Qualifiers Qs = CanResultTy.getQualifiers();
|
||||
Qs.removeObjCLifetime();
|
||||
CanResultTy = getQualifiedType(CanResultTy.getUnqualifiedType(), Qs);
|
||||
}
|
||||
|
||||
// Adjust the canonical function result type.
|
||||
CanQualType CanResultTy = getCanonicalFunctionResultType(ResultTy);
|
||||
Canonical = getFunctionType(CanResultTy, CanonicalArgs, CanonicalEPI);
|
||||
|
||||
// Get the new insert position for the node we care about.
|
||||
|
|
|
@ -685,7 +685,8 @@ void Sema::deduceClosureReturnType(CapturingScopeInfo &CSI) {
|
|||
|
||||
QualType ReturnType =
|
||||
(RetE ? RetE->getType() : Context.VoidTy).getUnqualifiedType();
|
||||
if (Context.hasSameType(ReturnType, CSI.ReturnType))
|
||||
if (Context.getCanonicalFunctionResultType(ReturnType) ==
|
||||
Context.getCanonicalFunctionResultType(CSI.ReturnType))
|
||||
continue;
|
||||
|
||||
// FIXME: This is a poor diagnostic for ReturnStmts without expressions.
|
||||
|
|
|
@ -3028,8 +3028,11 @@ bool Sema::DeduceFunctionTypeFromReturnExpr(FunctionDecl *FD,
|
|||
// the program is ill-formed.
|
||||
if (AT->isDeduced() && !FD->isInvalidDecl()) {
|
||||
AutoType *NewAT = Deduced->getContainedAutoType();
|
||||
if (!FD->isDependentContext() &&
|
||||
!Context.hasSameType(AT->getDeducedType(), NewAT->getDeducedType())) {
|
||||
CanQualType OldDeducedType = Context.getCanonicalFunctionResultType(
|
||||
AT->getDeducedType());
|
||||
CanQualType NewDeducedType = Context.getCanonicalFunctionResultType(
|
||||
NewAT->getDeducedType());
|
||||
if (!FD->isDependentContext() && OldDeducedType != NewDeducedType) {
|
||||
const LambdaScopeInfo *LambdaSI = getCurLambda();
|
||||
if (LambdaSI && LambdaSI->HasImplicitReturnType) {
|
||||
Diag(ReturnLoc, diag::err_typecheck_missing_return_type_incompatible)
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
// RUN: %clang_cc1 -std=c++1y -Wno-unused-value -fsyntax-only -verify -fobjc-arc %s
|
||||
|
||||
// expected-no-diagnostics
|
||||
__attribute__((objc_root_class))
|
||||
@interface NSString
|
||||
@end
|
||||
|
||||
// rdar://problem/22344904
|
||||
void testResultTypeDeduction(int i) {
|
||||
auto x = [i] {
|
||||
switch (i) {
|
||||
case 0:
|
||||
return @"foo";
|
||||
|
||||
default:
|
||||
return @"bar";
|
||||
}
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue