From cdf47df08aba23c5b40fa3e4b8d7f4c9cc2c882e Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Sat, 16 Mar 2013 22:34:45 -0400 Subject: re PR c++/55240 ([c++0x] ICE on non-static data member initialization using 'auto' variable from containing function) PR c++/55240 * parser.c (parsing_nsdmi): New. * semantics.c (outer_automatic_var_p): Check it. (finish_id_expression): Likewise. * cp-tree.h: Declare it. From-SVN: r196727 --- gcc/cp/ChangeLog | 6 ++++++ gcc/cp/cp-tree.h | 1 + gcc/cp/parser.c | 13 +++++++++++++ gcc/cp/semantics.c | 9 ++++++--- gcc/testsuite/g++.dg/cpp0x/nsdmi-local.C | 8 ++++++++ 5 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/nsdmi-local.C (limited to 'gcc') diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 5b27820..04eab4a 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,11 @@ 2013-03-16 Jason Merrill + PR c++/55240 + * parser.c (parsing_nsdmi): New. + * semantics.c (outer_automatic_var_p): Check it. + (finish_id_expression): Likewise. + * cp-tree.h: Declare it. + PR c++/55241 * error.c (dump_expr) [SIZEOF_EXPR]: Print sizeof... properly. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index c3b2aec..d9496d2 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4259,6 +4259,7 @@ extern int comparing_specializations; extern int cp_unevaluated_operand; extern tree cp_convert_range_for (tree, tree, tree); +extern bool parsing_nsdmi (void); /* in pt.c */ diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 12926e3..0a3740d 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -16938,6 +16938,19 @@ inject_this_parameter (tree ctype, cp_cv_quals quals) current_class_ptr = this_parm; } +/* Return true iff our current scope is a non-static data member + initializer. */ + +bool +parsing_nsdmi (void) +{ + /* We recognize NSDMI context by the context-less 'this' pointer set up + by the function above. */ + if (current_class_ptr && DECL_CONTEXT (current_class_ptr) == NULL_TREE) + return true; + return false; +} + /* Parse a late-specified return type, if any. This is not a separate non-terminal, but part of a function declarator, which looks like diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 3c76bad..efe09bb 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -2884,7 +2884,8 @@ outer_var_p (tree decl) { return ((TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL) && DECL_FUNCTION_SCOPE_P (decl) - && DECL_CONTEXT (decl) != current_function_decl); + && (DECL_CONTEXT (decl) != current_function_decl + || parsing_nsdmi ())); } /* As above, but also checks that DECL is automatic. */ @@ -3041,12 +3042,14 @@ finish_id_expression (tree id_expression, return integral_constant_value (decl); } + if (parsing_nsdmi ()) + containing_function = NULL_TREE; /* If we are in a lambda function, we can move out until we hit 1. the context, 2. a non-lambda function, or 3. a non-default capturing lambda function. */ - while (context != containing_function - && LAMBDA_FUNCTION_P (containing_function)) + else while (context != containing_function + && LAMBDA_FUNCTION_P (containing_function)) { lambda_expr = CLASSTYPE_LAMBDA_EXPR (DECL_CONTEXT (containing_function)); diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-local.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi-local.C new file mode 100644 index 0000000..9b84c8c --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi-local.C @@ -0,0 +1,8 @@ +// PR c++/55240 +// { dg-do compile { target c++11 } } + +int main() +{ + int q = 1; // { dg-error "declared here" } + struct test { int x = q; } instance; // { dg-error "local variable" } +} -- cgit v1.1