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);
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 {
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.
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.
// 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)
--- /dev/null
+// 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";
+ }
+ };
+}