"lambda expression in default argument cannot capture any entity">;
def err_lambda_incomplete_result : Error<
"incomplete result type %0 in lambda expression">;
- def err_lambda_objc_object_result : Error<
- "non-pointer Objective-C class type %0 in lambda expression result">;
def err_noreturn_lambda_has_return_expr : Error<
"lambda declared 'noreturn' should not return">;
def warn_maybe_falloff_nonvoid_lambda : Warning<
QualType BuildExtVectorType(QualType T, Expr *ArraySize,
SourceLocation AttrLoc);
+ bool CheckFunctionReturnType(QualType T, SourceLocation Loc);
+
/// \brief Build a function type.
///
/// This routine checks the function type according to C++ rules and
diag::err_invalid_thread)
<< DeclSpec::getSpecifierName(TSCS);
- // Do not allow returning a objc interface by-value.
- if (R->getAs<FunctionType>()->getResultType()->isObjCObjectType()) {
- Diag(D.getIdentifierLoc(),
- diag::err_object_cannot_be_passed_returned_by_value) << 0
- << R->getAs<FunctionType>()->getResultType()
- << FixItHint::CreateInsertion(D.getIdentifierLoc(), "*");
-
- QualType T = R->getAs<FunctionType>()->getResultType();
- T = Context.getObjCObjectPointerType(T);
- if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(R)) {
- FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
- R = Context.getFunctionType(T, FPT->getArgTypes(), EPI);
- }
- else if (isa<FunctionNoProtoType>(R))
- R = Context.getFunctionNoProtoType(T);
- }
-
bool isFriend = false;
FunctionTemplateDecl *FunctionTemplate = 0;
bool isExplicitSpecialization = false;
if (ReturnType) {
resultDeclType = GetTypeFromParser(ReturnType, &ResultTInfo);
- // Methods cannot return interface types. All ObjC objects are
- // passed by reference.
- if (resultDeclType->isObjCObjectType()) {
- Diag(MethodLoc, diag::err_object_cannot_be_passed_returned_by_value)
- << 0 << resultDeclType;
+ if (CheckFunctionReturnType(resultDeclType, MethodLoc))
return 0;
- }
-
+
HasRelatedResultType = (resultDeclType == Context.getObjCInstanceType());
} else { // get the type for "id".
resultDeclType = Context.getObjCIdType();
else
// Perform the default array/function conversions (C99 6.7.5.3p[7,8]).
ArgType = Context.getAdjustedParameterType(ArgType);
- if (ArgType->isObjCObjectType()) {
- Diag(Param->getLocation(),
- diag::err_object_cannot_be_passed_returned_by_value)
- << 1 << ArgType;
- Param->setInvalidDecl();
- }
+
Param->setDeclContext(ObjCMethod);
-
Params.push_back(Param);
}
CurBlock->TheDecl->setIsVariadic(isVariadic);
- // Don't allow returning a objc interface by value.
- if (RetTy->isObjCObjectType()) {
- Diag(ParamInfo.getLocStart(),
- diag::err_object_cannot_be_passed_returned_by_value) << 0 << RetTy;
- return;
- }
-
// Context.DependentTy is used as a placeholder for a missing block
// return type. TODO: what should we do with declarators like:
// ^ * { ... }
if (RequireCompleteType(CallOperator->getLocStart(), LSI->ReturnType,
diag::err_lambda_incomplete_result)) {
// Do nothing.
- } else if (LSI->ReturnType->isObjCObjectOrInterfaceType()) {
- Diag(CallOperator->getLocStart(), diag::err_lambda_objc_object_result)
- << LSI->ReturnType;
}
}
} else {
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/ErrorHandling.h"
+#include "TypeLocBuilder.h"
+
using namespace clang;
/// isOmittedBlockReturnType - Return true if this declarator is missing a
return Context.getDependentSizedExtVectorType(T, ArraySize, AttrLoc);
}
-QualType Sema::BuildFunctionType(QualType T,
- llvm::MutableArrayRef<QualType> ParamTypes,
- SourceLocation Loc, DeclarationName Entity,
- const FunctionProtoType::ExtProtoInfo &EPI) {
+bool Sema::CheckFunctionReturnType(QualType T, SourceLocation Loc) {
if (T->isArrayType() || T->isFunctionType()) {
Diag(Loc, diag::err_func_returning_array_function)
<< T->isFunctionType() << T;
- return QualType();
+ return true;
}
// Functions cannot return half FP.
if (T->isHalfType()) {
Diag(Loc, diag::err_parameters_retval_cannot_have_fp16_type) << 1 <<
FixItHint::CreateInsertion(Loc, "*");
- return QualType();
+ return true;
+ }
+
+ // Methods cannot return interface types. All ObjC objects are
+ // passed by reference.
+ if (T->isObjCObjectType()) {
+ Diag(Loc, diag::err_object_cannot_be_passed_returned_by_value) << 0 << T;
+ return 0;
}
+ return false;
+}
+
+QualType Sema::BuildFunctionType(QualType T,
+ llvm::MutableArrayRef<QualType> ParamTypes,
+ SourceLocation Loc, DeclarationName Entity,
+ const FunctionProtoType::ExtProtoInfo &EPI) {
bool Invalid = false;
+
+ Invalid |= CheckFunctionReturnType(T, Loc);
+
for (unsigned Idx = 0, Cnt = ParamTypes.size(); Idx < Cnt; ++Idx) {
// FIXME: Loc is too inprecise here, should use proper locations for args.
QualType ParamType = Context.getAdjustedParameterType(ParamTypes[Idx]);
}
}
+ // Methods cannot return interface types. All ObjC objects are
+ // passed by reference.
+ if (T->isObjCObjectType()) {
+ SourceLocation DiagLoc, FixitLoc;
+ if (TInfo) {
+ DiagLoc = TInfo->getTypeLoc().getLocStart();
+ FixitLoc = S.PP.getLocForEndOfToken(TInfo->getTypeLoc().getLocEnd());
+ } else {
+ DiagLoc = D.getDeclSpec().getTypeSpecTypeLoc();
+ FixitLoc = S.PP.getLocForEndOfToken(D.getDeclSpec().getLocEnd());
+ }
+ S.Diag(DiagLoc, diag::err_object_cannot_be_passed_returned_by_value)
+ << 0 << T
+ << FixItHint::CreateInsertion(FixitLoc, "*");
+
+ T = Context.getObjCObjectPointerType(T);
+ if (TInfo) {
+ TypeLocBuilder TLB;
+ TLB.pushFullCopy(TInfo->getTypeLoc());
+ ObjCObjectPointerTypeLoc TLoc = TLB.push<ObjCObjectPointerTypeLoc>(T);
+ TLoc.setStarLoc(FixitLoc);
+ TInfo = TLB.getTypeSourceInfo(Context, T);
+ }
+
+ D.setInvalidType(true);
+ }
+
// cv-qualifiers on return types are pointless except when the type is a
// class type in C++.
if ((T.getCVRQualifiers() || T->isAtomicType()) &&
QualType exprResultType =
getDerived().TransformType(exprFunctionType->getResultType());
- // Don't allow returning a objc interface by value.
- if (exprResultType->isObjCObjectType()) {
- getSema().Diag(E->getCaretLocation(),
- diag::err_object_cannot_be_passed_returned_by_value)
- << 0 << exprResultType;
- getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/0);
- return ExprError();
- }
-
QualType functionType =
getDerived().RebuildFunctionProtoType(exprResultType, paramTypes,
exprFunctionType->getExtProtoInfo());
@end
void test_result_type() {
- auto l1 = [] () -> A { }; // expected-error{{non-pointer Objective-C class type 'A' in lambda expression result}}
+ auto l1 = [] () -> A { }; // expected-error{{interface type 'A' cannot be returned by value; did you forget * in 'A'?}}
}
@interface T
- - (int)foo: (T (^)(T*)) x;
+ - (int)foo: (T* (^)(T*)) x;
@end
void foo(T *P) {
// Objective-C++ recovery
// RUN: cp %s %t
-// RUN: not %clang_cc1 -fixit -x objective-c++ %t
-// RUN: %clang_cc1 -fsyntax-only -Werror -x objective-c++ %t
+// RUN: not %clang_cc1 -fixit -x objective-c++ %t -std=c++11
+// RUN: %clang_cc1 -fsyntax-only -Werror -x objective-c++ %t -std=c++11
// rdar://9603056
@interface S @end
return P;
}
+NSArray (func2)() { return 0; }
+
+#ifdef __cplusplus
+void test_result_type() {
+ auto l1 = [] () -> NSArray { return 0; };
+}
+#endif
+
int main() {
NSArray pluginNames = [NSArray arrayWithObjects];
}
}
@end
+@interface arrayfun
+- (int[6])arrayRet; // expected-error {{function cannot return array type 'int [6]'}}
+- (int())funcRet; // expected-error {{function cannot return function type 'int ()'}}
+@end