[cfe-commits] r150503 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaLambda.cpp test/CXX/expr/expr.prim/expr.prim.lambda/p4.cpp test/CXX/expr/expr.prim/expr.prim.lambda/p4.mm
Douglas Gregor
dgregor at apple.com
Tue Feb 14 13:20:44 PST 2012
Author: dgregor
Date: Tue Feb 14 15:20:44 2012
New Revision: 150503
URL: http://llvm.org/viewvc/llvm-project?rev=150503&view=rev
Log:
Check the return type of lambda expressions.
Added:
cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p4.mm
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaLambda.cpp
cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p4.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=150503&r1=150502&r2=150503&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Feb 14 15:20:44 2012
@@ -3999,44 +3999,51 @@
def err_return_in_constructor_handler : Error<
"return in the catch of a function try block of a constructor is illegal">;
-def err_capture_more_than_once : Error<
- "%0 can appear only once in a capture list">;
-def err_reference_capture_with_reference_default : Error<
- "'&' cannot precede a capture when the capture default is '&'">;
-def err_this_capture_with_copy_default : Error<
- "'this' cannot be explicitly captured when the capture default is '='">;
-def err_copy_capture_with_copy_default : Error<
- "'&' must precede a capture when the capture default is '='">;
-def err_capture_does_not_name_variable : Error<
- "%0 in capture list does not name a variable">;
-def err_capture_non_automatic_variable : Error<
- "%0 cannot be captured because it does not have automatic storage duration">;
-def err_this_capture : Error<
- "'this' cannot be %select{implicitly |}0captured in this context">;
-def err_lambda_capture_block : Error<
- "__block variable %0 cannot be captured in a lambda expression">;
-def err_lambda_capture_anonymous_var : Error<
- "unnamed variable cannot be implicitly captured in a lambda expression">;
-def err_lambda_capture_vm_type : Error<
- "variable %0 with variably modified type cannot be captured in "
- "a lambda expression">;
-def err_lambda_impcap : Error<
- "variable %0 cannot be implicitly captured in a lambda with no "
- "capture-default specified">;
-def note_lambda_decl : Note<"lambda expression begins here">;
-def err_lambda_unevaluated_operand : Error<
- "lambda expression in an unevaluated operand">;
-def ext_lambda_implies_void_return : ExtWarn<
- "C++11 requires lambda with omitted result type to consist of a single "
- "return statement">,
- InGroup<DiagGroup<"lambda-return">>;
-def err_lambda_return_init_list : Error<
- "cannot deduce lambda return type from initializer list">;
-def err_lambda_capture_default_arg : Error<
- "lambda expression in default argument cannot capture any entity">;
-def err_lambda_unexpanded_pack : Error<
- "unexpanded function parameter pack capture is unsupported">;
-
+let CategoryName = "Lambda Issue" in {
+ def err_capture_more_than_once : Error<
+ "%0 can appear only once in a capture list">;
+ def err_reference_capture_with_reference_default : Error<
+ "'&' cannot precede a capture when the capture default is '&'">;
+ def err_this_capture_with_copy_default : Error<
+ "'this' cannot be explicitly captured when the capture default is '='">;
+ def err_copy_capture_with_copy_default : Error<
+ "'&' must precede a capture when the capture default is '='">;
+ def err_capture_does_not_name_variable : Error<
+ "%0 in capture list does not name a variable">;
+ def err_capture_non_automatic_variable : Error<
+ "%0 cannot be captured because it does not have automatic storage "
+ "duration">;
+ def err_this_capture : Error<
+ "'this' cannot be %select{implicitly |}0captured in this context">;
+ def err_lambda_capture_block : Error<
+ "__block variable %0 cannot be captured in a lambda expression">;
+ def err_lambda_capture_anonymous_var : Error<
+ "unnamed variable cannot be implicitly captured in a lambda expression">;
+ def err_lambda_capture_vm_type : Error<
+ "variable %0 with variably modified type cannot be captured in "
+ "a lambda expression">;
+ def err_lambda_impcap : Error<
+ "variable %0 cannot be implicitly captured in a lambda with no "
+ "capture-default specified">;
+ def note_lambda_decl : Note<"lambda expression begins here">;
+ def err_lambda_unevaluated_operand : Error<
+ "lambda expression in an unevaluated operand">;
+ def ext_lambda_implies_void_return : ExtWarn<
+ "C++11 requires lambda with omitted result type to consist of a single "
+ "return statement">,
+ InGroup<DiagGroup<"lambda-return">>;
+ def err_lambda_return_init_list : Error<
+ "cannot deduce lambda return type from initializer list">;
+ def err_lambda_capture_default_arg : Error<
+ "lambda expression in default argument cannot capture any entity">;
+ def err_lambda_unexpanded_pack : Error<
+ "unexpanded function parameter pack capture is unsupported">;
+ 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_operator_arrow_circular : Error<
"circular pointer delegation detected">;
def err_pseudo_dtor_base_not_scalar : Error<
Modified: cfe/trunk/lib/Sema/SemaLambda.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLambda.cpp?rev=150503&r1=150502&r2=150503&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLambda.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLambda.cpp Tue Feb 14 15:20:44 2012
@@ -87,6 +87,17 @@
if (ExplicitResultType) {
LSI->ReturnType = CallOperator->getResultType();
+
+ if (!LSI->ReturnType->isDependentType() &&
+ !LSI->ReturnType->isVoidType()) {
+ 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 {
LSI->HasImplicitReturnType = true;
}
@@ -161,7 +172,6 @@
CheckExtraCXXDefaultArguments(ParamInfo);
MethodTyInfo = GetTypeForDeclarator(ParamInfo, CurScope);
- // FIXME: Can these asserts actually fail?
assert(MethodTyInfo && "no type from lambda-declarator");
EndLoc = ParamInfo.getSourceRange().getEnd();
@@ -266,7 +276,8 @@
// for unqualified name lookup (3.4.1); each such lookup shall find a
// variable with automatic storage duration declared in the reaching
// scope of the local lambda expression.
- // FIXME: Check reaching scope.
+ //
+ // Note that the 'reaching scope' check happens in TryCaptureVar.
VarDecl *Var = R.getAsSingle<VarDecl>();
if (!Var) {
Diag(C->Loc, diag::err_capture_does_not_name_variable) << C->Id;
@@ -321,8 +332,6 @@
addLambdaParameters(Method, CurScope, Proto.getParams());
}
- // FIXME: Check return type is complete, !isObjCObjectType
-
// Enter a new evaluation context to insulate the lambda from any
// cleanups from the enclosing full-expression.
PushExpressionEvaluationContext(PotentiallyEvaluated);
Modified: cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p4.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p4.cpp?rev=150503&r1=150502&r2=150503&view=diff
==============================================================================
--- cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p4.cpp (original)
+++ cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p4.cpp Tue Feb 14 15:20:44 2012
@@ -41,3 +41,11 @@
return x; // expected-error{{return type 'const X' must match previous return type 'X' when block literal has unspecified explicit return type}}
}(5);
}
+
+struct Incomplete; // expected-note{{forward declaration of 'Incomplete'}}
+void test_result_type(int N) {
+ auto l1 = [] () -> Incomplete { }; // expected-error{{incomplete result type 'Incomplete' in lambda expression}}
+
+ typedef int vla[N];
+ auto l2 = [] () -> vla { }; // expected-error{{function cannot return array type 'vla' (aka 'int [N]')}}
+}
Added: cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p4.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p4.mm?rev=150503&view=auto
==============================================================================
--- cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p4.mm (added)
+++ cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p4.mm Tue Feb 14 15:20:44 2012
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify
+
+ at interface A
+ at end
+
+void test_result_type() {
+ auto l1 = [] () -> A { }; // expected-error{{non-pointer Objective-C class type 'A' in lambda expression result}}
+}
More information about the cfe-commits
mailing list