Handle deferred parsing of NSDMIs.
* parser.h (cp_unparsed_functions_entry): Add nsdmis field. * parser.c (unparsed_nsdmis, cp_parser_save_nsdmi): New. (cp_parser_late_parse_one_default_arg): Split out from cp_parser_late_parsing_default_args. (cp_parser_late_parsing_nsdmi): New. (push_unparsed_function_queues): Set it. (cp_parser_parameter_declaration): Save the '=' token. (cp_parser_template_parameter): Likewise. (cp_parser_default_argument): Call cp_parser_initializer rather than cp_parser_initializer_clause. (cp_parser_class_specifier_1): Parse unparsed_nsdmis. (cp_parser_member_declaration): Handle nsdmis. * decl2.c (grokfield): Handle DEFAULT_ARG for a function. From-SVN: r179156
This commit is contained in:
parent
0e5f8a598d
commit
eb02633818
@ -1,5 +1,20 @@
|
||||
2011-09-24 Jason Merrill <jason@redhat.com>
|
||||
|
||||
Handle deferred parsing of NSDMIs.
|
||||
* parser.h (cp_unparsed_functions_entry): Add nsdmis field.
|
||||
* parser.c (unparsed_nsdmis, cp_parser_save_nsdmi): New.
|
||||
(cp_parser_late_parse_one_default_arg): Split out from
|
||||
cp_parser_late_parsing_default_args.
|
||||
(cp_parser_late_parsing_nsdmi): New.
|
||||
(push_unparsed_function_queues): Set it.
|
||||
(cp_parser_parameter_declaration): Save the '=' token.
|
||||
(cp_parser_template_parameter): Likewise.
|
||||
(cp_parser_default_argument): Call cp_parser_initializer
|
||||
rather than cp_parser_initializer_clause.
|
||||
(cp_parser_class_specifier_1): Parse unparsed_nsdmis.
|
||||
(cp_parser_member_declaration): Handle nsdmis.
|
||||
* decl2.c (grokfield): Handle DEFAULT_ARG for a function.
|
||||
|
||||
Implement C++11 non-static data member initializers.
|
||||
* cp-tree.h (enum cpp_warn_str): Add CPP0X_NSDMI.
|
||||
* error.c (maybe_warn_cpp0x): Handle it.
|
||||
|
@ -6077,7 +6077,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
|
||||
|
||||
/* Just store non-static data member initializers for later. */
|
||||
if (init && TREE_CODE (decl) == FIELD_DECL)
|
||||
DECL_INITIAL (decl) = digest_init_flags (TREE_TYPE (decl), init, flags);
|
||||
DECL_INITIAL (decl) = init;
|
||||
|
||||
/* Take care of TYPE_DECLs up front. */
|
||||
if (TREE_CODE (decl) == TYPE_DECL)
|
||||
|
@ -902,6 +902,8 @@ grokfield (const cp_declarator *declarator,
|
||||
DECL_DECLARED_INLINE_P (value) = 1;
|
||||
}
|
||||
}
|
||||
else if (TREE_CODE (init) == DEFAULT_ARG)
|
||||
error ("invalid initializer for member function %qD", value);
|
||||
else if (TREE_CODE (TREE_TYPE (value)) == METHOD_TYPE)
|
||||
{
|
||||
if (integer_zerop (init))
|
||||
|
196
gcc/cp/parser.c
196
gcc/cp/parser.c
@ -1486,6 +1486,8 @@ cp_parser_context_new (cp_parser_context* next)
|
||||
VEC_last (cp_unparsed_functions_entry, parser->unparsed_queues)->funs_with_default_args
|
||||
#define unparsed_funs_with_definitions \
|
||||
VEC_last (cp_unparsed_functions_entry, parser->unparsed_queues)->funs_with_definitions
|
||||
#define unparsed_nsdmis \
|
||||
VEC_last (cp_unparsed_functions_entry, parser->unparsed_queues)->nsdmis
|
||||
|
||||
static void
|
||||
push_unparsed_function_queues (cp_parser *parser)
|
||||
@ -1494,6 +1496,7 @@ push_unparsed_function_queues (cp_parser *parser)
|
||||
parser->unparsed_queues, NULL);
|
||||
unparsed_funs_with_default_args = NULL;
|
||||
unparsed_funs_with_definitions = make_tree_vector ();
|
||||
unparsed_nsdmis = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1936,12 +1939,18 @@ static tree cp_parser_functional_cast
|
||||
(cp_parser *, tree);
|
||||
static tree cp_parser_save_member_function_body
|
||||
(cp_parser *, cp_decl_specifier_seq *, cp_declarator *, tree);
|
||||
static tree cp_parser_save_nsdmi
|
||||
(cp_parser *);
|
||||
static tree cp_parser_enclosed_template_argument_list
|
||||
(cp_parser *);
|
||||
static void cp_parser_save_default_args
|
||||
(cp_parser *, tree);
|
||||
static void cp_parser_late_parsing_for_member
|
||||
(cp_parser *, tree);
|
||||
static tree cp_parser_late_parse_one_default_arg
|
||||
(cp_parser *, tree, tree, tree);
|
||||
static void cp_parser_late_parsing_nsdmi
|
||||
(cp_parser *, tree);
|
||||
static void cp_parser_late_parsing_default_args
|
||||
(cp_parser *, tree);
|
||||
static tree cp_parser_sizeof_operand
|
||||
@ -11343,9 +11352,7 @@ cp_parser_template_parameter (cp_parser* parser, bool *is_non_type,
|
||||
user may try to do so, so we'll parse them and give an
|
||||
appropriate diagnostic here. */
|
||||
|
||||
/* Consume the `='. */
|
||||
cp_token *start_token = cp_lexer_peek_token (parser->lexer);
|
||||
cp_lexer_consume_token (parser->lexer);
|
||||
|
||||
/* Find the name of the parameter pack. */
|
||||
id_declarator = parameter_declarator->declarator;
|
||||
@ -16323,9 +16330,6 @@ cp_parser_parameter_declaration (cp_parser *parser,
|
||||
/* If the next token is `=', then process a default argument. */
|
||||
if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))
|
||||
{
|
||||
/* Consume the `='. */
|
||||
cp_lexer_consume_token (parser->lexer);
|
||||
|
||||
/* If we are defining a class, then the tokens that make up the
|
||||
default argument must be saved and processed later. */
|
||||
if (!template_parm_p && at_class_scope_p ()
|
||||
@ -16535,7 +16539,7 @@ cp_parser_default_argument (cp_parser *parser, bool template_parm_p)
|
||||
tree default_argument = NULL_TREE;
|
||||
bool saved_greater_than_is_operator_p;
|
||||
bool saved_local_variables_forbidden_p;
|
||||
bool non_constant_p;
|
||||
bool non_constant_p, is_direct_init;
|
||||
|
||||
/* Make sure that PARSER->GREATER_THAN_IS_OPERATOR_P is
|
||||
set correctly. */
|
||||
@ -16549,7 +16553,7 @@ cp_parser_default_argument (cp_parser *parser, bool template_parm_p)
|
||||
if (template_parm_p)
|
||||
push_deferring_access_checks (dk_no_deferred);
|
||||
default_argument
|
||||
= cp_parser_initializer_clause (parser, &non_constant_p);
|
||||
= cp_parser_initializer (parser, &is_direct_init, &non_constant_p);
|
||||
if (BRACE_ENCLOSED_INITIALIZER_P (default_argument))
|
||||
maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
|
||||
if (template_parm_p)
|
||||
@ -17265,7 +17269,7 @@ cp_parser_class_specifier_1 (cp_parser* parser)
|
||||
there is no need to delay the parsing of `A::B::f'. */
|
||||
if (--parser->num_classes_being_defined == 0)
|
||||
{
|
||||
tree fn;
|
||||
tree decl;
|
||||
tree class_type = NULL_TREE;
|
||||
tree pushed_scope = NULL_TREE;
|
||||
unsigned ix;
|
||||
@ -17284,7 +17288,7 @@ cp_parser_class_specifier_1 (cp_parser* parser)
|
||||
FOR_EACH_VEC_ELT (cp_default_arg_entry, unparsed_funs_with_default_args,
|
||||
ix, e)
|
||||
{
|
||||
fn = e->decl;
|
||||
decl = e->decl;
|
||||
/* If there are default arguments that have not yet been processed,
|
||||
take care of them now. */
|
||||
if (class_type != e->class_type)
|
||||
@ -17295,18 +17299,31 @@ cp_parser_class_specifier_1 (cp_parser* parser)
|
||||
pushed_scope = push_scope (class_type);
|
||||
}
|
||||
/* Make sure that any template parameters are in scope. */
|
||||
maybe_begin_member_template_processing (fn);
|
||||
maybe_begin_member_template_processing (decl);
|
||||
/* Parse the default argument expressions. */
|
||||
cp_parser_late_parsing_default_args (parser, fn);
|
||||
cp_parser_late_parsing_default_args (parser, decl);
|
||||
/* Remove any template parameters from the symbol table. */
|
||||
maybe_end_member_template_processing ();
|
||||
}
|
||||
VEC_truncate (cp_default_arg_entry, unparsed_funs_with_default_args, 0);
|
||||
/* Now parse any NSDMIs. */
|
||||
FOR_EACH_VEC_ELT (tree, unparsed_nsdmis, ix, decl)
|
||||
{
|
||||
if (class_type != DECL_CONTEXT (decl))
|
||||
{
|
||||
if (pushed_scope)
|
||||
pop_scope (pushed_scope);
|
||||
class_type = DECL_CONTEXT (decl);
|
||||
pushed_scope = push_scope (class_type);
|
||||
}
|
||||
cp_parser_late_parsing_nsdmi (parser, decl);
|
||||
}
|
||||
VEC_truncate (tree, unparsed_nsdmis, 0);
|
||||
if (pushed_scope)
|
||||
pop_scope (pushed_scope);
|
||||
VEC_truncate (cp_default_arg_entry, unparsed_funs_with_default_args, 0);
|
||||
/* Now parse the body of the functions. */
|
||||
FOR_EACH_VEC_ELT (tree, unparsed_funs_with_definitions, ix, fn)
|
||||
cp_parser_late_parsing_for_member (parser, fn);
|
||||
FOR_EACH_VEC_ELT (tree, unparsed_funs_with_definitions, ix, decl)
|
||||
cp_parser_late_parsing_for_member (parser, decl);
|
||||
VEC_truncate (tree, unparsed_funs_with_definitions, 0);
|
||||
}
|
||||
|
||||
@ -18185,8 +18202,14 @@ cp_parser_member_declaration (cp_parser* parser)
|
||||
constant-initializer. When we call `grokfield', it will
|
||||
perform more stringent semantics checks. */
|
||||
initializer_token_start = cp_lexer_peek_token (parser->lexer);
|
||||
if (function_declarator_p (declarator))
|
||||
if (function_declarator_p (declarator)
|
||||
|| (decl_specifiers.type
|
||||
&& TREE_CODE (decl_specifiers.type) == TYPE_DECL
|
||||
&& (TREE_CODE (TREE_TYPE (decl_specifiers.type))
|
||||
== FUNCTION_TYPE)))
|
||||
initializer = cp_parser_pure_specifier (parser);
|
||||
else if (decl_specifiers.storage_class != sc_static)
|
||||
initializer = cp_parser_save_nsdmi (parser);
|
||||
else if (cxx_dialect >= cxx0x)
|
||||
{
|
||||
bool nonconst;
|
||||
@ -18206,7 +18229,10 @@ cp_parser_member_declaration (cp_parser* parser)
|
||||
&& !function_declarator_p (declarator))
|
||||
{
|
||||
bool x;
|
||||
initializer = cp_parser_initializer (parser, &x, &x);
|
||||
if (decl_specifiers.storage_class != sc_static)
|
||||
initializer = cp_parser_save_nsdmi (parser);
|
||||
else
|
||||
initializer = cp_parser_initializer (parser, &x, &x);
|
||||
}
|
||||
/* Otherwise, there is no initializer. */
|
||||
else
|
||||
@ -18292,6 +18318,11 @@ cp_parser_member_declaration (cp_parser* parser)
|
||||
|
||||
if (TREE_CODE (decl) == FUNCTION_DECL)
|
||||
cp_parser_save_default_args (parser, decl);
|
||||
else if (TREE_CODE (decl) == FIELD_DECL
|
||||
&& !DECL_C_BIT_FIELD (decl)
|
||||
&& DECL_INITIAL (decl))
|
||||
/* Add DECL to the queue of NSDMI to be parsed later. */
|
||||
VEC_safe_push (tree, gc, unparsed_nsdmis, decl);
|
||||
}
|
||||
|
||||
if (assume_semicolon)
|
||||
@ -20539,6 +20570,30 @@ cp_parser_save_member_function_body (cp_parser* parser,
|
||||
return fn;
|
||||
}
|
||||
|
||||
/* Save the tokens that make up the in-class initializer for a non-static
|
||||
data member. Returns a DEFAULT_ARG. */
|
||||
|
||||
static tree
|
||||
cp_parser_save_nsdmi (cp_parser* parser)
|
||||
{
|
||||
/* Save away the tokens that make up the body of the
|
||||
function. */
|
||||
cp_token *first = parser->lexer->next_token;
|
||||
cp_token *last;
|
||||
tree node;
|
||||
|
||||
cp_parser_cache_group (parser, CPP_CLOSE_PAREN, /*depth=*/0);
|
||||
|
||||
last = parser->lexer->next_token;
|
||||
|
||||
node = make_node (DEFAULT_ARG);
|
||||
DEFARG_TOKENS (node) = cp_token_cache_new (first, last);
|
||||
DEFARG_INSTANTIATIONS (node) = NULL;
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
/* Parse a template-argument-list, as well as the trailing ">" (but
|
||||
not the opening ">"). See cp_parser_template_argument_list for the
|
||||
return value. */
|
||||
@ -20744,6 +20799,83 @@ cp_parser_save_default_args (cp_parser* parser, tree decl)
|
||||
}
|
||||
}
|
||||
|
||||
/* DEFAULT_ARG contains the saved tokens for the initializer of DECL,
|
||||
which is either a FIELD_DECL or PARM_DECL. Parse it and return
|
||||
the result. For a PARM_DECL, PARMTYPE is the corresponding type
|
||||
from the parameter-type-list. */
|
||||
|
||||
static tree
|
||||
cp_parser_late_parse_one_default_arg (cp_parser *parser, tree decl,
|
||||
tree default_arg, tree parmtype)
|
||||
{
|
||||
cp_token_cache *tokens;
|
||||
tree parsed_arg;
|
||||
bool dummy;
|
||||
|
||||
/* Push the saved tokens for the default argument onto the parser's
|
||||
lexer stack. */
|
||||
tokens = DEFARG_TOKENS (default_arg);
|
||||
cp_parser_push_lexer_for_tokens (parser, tokens);
|
||||
|
||||
start_lambda_scope (decl);
|
||||
|
||||
/* Parse the default argument. */
|
||||
parsed_arg = cp_parser_initializer (parser, &dummy, &dummy);
|
||||
if (BRACE_ENCLOSED_INITIALIZER_P (parsed_arg))
|
||||
maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
|
||||
|
||||
finish_lambda_scope ();
|
||||
|
||||
if (!processing_template_decl)
|
||||
{
|
||||
/* In a non-template class, check conversions now. In a template,
|
||||
we'll wait and instantiate these as needed. */
|
||||
if (TREE_CODE (decl) == PARM_DECL)
|
||||
parsed_arg = check_default_argument (parmtype, parsed_arg);
|
||||
else
|
||||
{
|
||||
int flags = LOOKUP_IMPLICIT;
|
||||
if (BRACE_ENCLOSED_INITIALIZER_P (parsed_arg)
|
||||
&& CONSTRUCTOR_IS_DIRECT_INIT (parsed_arg))
|
||||
flags = LOOKUP_NORMAL;
|
||||
parsed_arg = digest_init_flags (TREE_TYPE (decl), parsed_arg, flags);
|
||||
}
|
||||
}
|
||||
|
||||
/* If the token stream has not been completely used up, then
|
||||
there was extra junk after the end of the default
|
||||
argument. */
|
||||
if (!cp_lexer_next_token_is (parser->lexer, CPP_EOF))
|
||||
{
|
||||
if (TREE_CODE (decl) == PARM_DECL)
|
||||
cp_parser_error (parser, "expected %<,%>");
|
||||
else
|
||||
cp_parser_error (parser, "expected %<;%>");
|
||||
}
|
||||
|
||||
/* Revert to the main lexer. */
|
||||
cp_parser_pop_lexer (parser);
|
||||
|
||||
return parsed_arg;
|
||||
}
|
||||
|
||||
/* FIELD is a non-static data member with an initializer which we saved for
|
||||
later; parse it now. */
|
||||
|
||||
static void
|
||||
cp_parser_late_parsing_nsdmi (cp_parser *parser, tree field)
|
||||
{
|
||||
tree def;
|
||||
|
||||
push_unparsed_function_queues (parser);
|
||||
def = cp_parser_late_parse_one_default_arg (parser, field,
|
||||
DECL_INITIAL (field),
|
||||
NULL_TREE);
|
||||
pop_unparsed_function_queues (parser);
|
||||
|
||||
DECL_INITIAL (field) = def;
|
||||
}
|
||||
|
||||
/* FN is a FUNCTION_DECL which may contains a parameter with an
|
||||
unparsed DEFAULT_ARG. Parse the default args now. This function
|
||||
assumes that the current scope is the scope in which the default
|
||||
@ -20753,7 +20885,6 @@ static void
|
||||
cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
|
||||
{
|
||||
bool saved_local_variables_forbidden_p;
|
||||
bool non_constant_p;
|
||||
tree parm, parmdecl;
|
||||
|
||||
/* While we're parsing the default args, we might (due to the
|
||||
@ -20775,7 +20906,6 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
|
||||
parm = TREE_CHAIN (parm),
|
||||
parmdecl = DECL_CHAIN (parmdecl))
|
||||
{
|
||||
cp_token_cache *tokens;
|
||||
tree default_arg = TREE_PURPOSE (parm);
|
||||
tree parsed_arg;
|
||||
VEC(tree,gc) *insts;
|
||||
@ -20790,25 +20920,14 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
|
||||
already declared with default arguments. */
|
||||
continue;
|
||||
|
||||
/* Push the saved tokens for the default argument onto the parser's
|
||||
lexer stack. */
|
||||
tokens = DEFARG_TOKENS (default_arg);
|
||||
cp_parser_push_lexer_for_tokens (parser, tokens);
|
||||
|
||||
start_lambda_scope (parmdecl);
|
||||
|
||||
/* Parse the assignment-expression. */
|
||||
parsed_arg = cp_parser_initializer_clause (parser, &non_constant_p);
|
||||
parsed_arg
|
||||
= cp_parser_late_parse_one_default_arg (parser, parmdecl,
|
||||
default_arg,
|
||||
TREE_VALUE (parm));
|
||||
if (parsed_arg == error_mark_node)
|
||||
{
|
||||
cp_parser_pop_lexer (parser);
|
||||
continue;
|
||||
}
|
||||
if (BRACE_ENCLOSED_INITIALIZER_P (parsed_arg))
|
||||
maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
|
||||
|
||||
if (!processing_template_decl)
|
||||
parsed_arg = check_default_argument (TREE_VALUE (parm), parsed_arg);
|
||||
|
||||
TREE_PURPOSE (parm) = parsed_arg;
|
||||
|
||||
@ -20816,17 +20935,6 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
|
||||
for (insts = DEFARG_INSTANTIATIONS (default_arg), ix = 0;
|
||||
VEC_iterate (tree, insts, ix, copy); ix++)
|
||||
TREE_PURPOSE (copy) = parsed_arg;
|
||||
|
||||
finish_lambda_scope ();
|
||||
|
||||
/* If the token stream has not been completely used up, then
|
||||
there was extra junk after the end of the default
|
||||
argument. */
|
||||
if (!cp_lexer_next_token_is (parser->lexer, CPP_EOF))
|
||||
cp_parser_error (parser, "expected %<,%>");
|
||||
|
||||
/* Revert to the main lexer. */
|
||||
cp_parser_pop_lexer (parser);
|
||||
}
|
||||
|
||||
pop_defarg_context ();
|
||||
|
@ -169,6 +169,10 @@ typedef struct GTY(()) cp_unparsed_functions_entry_d {
|
||||
/* Functions with defintions that require post-processing. Functions
|
||||
appear in this list in declaration order. */
|
||||
VEC(tree,gc) *funs_with_definitions;
|
||||
|
||||
/* Non-static data members with initializers that require post-processing.
|
||||
FIELD_DECLs appear in this list in declaration order. */
|
||||
VEC(tree,gc) *nsdmis;
|
||||
} cp_unparsed_functions_entry;
|
||||
|
||||
DEF_VEC_O(cp_unparsed_functions_entry);
|
||||
|
@ -1,5 +1,8 @@
|
||||
2011-09-24 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* g++.dg/cpp0x/nsdmi-defer1.C: New.
|
||||
* g++.dg/cpp0x/nsdmi-defer2.C: New.
|
||||
|
||||
* g++.dg/cpp0x/nsdmi1.C: New.
|
||||
* g++.dg/cpp0x/nsdmi2.C: New.
|
||||
* g++.dg/cpp0x/nsdmi3.C: New.
|
||||
|
14
gcc/testsuite/g++.dg/cpp0x/nsdmi-defer1.C
Normal file
14
gcc/testsuite/g++.dg/cpp0x/nsdmi-defer1.C
Normal file
@ -0,0 +1,14 @@
|
||||
// { dg-options -std=c++0x }
|
||||
|
||||
#define SA(X) static_assert(X,#X)
|
||||
|
||||
struct A
|
||||
{
|
||||
int i = f();
|
||||
int j { f() };
|
||||
static constexpr int f() { return 42; }
|
||||
};
|
||||
|
||||
constexpr A a;
|
||||
SA(a.i == 42);
|
||||
SA(a.j == 42);
|
9
gcc/testsuite/g++.dg/cpp0x/nsdmi-defer2.C
Normal file
9
gcc/testsuite/g++.dg/cpp0x/nsdmi-defer2.C
Normal file
@ -0,0 +1,9 @@
|
||||
// { dg-options -std=c++0x }
|
||||
|
||||
struct A
|
||||
{
|
||||
int i = f();
|
||||
static int f(int i = 42) { return i; }
|
||||
};
|
||||
|
||||
A a;
|
@ -3,17 +3,17 @@
|
||||
|
||||
struct A
|
||||
{
|
||||
A(void* i=); // { dg-error "with|specification" }
|
||||
A(void* i=); // { dg-error "overloaded" }
|
||||
A(void* i=); // { dg-error "overloaded" }
|
||||
A(void* i=); // { dg-error "with|specification|primary-expression" }
|
||||
A(void* i=); // { dg-error "overloaded|primary-expression" }
|
||||
A(void* i=); // { dg-error "overloaded|primary-expression" }
|
||||
|
||||
void operator+ (void* i=); // { dg-error "arguments" }
|
||||
|
||||
virtual void foo1(=); // { dg-error "identifier" }
|
||||
void foo2(=); // { dg-error "identifier" }
|
||||
void foo3(=); // { dg-error "identifier" }
|
||||
void foo4(=); // { dg-error "identifier" }
|
||||
void foo5(=); // { dg-error "identifier" }
|
||||
}; // { dg-error "primary-expression" }
|
||||
virtual void foo1(=); // { dg-error "identifier|primary-expression" }
|
||||
void foo2(=); // { dg-error "identifier|primary-expression" }
|
||||
void foo3(=); // { dg-error "identifier|primary-expression" }
|
||||
void foo4(=); // { dg-error "identifier|primary-expression" }
|
||||
void foo5(=); // { dg-error "identifier|primary-expression" }
|
||||
};
|
||||
|
||||
A::A (void* i=) {} // { dg-error "primary-expression|argument" }
|
||||
|
@ -5,13 +5,13 @@
|
||||
struct A
|
||||
{
|
||||
typedef void (F)();
|
||||
F f = []{}; /* { dg-error "invalid initializer" } */
|
||||
F f = []{}; /* { dg-error "invalid pure" } */
|
||||
};
|
||||
|
||||
struct B
|
||||
{
|
||||
typedef void (F)();
|
||||
F f = 1; /* { dg-error "invalid initializer" } */
|
||||
virtual F f2 = 2; /* { dg-error "invalid initializer" } */
|
||||
F f3 = 3; /* { dg-error "invalid initializer" } */
|
||||
F f = 1; /* { dg-error "invalid pure" } */
|
||||
virtual F f2 = 2; /* { dg-error "invalid pure" } */
|
||||
F f3 = 3; /* { dg-error "invalid pure" } */
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user