Commit eb026338 by Jason Merrill Committed by Jason Merrill

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
parent 0e5f8a59
2011-09-24 Jason Merrill <jason@redhat.com> 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. Implement C++11 non-static data member initializers.
* cp-tree.h (enum cpp_warn_str): Add CPP0X_NSDMI. * cp-tree.h (enum cpp_warn_str): Add CPP0X_NSDMI.
* error.c (maybe_warn_cpp0x): Handle it. * error.c (maybe_warn_cpp0x): Handle it.
......
...@@ -6077,7 +6077,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, ...@@ -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. */ /* Just store non-static data member initializers for later. */
if (init && TREE_CODE (decl) == FIELD_DECL) 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. */ /* Take care of TYPE_DECLs up front. */
if (TREE_CODE (decl) == TYPE_DECL) if (TREE_CODE (decl) == TYPE_DECL)
......
...@@ -902,6 +902,8 @@ grokfield (const cp_declarator *declarator, ...@@ -902,6 +902,8 @@ grokfield (const cp_declarator *declarator,
DECL_DECLARED_INLINE_P (value) = 1; 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) else if (TREE_CODE (TREE_TYPE (value)) == METHOD_TYPE)
{ {
if (integer_zerop (init)) if (integer_zerop (init))
......
...@@ -1486,6 +1486,8 @@ cp_parser_context_new (cp_parser_context* next) ...@@ -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 VEC_last (cp_unparsed_functions_entry, parser->unparsed_queues)->funs_with_default_args
#define unparsed_funs_with_definitions \ #define unparsed_funs_with_definitions \
VEC_last (cp_unparsed_functions_entry, parser->unparsed_queues)->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 static void
push_unparsed_function_queues (cp_parser *parser) push_unparsed_function_queues (cp_parser *parser)
...@@ -1494,6 +1496,7 @@ push_unparsed_function_queues (cp_parser *parser) ...@@ -1494,6 +1496,7 @@ push_unparsed_function_queues (cp_parser *parser)
parser->unparsed_queues, NULL); parser->unparsed_queues, NULL);
unparsed_funs_with_default_args = NULL; unparsed_funs_with_default_args = NULL;
unparsed_funs_with_definitions = make_tree_vector (); unparsed_funs_with_definitions = make_tree_vector ();
unparsed_nsdmis = NULL;
} }
static void static void
...@@ -1936,12 +1939,18 @@ static tree cp_parser_functional_cast ...@@ -1936,12 +1939,18 @@ static tree cp_parser_functional_cast
(cp_parser *, tree); (cp_parser *, tree);
static tree cp_parser_save_member_function_body static tree cp_parser_save_member_function_body
(cp_parser *, cp_decl_specifier_seq *, cp_declarator *, tree); (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 static tree cp_parser_enclosed_template_argument_list
(cp_parser *); (cp_parser *);
static void cp_parser_save_default_args static void cp_parser_save_default_args
(cp_parser *, tree); (cp_parser *, tree);
static void cp_parser_late_parsing_for_member static void cp_parser_late_parsing_for_member
(cp_parser *, tree); (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 static void cp_parser_late_parsing_default_args
(cp_parser *, tree); (cp_parser *, tree);
static tree cp_parser_sizeof_operand static tree cp_parser_sizeof_operand
...@@ -11343,9 +11352,7 @@ cp_parser_template_parameter (cp_parser* parser, bool *is_non_type, ...@@ -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 user may try to do so, so we'll parse them and give an
appropriate diagnostic here. */ appropriate diagnostic here. */
/* Consume the `='. */
cp_token *start_token = cp_lexer_peek_token (parser->lexer); cp_token *start_token = cp_lexer_peek_token (parser->lexer);
cp_lexer_consume_token (parser->lexer);
/* Find the name of the parameter pack. */ /* Find the name of the parameter pack. */
id_declarator = parameter_declarator->declarator; id_declarator = parameter_declarator->declarator;
...@@ -16323,9 +16330,6 @@ cp_parser_parameter_declaration (cp_parser *parser, ...@@ -16323,9 +16330,6 @@ cp_parser_parameter_declaration (cp_parser *parser,
/* If the next token is `=', then process a default argument. */ /* If the next token is `=', then process a default argument. */
if (cp_lexer_next_token_is (parser->lexer, CPP_EQ)) 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 /* If we are defining a class, then the tokens that make up the
default argument must be saved and processed later. */ default argument must be saved and processed later. */
if (!template_parm_p && at_class_scope_p () if (!template_parm_p && at_class_scope_p ()
...@@ -16535,7 +16539,7 @@ cp_parser_default_argument (cp_parser *parser, bool template_parm_p) ...@@ -16535,7 +16539,7 @@ cp_parser_default_argument (cp_parser *parser, bool template_parm_p)
tree default_argument = NULL_TREE; tree default_argument = NULL_TREE;
bool saved_greater_than_is_operator_p; bool saved_greater_than_is_operator_p;
bool saved_local_variables_forbidden_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 /* Make sure that PARSER->GREATER_THAN_IS_OPERATOR_P is
set correctly. */ set correctly. */
...@@ -16549,7 +16553,7 @@ cp_parser_default_argument (cp_parser *parser, bool template_parm_p) ...@@ -16549,7 +16553,7 @@ cp_parser_default_argument (cp_parser *parser, bool template_parm_p)
if (template_parm_p) if (template_parm_p)
push_deferring_access_checks (dk_no_deferred); push_deferring_access_checks (dk_no_deferred);
default_argument 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)) if (BRACE_ENCLOSED_INITIALIZER_P (default_argument))
maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS); maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
if (template_parm_p) if (template_parm_p)
...@@ -17265,7 +17269,7 @@ cp_parser_class_specifier_1 (cp_parser* parser) ...@@ -17265,7 +17269,7 @@ cp_parser_class_specifier_1 (cp_parser* parser)
there is no need to delay the parsing of `A::B::f'. */ there is no need to delay the parsing of `A::B::f'. */
if (--parser->num_classes_being_defined == 0) if (--parser->num_classes_being_defined == 0)
{ {
tree fn; tree decl;
tree class_type = NULL_TREE; tree class_type = NULL_TREE;
tree pushed_scope = NULL_TREE; tree pushed_scope = NULL_TREE;
unsigned ix; unsigned ix;
...@@ -17284,7 +17288,7 @@ cp_parser_class_specifier_1 (cp_parser* parser) ...@@ -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, FOR_EACH_VEC_ELT (cp_default_arg_entry, unparsed_funs_with_default_args,
ix, e) ix, e)
{ {
fn = e->decl; decl = e->decl;
/* If there are default arguments that have not yet been processed, /* If there are default arguments that have not yet been processed,
take care of them now. */ take care of them now. */
if (class_type != e->class_type) if (class_type != e->class_type)
...@@ -17295,18 +17299,31 @@ cp_parser_class_specifier_1 (cp_parser* parser) ...@@ -17295,18 +17299,31 @@ cp_parser_class_specifier_1 (cp_parser* parser)
pushed_scope = push_scope (class_type); pushed_scope = push_scope (class_type);
} }
/* Make sure that any template parameters are in scope. */ /* 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. */ /* 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. */ /* Remove any template parameters from the symbol table. */
maybe_end_member_template_processing (); 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) if (pushed_scope)
pop_scope (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. */ /* Now parse the body of the functions. */
FOR_EACH_VEC_ELT (tree, unparsed_funs_with_definitions, ix, fn) FOR_EACH_VEC_ELT (tree, unparsed_funs_with_definitions, ix, decl)
cp_parser_late_parsing_for_member (parser, fn); cp_parser_late_parsing_for_member (parser, decl);
VEC_truncate (tree, unparsed_funs_with_definitions, 0); VEC_truncate (tree, unparsed_funs_with_definitions, 0);
} }
...@@ -18185,8 +18202,14 @@ cp_parser_member_declaration (cp_parser* parser) ...@@ -18185,8 +18202,14 @@ cp_parser_member_declaration (cp_parser* parser)
constant-initializer. When we call `grokfield', it will constant-initializer. When we call `grokfield', it will
perform more stringent semantics checks. */ perform more stringent semantics checks. */
initializer_token_start = cp_lexer_peek_token (parser->lexer); 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); 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) else if (cxx_dialect >= cxx0x)
{ {
bool nonconst; bool nonconst;
...@@ -18206,6 +18229,9 @@ cp_parser_member_declaration (cp_parser* parser) ...@@ -18206,6 +18229,9 @@ cp_parser_member_declaration (cp_parser* parser)
&& !function_declarator_p (declarator)) && !function_declarator_p (declarator))
{ {
bool x; bool x;
if (decl_specifiers.storage_class != sc_static)
initializer = cp_parser_save_nsdmi (parser);
else
initializer = cp_parser_initializer (parser, &x, &x); initializer = cp_parser_initializer (parser, &x, &x);
} }
/* Otherwise, there is no initializer. */ /* Otherwise, there is no initializer. */
...@@ -18292,6 +18318,11 @@ cp_parser_member_declaration (cp_parser* parser) ...@@ -18292,6 +18318,11 @@ cp_parser_member_declaration (cp_parser* parser)
if (TREE_CODE (decl) == FUNCTION_DECL) if (TREE_CODE (decl) == FUNCTION_DECL)
cp_parser_save_default_args (parser, 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) if (assume_semicolon)
...@@ -20539,6 +20570,30 @@ cp_parser_save_member_function_body (cp_parser* parser, ...@@ -20539,6 +20570,30 @@ cp_parser_save_member_function_body (cp_parser* parser,
return fn; 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 /* Parse a template-argument-list, as well as the trailing ">" (but
not the opening ">"). See cp_parser_template_argument_list for the not the opening ">"). See cp_parser_template_argument_list for the
return value. */ return value. */
...@@ -20744,6 +20799,83 @@ cp_parser_save_default_args (cp_parser* parser, tree decl) ...@@ -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 /* FN is a FUNCTION_DECL which may contains a parameter with an
unparsed DEFAULT_ARG. Parse the default args now. This function unparsed DEFAULT_ARG. Parse the default args now. This function
assumes that the current scope is the scope in which the default assumes that the current scope is the scope in which the default
...@@ -20753,7 +20885,6 @@ static void ...@@ -20753,7 +20885,6 @@ static void
cp_parser_late_parsing_default_args (cp_parser *parser, tree fn) cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
{ {
bool saved_local_variables_forbidden_p; bool saved_local_variables_forbidden_p;
bool non_constant_p;
tree parm, parmdecl; tree parm, parmdecl;
/* While we're parsing the default args, we might (due to the /* 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) ...@@ -20775,7 +20906,6 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
parm = TREE_CHAIN (parm), parm = TREE_CHAIN (parm),
parmdecl = DECL_CHAIN (parmdecl)) parmdecl = DECL_CHAIN (parmdecl))
{ {
cp_token_cache *tokens;
tree default_arg = TREE_PURPOSE (parm); tree default_arg = TREE_PURPOSE (parm);
tree parsed_arg; tree parsed_arg;
VEC(tree,gc) *insts; VEC(tree,gc) *insts;
...@@ -20790,25 +20920,14 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn) ...@@ -20790,25 +20920,14 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
already declared with default arguments. */ already declared with default arguments. */
continue; continue;
/* Push the saved tokens for the default argument onto the parser's parsed_arg
lexer stack. */ = cp_parser_late_parse_one_default_arg (parser, parmdecl,
tokens = DEFARG_TOKENS (default_arg); default_arg,
cp_parser_push_lexer_for_tokens (parser, tokens); TREE_VALUE (parm));
start_lambda_scope (parmdecl);
/* Parse the assignment-expression. */
parsed_arg = cp_parser_initializer_clause (parser, &non_constant_p);
if (parsed_arg == error_mark_node) if (parsed_arg == error_mark_node)
{ {
cp_parser_pop_lexer (parser);
continue; 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; TREE_PURPOSE (parm) = parsed_arg;
...@@ -20816,17 +20935,6 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn) ...@@ -20816,17 +20935,6 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
for (insts = DEFARG_INSTANTIATIONS (default_arg), ix = 0; for (insts = DEFARG_INSTANTIATIONS (default_arg), ix = 0;
VEC_iterate (tree, insts, ix, copy); ix++) VEC_iterate (tree, insts, ix, copy); ix++)
TREE_PURPOSE (copy) = parsed_arg; 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 (); pop_defarg_context ();
......
...@@ -169,6 +169,10 @@ typedef struct GTY(()) cp_unparsed_functions_entry_d { ...@@ -169,6 +169,10 @@ typedef struct GTY(()) cp_unparsed_functions_entry_d {
/* Functions with defintions that require post-processing. Functions /* Functions with defintions that require post-processing. Functions
appear in this list in declaration order. */ appear in this list in declaration order. */
VEC(tree,gc) *funs_with_definitions; 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; } cp_unparsed_functions_entry;
DEF_VEC_O(cp_unparsed_functions_entry); DEF_VEC_O(cp_unparsed_functions_entry);
......
2011-09-24 Jason Merrill <jason@redhat.com> 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/nsdmi1.C: New.
* g++.dg/cpp0x/nsdmi2.C: New. * g++.dg/cpp0x/nsdmi2.C: New.
* g++.dg/cpp0x/nsdmi3.C: New. * g++.dg/cpp0x/nsdmi3.C: New.
......
// { 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);
// { dg-options -std=c++0x }
struct A
{
int i = f();
static int f(int i = 42) { return i; }
};
A a;
...@@ -3,17 +3,17 @@ ...@@ -3,17 +3,17 @@
struct A struct A
{ {
A(void* i=); // { dg-error "with|specification" } A(void* i=); // { dg-error "with|specification|primary-expression" }
A(void* i=); // { dg-error "overloaded" } A(void* i=); // { dg-error "overloaded|primary-expression" }
A(void* i=); // { dg-error "overloaded" } A(void* i=); // { dg-error "overloaded|primary-expression" }
void operator+ (void* i=); // { dg-error "arguments" } void operator+ (void* i=); // { dg-error "arguments" }
virtual void foo1(=); // { dg-error "identifier" } virtual void foo1(=); // { dg-error "identifier|primary-expression" }
void foo2(=); // { dg-error "identifier" } void foo2(=); // { dg-error "identifier|primary-expression" }
void foo3(=); // { dg-error "identifier" } void foo3(=); // { dg-error "identifier|primary-expression" }
void foo4(=); // { dg-error "identifier" } void foo4(=); // { dg-error "identifier|primary-expression" }
void foo5(=); // { dg-error "identifier" } void foo5(=); // { dg-error "identifier|primary-expression" }
}; // { dg-error "primary-expression" } };
A::A (void* i=) {} // { dg-error "primary-expression|argument" } A::A (void* i=) {} // { dg-error "primary-expression|argument" }
...@@ -5,13 +5,13 @@ ...@@ -5,13 +5,13 @@
struct A struct A
{ {
typedef void (F)(); typedef void (F)();
F f = []{}; /* { dg-error "invalid initializer" } */ F f = []{}; /* { dg-error "invalid pure" } */
}; };
struct B struct B
{ {
typedef void (F)(); typedef void (F)();
F f = 1; /* { dg-error "invalid initializer" } */ F f = 1; /* { dg-error "invalid pure" } */
virtual F f2 = 2; /* { dg-error "invalid initializer" } */ virtual F f2 = 2; /* { dg-error "invalid pure" } */
F f3 = 3; /* { dg-error "invalid initializer" } */ F f3 = 3; /* { dg-error "invalid pure" } */
}; };
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment