Allow no-capture lambdas to convert to function pointer.
* semantics.c (maybe_add_lambda_conv_op): New. * parser.c (cp_parser_lambda_expression): Call it. (cp_parser_lambda_declarator_opt): Make op() static if no captures. * mangle.c (write_closure_type_name): Adjust. * semantics.c (finish_this_expr): Adjust. * decl.c (grok_op_properties): Allow it. * call.c (build_user_type_conversion_1): Handle static conversion op. (build_op_call): And op(). From-SVN: r153617
This commit is contained in:
parent
73d2803438
commit
b77068f27b
|
@ -1,3 +1,16 @@
|
||||||
|
2009-10-27 Jason Merrill <jason@redhat.com>
|
||||||
|
|
||||||
|
Allow no-capture lambdas to convert to function pointer.
|
||||||
|
* semantics.c (maybe_add_lambda_conv_op): New.
|
||||||
|
* parser.c (cp_parser_lambda_expression): Call it.
|
||||||
|
(cp_parser_lambda_declarator_opt): Make op() static if
|
||||||
|
no captures.
|
||||||
|
* mangle.c (write_closure_type_name): Adjust.
|
||||||
|
* semantics.c (finish_this_expr): Adjust.
|
||||||
|
* decl.c (grok_op_properties): Allow it.
|
||||||
|
* call.c (build_user_type_conversion_1): Handle static conversion op.
|
||||||
|
(build_op_call): And op().
|
||||||
|
|
||||||
2009-10-26 Jakub Jelinek <jakub@redhat.com>
|
2009-10-26 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
PR debug/41828
|
PR debug/41828
|
||||||
|
|
|
@ -2953,11 +2953,16 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
|
||||||
for (fns = TREE_VALUE (conv_fns); fns; fns = OVL_NEXT (fns))
|
for (fns = TREE_VALUE (conv_fns); fns; fns = OVL_NEXT (fns))
|
||||||
{
|
{
|
||||||
tree fn = OVL_CURRENT (fns);
|
tree fn = OVL_CURRENT (fns);
|
||||||
|
tree first = first_arg;
|
||||||
|
|
||||||
if (DECL_NONCONVERTING_P (fn)
|
if (DECL_NONCONVERTING_P (fn)
|
||||||
&& (flags & LOOKUP_ONLYCONVERTING))
|
&& (flags & LOOKUP_ONLYCONVERTING))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
/* Lambdas have a static conversion op. */
|
||||||
|
if (DECL_STATIC_FUNCTION_P (fn))
|
||||||
|
first = NULL_TREE;
|
||||||
|
|
||||||
/* [over.match.funcs] For conversion functions, the function
|
/* [over.match.funcs] For conversion functions, the function
|
||||||
is considered to be a member of the class of the implicit
|
is considered to be a member of the class of the implicit
|
||||||
object argument for the purpose of defining the type of
|
object argument for the purpose of defining the type of
|
||||||
|
@ -2968,14 +2973,14 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
|
||||||
if (TREE_CODE (fn) == TEMPLATE_DECL)
|
if (TREE_CODE (fn) == TEMPLATE_DECL)
|
||||||
cand = add_template_candidate (&candidates, fn, fromtype,
|
cand = add_template_candidate (&candidates, fn, fromtype,
|
||||||
NULL_TREE,
|
NULL_TREE,
|
||||||
first_arg, NULL, totype,
|
first, NULL, totype,
|
||||||
TYPE_BINFO (fromtype),
|
TYPE_BINFO (fromtype),
|
||||||
conversion_path,
|
conversion_path,
|
||||||
flags,
|
flags,
|
||||||
DEDUCE_CONV);
|
DEDUCE_CONV);
|
||||||
else
|
else
|
||||||
cand = add_function_candidate (&candidates, fn, fromtype,
|
cand = add_function_candidate (&candidates, fn, fromtype,
|
||||||
first_arg, NULL,
|
first, NULL,
|
||||||
TYPE_BINFO (fromtype),
|
TYPE_BINFO (fromtype),
|
||||||
conversion_path,
|
conversion_path,
|
||||||
flags);
|
flags);
|
||||||
|
@ -3382,20 +3387,30 @@ build_op_call (tree obj, VEC(tree,gc) **args, tsubst_flags_t complain)
|
||||||
for (fns = BASELINK_FUNCTIONS (fns); fns; fns = OVL_NEXT (fns))
|
for (fns = BASELINK_FUNCTIONS (fns); fns; fns = OVL_NEXT (fns))
|
||||||
{
|
{
|
||||||
tree fn = OVL_CURRENT (fns);
|
tree fn = OVL_CURRENT (fns);
|
||||||
|
|
||||||
|
tree lfirst = first_mem_arg;
|
||||||
|
if (DECL_STATIC_FUNCTION_P (fn))
|
||||||
|
lfirst = NULL_TREE;
|
||||||
|
|
||||||
if (TREE_CODE (fn) == TEMPLATE_DECL)
|
if (TREE_CODE (fn) == TEMPLATE_DECL)
|
||||||
add_template_candidate (&candidates, fn, base, NULL_TREE,
|
add_template_candidate (&candidates, fn, base, NULL_TREE,
|
||||||
first_mem_arg, *args, NULL_TREE,
|
lfirst, *args, NULL_TREE,
|
||||||
TYPE_BINFO (type),
|
TYPE_BINFO (type),
|
||||||
TYPE_BINFO (type),
|
TYPE_BINFO (type),
|
||||||
LOOKUP_NORMAL, DEDUCE_CALL);
|
LOOKUP_NORMAL, DEDUCE_CALL);
|
||||||
else
|
else
|
||||||
add_function_candidate
|
add_function_candidate
|
||||||
(&candidates, fn, base, first_mem_arg, *args, TYPE_BINFO (type),
|
(&candidates, fn, base, lfirst, *args, TYPE_BINFO (type),
|
||||||
TYPE_BINFO (type), LOOKUP_NORMAL);
|
TYPE_BINFO (type), LOOKUP_NORMAL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
convs = lookup_conversions (type);
|
/* Rather than mess with handling static conversion ops here, just don't
|
||||||
|
look at conversions in lambdas. */
|
||||||
|
if (LAMBDA_TYPE_P (type))
|
||||||
|
convs = NULL_TREE;
|
||||||
|
else
|
||||||
|
convs = lookup_conversions (type);
|
||||||
|
|
||||||
for (; convs; convs = TREE_CHAIN (convs))
|
for (; convs; convs = TREE_CHAIN (convs))
|
||||||
{
|
{
|
||||||
|
|
|
@ -2677,7 +2677,8 @@ add_implicitly_declared_members (tree t,
|
||||||
CLASSTYPE_LAZY_COPY_CTOR (t) = 1;
|
CLASSTYPE_LAZY_COPY_CTOR (t) = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Currently only lambdas get a lazy move ctor. */
|
/* Currently only lambdas get a lazy move ctor, but N2987 adds them for
|
||||||
|
other classes. */
|
||||||
if (LAMBDA_TYPE_P (t))
|
if (LAMBDA_TYPE_P (t))
|
||||||
CLASSTYPE_LAZY_MOVE_CTOR (t) = 1;
|
CLASSTYPE_LAZY_MOVE_CTOR (t) = 1;
|
||||||
|
|
||||||
|
|
|
@ -5073,6 +5073,7 @@ extern void apply_lambda_return_type (tree, tree);
|
||||||
extern tree add_capture (tree, tree, tree, bool, bool);
|
extern tree add_capture (tree, tree, tree, bool, bool);
|
||||||
extern tree add_default_capture (tree, tree, tree);
|
extern tree add_default_capture (tree, tree, tree);
|
||||||
extern tree lambda_expr_this_capture (tree);
|
extern tree lambda_expr_this_capture (tree);
|
||||||
|
extern void maybe_add_lambda_conv_op (tree);
|
||||||
|
|
||||||
/* in tree.c */
|
/* in tree.c */
|
||||||
void cp_free_lang_data (tree t);
|
void cp_free_lang_data (tree t);
|
||||||
|
|
|
@ -10209,8 +10209,13 @@ grok_op_properties (tree decl, bool complain)
|
||||||
|| operator_code == ARRAY_REF
|
|| operator_code == ARRAY_REF
|
||||||
|| operator_code == NOP_EXPR)
|
|| operator_code == NOP_EXPR)
|
||||||
{
|
{
|
||||||
error ("%qD must be a nonstatic member function", decl);
|
if (class_type && LAMBDA_TYPE_P (class_type))
|
||||||
return false;
|
/* Lambdas can have static op() and conv ops. */;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
error ("%qD must be a nonstatic member function", decl);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -1309,7 +1309,7 @@ write_closure_type_name (const tree type)
|
||||||
MANGLE_TRACE_TREE ("closure-type-name", type);
|
MANGLE_TRACE_TREE ("closure-type-name", type);
|
||||||
|
|
||||||
write_string ("Ul");
|
write_string ("Ul");
|
||||||
write_method_parms (parms, /*method_p=*/1, fn);
|
write_method_parms (parms, DECL_NONSTATIC_MEMBER_FUNCTION_P (fn), fn);
|
||||||
write_char ('E');
|
write_char ('E');
|
||||||
write_compact_number (LAMBDA_EXPR_DISCRIMINATOR (lambda));
|
write_compact_number (LAMBDA_EXPR_DISCRIMINATOR (lambda));
|
||||||
}
|
}
|
||||||
|
|
|
@ -7090,6 +7090,8 @@ cp_parser_lambda_expression (cp_parser* parser)
|
||||||
LAMBDA_EXPR_CAPTURE_LIST (lambda_expr) = newlist;
|
LAMBDA_EXPR_CAPTURE_LIST (lambda_expr) = newlist;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
maybe_add_lambda_conv_op (type);
|
||||||
|
|
||||||
type = finish_struct (type, /*attributes=*/NULL_TREE);
|
type = finish_struct (type, /*attributes=*/NULL_TREE);
|
||||||
|
|
||||||
parser->num_template_parameter_lists = saved_num_template_parameter_lists;
|
parser->num_template_parameter_lists = saved_num_template_parameter_lists;
|
||||||
|
@ -7347,15 +7349,25 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
|
||||||
declarator = make_id_declarator (NULL_TREE, ansi_opname (CALL_EXPR),
|
declarator = make_id_declarator (NULL_TREE, ansi_opname (CALL_EXPR),
|
||||||
sfk_none);
|
sfk_none);
|
||||||
|
|
||||||
quals = (LAMBDA_EXPR_MUTABLE_P (lambda_expr)
|
quals = TYPE_UNQUALIFIED;
|
||||||
? TYPE_UNQUALIFIED : TYPE_QUAL_CONST);
|
if (LAMBDA_EXPR_CAPTURE_LIST (lambda_expr) == NULL_TREE
|
||||||
|
&& LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) == CPLD_NONE)
|
||||||
|
{
|
||||||
|
/* A lambda with no captures has a static op() and a conversion op
|
||||||
|
to function type. */
|
||||||
|
if (LAMBDA_EXPR_MUTABLE_P (lambda_expr))
|
||||||
|
error ("lambda expression with no captures declared mutable");
|
||||||
|
return_type_specs.storage_class = sc_static;
|
||||||
|
}
|
||||||
|
else if (!LAMBDA_EXPR_MUTABLE_P (lambda_expr))
|
||||||
|
quals = TYPE_QUAL_CONST;
|
||||||
declarator = make_call_declarator (declarator, param_list, quals,
|
declarator = make_call_declarator (declarator, param_list, quals,
|
||||||
exception_spec,
|
exception_spec,
|
||||||
/*late_return_type=*/NULL_TREE);
|
/*late_return_type=*/NULL_TREE);
|
||||||
|
|
||||||
fco = grokmethod (&return_type_specs,
|
fco = grokmethod (&return_type_specs,
|
||||||
declarator,
|
declarator,
|
||||||
attributes);
|
attributes);
|
||||||
DECL_INITIALIZED_IN_CLASS_P (fco) = 1;
|
DECL_INITIALIZED_IN_CLASS_P (fco) = 1;
|
||||||
DECL_ARTIFICIAL (fco) = 1;
|
DECL_ARTIFICIAL (fco) = 1;
|
||||||
|
|
||||||
|
|
|
@ -2063,17 +2063,13 @@ finish_this_expr (void)
|
||||||
{
|
{
|
||||||
tree result;
|
tree result;
|
||||||
|
|
||||||
if (current_class_ptr)
|
/* In a lambda expression, 'this' refers to the captured 'this'. */
|
||||||
{
|
if (current_function_decl
|
||||||
tree type = TREE_TYPE (current_class_ref);
|
&& LAMBDA_FUNCTION_P (current_function_decl))
|
||||||
|
result = (lambda_expr_this_capture
|
||||||
/* In a lambda expression, 'this' refers to the captured 'this'. */
|
(CLASSTYPE_LAMBDA_EXPR (current_class_type)));
|
||||||
if (LAMBDA_TYPE_P (type))
|
else if (current_class_ptr)
|
||||||
result = lambda_expr_this_capture (CLASSTYPE_LAMBDA_EXPR (type));
|
result = current_class_ptr;
|
||||||
else
|
|
||||||
result = current_class_ptr;
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (current_function_decl
|
else if (current_function_decl
|
||||||
&& DECL_STATIC_FUNCTION_P (current_function_decl))
|
&& DECL_STATIC_FUNCTION_P (current_function_decl))
|
||||||
{
|
{
|
||||||
|
@ -5759,4 +5755,55 @@ lambda_expr_this_capture (tree lambda)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If the closure TYPE has a static op(), also add a conversion to function
|
||||||
|
pointer. */
|
||||||
|
|
||||||
|
void
|
||||||
|
maybe_add_lambda_conv_op (tree type)
|
||||||
|
{
|
||||||
|
bool nested = (current_function_decl != NULL_TREE);
|
||||||
|
tree callop = lambda_function (type);
|
||||||
|
tree rettype, name, fntype, fn, body, compound_stmt;
|
||||||
|
|
||||||
|
if (!DECL_STATIC_FUNCTION_P (callop))
|
||||||
|
return;
|
||||||
|
|
||||||
|
rettype = build_pointer_type (TREE_TYPE (callop));
|
||||||
|
name = mangle_conv_op_name_for_type (rettype);
|
||||||
|
fntype = build_function_type (rettype, void_list_node);
|
||||||
|
fn = build_lang_decl (FUNCTION_DECL, name, fntype);
|
||||||
|
DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (callop);
|
||||||
|
|
||||||
|
if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn
|
||||||
|
&& DECL_ALIGN (fn) < 2 * BITS_PER_UNIT)
|
||||||
|
DECL_ALIGN (fn) = 2 * BITS_PER_UNIT;
|
||||||
|
|
||||||
|
SET_OVERLOADED_OPERATOR_CODE (fn, TYPE_EXPR);
|
||||||
|
grokclassfn (type, fn, NO_SPECIAL);
|
||||||
|
set_linkage_according_to_type (type, fn);
|
||||||
|
rest_of_decl_compilation (fn, toplevel_bindings_p (), at_eof);
|
||||||
|
DECL_IN_AGGR_P (fn) = 1;
|
||||||
|
DECL_ARTIFICIAL (fn) = 1;
|
||||||
|
DECL_NOT_REALLY_EXTERN (fn) = 1;
|
||||||
|
DECL_DECLARED_INLINE_P (fn) = 1;
|
||||||
|
DECL_STATIC_FUNCTION_P (fn) = 1;
|
||||||
|
|
||||||
|
add_method (type, fn, NULL_TREE);
|
||||||
|
|
||||||
|
if (nested)
|
||||||
|
push_function_context ();
|
||||||
|
start_preparsed_function (fn, NULL_TREE,
|
||||||
|
SF_PRE_PARSED | SF_INCLASS_INLINE);
|
||||||
|
body = begin_function_body ();
|
||||||
|
compound_stmt = begin_compound_stmt (0);
|
||||||
|
|
||||||
|
finish_return_stmt (decay_conversion (callop));
|
||||||
|
|
||||||
|
finish_compound_stmt (compound_stmt);
|
||||||
|
finish_function_body (body);
|
||||||
|
|
||||||
|
expand_or_defer_fn (finish_function (2));
|
||||||
|
if (nested)
|
||||||
|
pop_function_context ();
|
||||||
|
}
|
||||||
#include "gt-cp-semantics.h"
|
#include "gt-cp-semantics.h"
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
|
2009-10-27 Jason Merrill <jason@redhat.com>
|
||||||
|
|
||||||
|
* g++.dg/cpp0x/lambda/lambda-conv.C: New.
|
||||||
|
* g++.dg/cpp0x/lambda/lambda-const-neg.C: Adjust.
|
||||||
|
* g++.dg/cpp0x/lambda/lambda-mangle.C: Adjust.
|
||||||
|
* g++.dg/cpp0x/lambda/lambda-non-const.C: Adjust.
|
||||||
|
|
||||||
2009-10-27 Eric Botcazou <ebotcazou@adacore.com>
|
2009-10-27 Eric Botcazou <ebotcazou@adacore.com>
|
||||||
|
|
||||||
* gnat.dg/null_pointer_deref1.adb: Accept Constraint_Error.
|
* gnat.dg/null_pointer_deref1.adb: Accept Constraint_Error.
|
||||||
|
|
|
@ -3,11 +3,11 @@
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
void call(const F& f) { f(); } // { dg-error "discards qualifiers" }
|
void call(const F& f) { f(); }
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
call([] () -> void {});
|
call([] () -> void {});
|
||||||
call([] () mutable -> void {}); // { dg-message "" "`f' does not have const `operator()'" }
|
call([] () mutable -> void {}); // { dg-message "" "declared mutable" }
|
||||||
|
|
||||||
int i = -1;
|
int i = -1;
|
||||||
call([&i] () -> void { i = 0; });
|
call([&i] () -> void { i = 0; });
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
// { dg-options -std=c++0x }
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
void (*pfn)() = []{};
|
||||||
|
}
|
|
@ -9,8 +9,8 @@ inline void g(int n) {
|
||||||
// The closure type is encoded as Z1giEUlvE_.
|
// The closure type is encoded as Z1giEUlvE_.
|
||||||
// The call operator of that type is _ZZ1giENKUlvE_clEv.
|
// The call operator of that type is _ZZ1giENKUlvE_clEv.
|
||||||
|
|
||||||
// { dg-final { scan-assembler "_ZZ1giENKUlvE_clEv" } }
|
// { dg-final { scan-assembler "_ZZ1giENUlvE_clEv" } }
|
||||||
// { dg-final { scan-assembler "weak\[ \t\]*_?_ZZ1giENKUlvE_clEv" { target { ! { *-*-darwin* *-*-mingw* *-*-cygwin } } } } }
|
// { dg-final { scan-assembler "weak\[ \t\]*_?_ZZ1giENUlvE_clEv" { target { ! { *-*-darwin* *-*-mingw* *-*-cygwin } } } } }
|
||||||
|
|
||||||
algo([=]{return n+bef();});
|
algo([=]{return n+bef();});
|
||||||
// The captured entities do not participate in <lambda-sig>
|
// The captured entities do not participate in <lambda-sig>
|
||||||
|
@ -31,17 +31,17 @@ struct S {
|
||||||
void f(int =
|
void f(int =
|
||||||
// Type: ZN1S1fEiiEd0_UlvE_
|
// Type: ZN1S1fEiiEd0_UlvE_
|
||||||
// Operator: _ZZN1S1fEiiEd0_NKUlvE_clEv
|
// Operator: _ZZN1S1fEiiEd0_NKUlvE_clEv
|
||||||
// { dg-final { scan-assembler "_ZZN1S1fEiiEd0_NKUlvE_clEv" } }
|
// { dg-final { scan-assembler "_ZZN1S1fEiiEd0_NUlvE_clEv" } }
|
||||||
// { dg-final { scan-assembler "weak\[ \t\]*_?_ZZN1S1fEiiEd0_NKUlvE_clEv" { target { ! { *-*-darwin* *-*-mingw* *-*-cygwin } } } } }
|
// { dg-final { scan-assembler "weak\[ \t\]*_?_ZZN1S1fEiiEd0_NUlvE_clEv" { target { ! { *-*-darwin* *-*-mingw* *-*-cygwin } } } } }
|
||||||
[]{return 1;}()
|
[]{return 1;}()
|
||||||
// Type: ZN1S1fEiiEd0_UlvE0_
|
// Type: ZN1S1fEiiEd0_UlvE0_
|
||||||
// Operator: _ZZN1S1fEiiEd0_NKUlvE0_clEv
|
// Operator: _ZZN1S1fEiiEd0_NKUlvE0_clEv
|
||||||
// { dg-final { scan-assembler "_ZZN1S1fEiiEd0_NKUlvE0_clEv" } }
|
// { dg-final { scan-assembler "_ZZN1S1fEiiEd0_NUlvE0_clEv" } }
|
||||||
+ []{return 2;}(),
|
+ []{return 2;}(),
|
||||||
int =
|
int =
|
||||||
// Type: ZN1S1fEiiEd_UlvE_
|
// Type: ZN1S1fEiiEd_UlvE_
|
||||||
// Operator: _ZZN1S1fEiiEd_NKUlvE_clEv
|
// Operator: _ZZN1S1fEiiEd_NKUlvE_clEv
|
||||||
// { dg-final { scan-assembler "_ZZN1S1fEiiEd_NKUlvE_clEv" } }
|
// { dg-final { scan-assembler "_ZZN1S1fEiiEd_NUlvE_clEv" } }
|
||||||
[]{return 3;}());
|
[]{return 3;}());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -52,8 +52,8 @@ template<typename T> int R<T>::x = []{return 1;}();
|
||||||
template int R<int>::x;
|
template int R<int>::x;
|
||||||
// Type of lambda in intializer of R<int>::x: N1RIiE1xMUlvE_E
|
// Type of lambda in intializer of R<int>::x: N1RIiE1xMUlvE_E
|
||||||
// Corresponding operator(): _ZNK1RIiE1xMUlvE_clEv
|
// Corresponding operator(): _ZNK1RIiE1xMUlvE_clEv
|
||||||
// { dg-final { scan-assembler "_ZNK1RIiE1xMUlvE_clEv" } }
|
// { dg-final { scan-assembler "_ZN1RIiE1xMUlvE_clEv" } }
|
||||||
// { dg-final { scan-assembler "weak\[ \t\]*_?_ZNK1RIiE1xMUlvE_clEv" { target { ! { *-*-mingw* *-*-cygwin } } } } }
|
// { dg-final { scan-assembler "weak\[ \t\]*_?_ZN1RIiE1xMUlvE_clEv" { target { ! { *-*-mingw* *-*-cygwin } } } } }
|
||||||
|
|
||||||
void bar()
|
void bar()
|
||||||
{
|
{
|
||||||
|
@ -63,7 +63,7 @@ void bar()
|
||||||
}
|
}
|
||||||
|
|
||||||
// lambdas used in non-template, non-class body initializers are internal.
|
// lambdas used in non-template, non-class body initializers are internal.
|
||||||
// { dg-final { scan-assembler-not "weak\[^\n\r\]*_ZNKUlv" } }
|
// { dg-final { scan-assembler-not "weak\[^\n\r\]*_ZNUlv" } }
|
||||||
// { dg-final { scan-assembler-not "weak\[^\n\r\]*variable" } }
|
// { dg-final { scan-assembler-not "weak\[^\n\r\]*variable" } }
|
||||||
int variable = []{return 1;}();
|
int variable = []{return 1;}();
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,6 @@ void call(F f) { f(); }
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
call([] () -> void {});
|
call([] () -> void {});
|
||||||
call([] () mutable -> void {});
|
|
||||||
|
|
||||||
int i = -1;
|
int i = -1;
|
||||||
call([i] () mutable -> void { i = 0; });
|
call([i] () mutable -> void { i = 0; });
|
||||||
|
|
Loading…
Reference in New Issue