Author: dgregor Date: Thu Oct 1 15:20:47 2015 New Revision: 249065 URL: http://llvm.org/viewvc/llvm-project?rev=249065&view=rev Log: 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. Added: cfe/trunk/test/SemaObjCXX/cxx1y-lambda.mm Modified: cfe/trunk/include/clang/AST/ASTContext.h cfe/trunk/lib/AST/ASTContext.cpp cfe/trunk/lib/Sema/SemaLambda.cpp cfe/trunk/lib/Sema/SemaStmt.cpp Modified: cfe/trunk/include/clang/AST/ASTContext.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=249065&r1=249064&r2=249065&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/ASTContext.h (original) +++ cfe/trunk/include/clang/AST/ASTContext.h Thu Oct 1 15:20:47 2015 @@ -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); Modified: cfe/trunk/lib/AST/ASTContext.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=249065&r1=249064&r2=249065&view=diff ============================================================================== --- cfe/trunk/lib/AST/ASTContext.cpp (original) +++ cfe/trunk/lib/AST/ASTContext.cpp Thu Oct 1 15:20:47 2015 @@ -2990,6 +2990,21 @@ static bool isCanonicalResultType(QualTy 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 Res 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. Modified: cfe/trunk/lib/Sema/SemaLambda.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLambda.cpp?rev=249065&r1=249064&r2=249065&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaLambda.cpp (original) +++ cfe/trunk/lib/Sema/SemaLambda.cpp Thu Oct 1 15:20:47 2015 @@ -685,7 +685,8 @@ void Sema::deduceClosureReturnType(Captu 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. Modified: cfe/trunk/lib/Sema/SemaStmt.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=249065&r1=249064&r2=249065&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaStmt.cpp (original) +++ cfe/trunk/lib/Sema/SemaStmt.cpp Thu Oct 1 15:20:47 2015 @@ -3028,8 +3028,11 @@ bool Sema::DeduceFunctionTypeFromReturnE // 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) Added: cfe/trunk/test/SemaObjCXX/cxx1y-lambda.mm URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjCXX/cxx1y-lambda.mm?rev=249065&view=auto ============================================================================== --- cfe/trunk/test/SemaObjCXX/cxx1y-lambda.mm (added) +++ cfe/trunk/test/SemaObjCXX/cxx1y-lambda.mm Thu Oct 1 15:20:47 2015 @@ -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"; + } + }; +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits