summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/AST/ASTContext.h3
-rw-r--r--clang/lib/AST/ASTContext.cpp25
-rw-r--r--clang/lib/Sema/SemaLambda.cpp3
-rw-r--r--clang/lib/Sema/SemaStmt.cpp7
-rw-r--r--clang/test/SemaObjCXX/cxx1y-lambda.mm19
5 files changed, 46 insertions, 11 deletions
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index 8b31876ddda..5b8240925d8 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -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);
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 85add927925..47d0107a66d 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -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.
diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index 952272e37f3..a8f109df284 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -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.
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index 8ca3f5693e2..e876fa921e1 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -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)
diff --git a/clang/test/SemaObjCXX/cxx1y-lambda.mm b/clang/test/SemaObjCXX/cxx1y-lambda.mm
new file mode 100644
index 00000000000..25445cc68c5
--- /dev/null
+++ b/clang/test/SemaObjCXX/cxx1y-lambda.mm
@@ -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";
+ }
+ };
+}
OpenPOWER on IntegriCloud