re PR c++/54764 (In class initialization of non-static lambda member can't be used in class with default template paramer)
PR c++/54764 PR c++/55972 * name-lookup.h (tag_scope): Add ts_lambda. * semantics.c (begin_lambda_type): Use it. * decl.c (xref_tag_1): Set CLASSTYPE_LAMBDA_EXPR. * pt.c (check_default_tmpl_args): Ignore lambdas. (push_template_decl_real): Handle lambdas. * tree.c (no_linkage_check): Adjust lambda check. From-SVN: r196742
This commit is contained in:
parent
8e519a8b0a
commit
c73356802f
@ -1,5 +1,14 @@
|
||||
2013-03-16 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/54764
|
||||
PR c++/55972
|
||||
* name-lookup.h (tag_scope): Add ts_lambda.
|
||||
* semantics.c (begin_lambda_type): Use it.
|
||||
* decl.c (xref_tag_1): Set CLASSTYPE_LAMBDA_EXPR.
|
||||
* pt.c (check_default_tmpl_args): Ignore lambdas.
|
||||
(push_template_decl_real): Handle lambdas.
|
||||
* tree.c (no_linkage_check): Adjust lambda check.
|
||||
|
||||
PR c++/56039
|
||||
* tree.c (strip_typedefs_expr): Complain about lambda, don't abort.
|
||||
|
||||
|
@ -11887,11 +11887,12 @@ lookup_and_check_tag (enum tag_types tag_code, tree name,
|
||||
|
||||
static tree
|
||||
xref_tag_1 (enum tag_types tag_code, tree name,
|
||||
tag_scope scope, bool template_header_p)
|
||||
tag_scope orig_scope, bool template_header_p)
|
||||
{
|
||||
enum tree_code code;
|
||||
tree t;
|
||||
tree context = NULL_TREE;
|
||||
tag_scope scope;
|
||||
|
||||
gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
|
||||
|
||||
@ -11911,6 +11912,11 @@ xref_tag_1 (enum tag_types tag_code, tree name,
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
if (orig_scope == ts_lambda)
|
||||
scope = ts_current;
|
||||
else
|
||||
scope = orig_scope;
|
||||
|
||||
/* In case of anonymous name, xref_tag is only called to
|
||||
make type node and push name. Name lookup is not required. */
|
||||
if (ANON_AGGRNAME_P (name))
|
||||
@ -11984,6 +11990,10 @@ xref_tag_1 (enum tag_types tag_code, tree name,
|
||||
{
|
||||
t = make_class_type (code);
|
||||
TYPE_CONTEXT (t) = context;
|
||||
if (orig_scope == ts_lambda)
|
||||
/* Remember that we're declaring a lambda to avoid bogus errors
|
||||
in push_template_decl. */
|
||||
CLASSTYPE_LAMBDA_EXPR (t) = error_mark_node;
|
||||
t = pushtag (name, t, scope);
|
||||
}
|
||||
}
|
||||
|
@ -132,10 +132,11 @@ typedef enum tag_scope {
|
||||
ts_global = 1, /* All scopes. This is the 3.4.1
|
||||
[basic.lookup.unqual] lookup mentioned
|
||||
in [basic.lookup.elab]/2. */
|
||||
ts_within_enclosing_non_class = 2 /* Search within enclosing non-class
|
||||
ts_within_enclosing_non_class = 2, /* Search within enclosing non-class
|
||||
only, for friend class lookup
|
||||
according to [namespace.memdef]/3
|
||||
and [class.friend]/9. */
|
||||
ts_lambda = 3 /* Declaring a lambda closure. */
|
||||
} tag_scope;
|
||||
|
||||
typedef struct GTY(()) cp_class_binding {
|
||||
|
@ -4306,6 +4306,13 @@ check_default_tmpl_args (tree decl, tree parms, bool is_primary,
|
||||
local scope. */
|
||||
return true;
|
||||
|
||||
if (TREE_CODE (decl) == TYPE_DECL
|
||||
&& TREE_TYPE (decl)
|
||||
&& LAMBDA_TYPE_P (TREE_TYPE (decl)))
|
||||
/* A lambda doesn't have an explicit declaration; don't complain
|
||||
about the parms of the enclosing class. */
|
||||
return true;
|
||||
|
||||
if (current_class_type
|
||||
&& !TYPE_BEING_DEFINED (current_class_type)
|
||||
&& DECL_LANG_SPECIFIC (decl)
|
||||
@ -4674,6 +4681,8 @@ push_template_decl_real (tree decl, bool is_friend)
|
||||
if (!ctx
|
||||
|| TREE_CODE (ctx) == FUNCTION_DECL
|
||||
|| (CLASS_TYPE_P (ctx) && TYPE_BEING_DEFINED (ctx))
|
||||
|| (TREE_CODE (decl) == TYPE_DECL
|
||||
&& LAMBDA_TYPE_P (TREE_TYPE (decl)))
|
||||
|| (is_friend && !DECL_TEMPLATE_INFO (decl)))
|
||||
{
|
||||
if (DECL_LANG_SPECIFIC (decl)
|
||||
|
@ -8984,7 +8984,7 @@ begin_lambda_type (tree lambda)
|
||||
/* Create the new RECORD_TYPE for this lambda. */
|
||||
type = xref_tag (/*tag_code=*/record_type,
|
||||
name,
|
||||
/*scope=*/ts_within_enclosing_non_class,
|
||||
/*scope=*/ts_lambda,
|
||||
/*template_header_p=*/false);
|
||||
}
|
||||
|
||||
|
@ -2028,11 +2028,12 @@ no_linkage_check (tree t, bool relaxed_p)
|
||||
if (TYPE_PTRMEMFUNC_P (t))
|
||||
goto ptrmem;
|
||||
/* Lambda types that don't have mangling scope have no linkage. We
|
||||
check CLASSTYPE_LAMBDA_EXPR here rather than LAMBDA_TYPE_P because
|
||||
check CLASSTYPE_LAMBDA_EXPR for error_mark_node because
|
||||
when we get here from pushtag none of the lambda information is
|
||||
set up yet, so we want to assume that the lambda has linkage and
|
||||
fix it up later if not. */
|
||||
if (CLASSTYPE_LAMBDA_EXPR (t)
|
||||
&& CLASSTYPE_LAMBDA_EXPR (t) != error_mark_node
|
||||
&& LAMBDA_TYPE_EXTRA_SCOPE (t) == NULL_TREE)
|
||||
return t;
|
||||
/* Fall through. */
|
||||
|
8
gcc/testsuite/g++.dg/cpp0x/lambda/lambda-defarg4.C
Normal file
8
gcc/testsuite/g++.dg/cpp0x/lambda/lambda-defarg4.C
Normal file
@ -0,0 +1,8 @@
|
||||
// PR c++/54764
|
||||
// { dg-require-effective-target c++11 }
|
||||
|
||||
template<class T = void>
|
||||
struct c
|
||||
{
|
||||
int (*f)(int) = [](int i){return i + i;};
|
||||
};
|
9
gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nsdmi3.C
Normal file
9
gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nsdmi3.C
Normal file
@ -0,0 +1,9 @@
|
||||
// PR c++/55972
|
||||
// { dg-do compile { target c++11 } }
|
||||
|
||||
class C
|
||||
{
|
||||
void f();
|
||||
int j = 10;
|
||||
int i = [this]() { return this->j; }();
|
||||
};
|
Loading…
Reference in New Issue
Block a user