aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2013-03-16 22:34:45 -0400
committerJason Merrill <jason@gcc.gnu.org>2013-03-16 22:34:45 -0400
commitcdf47df08aba23c5b40fa3e4b8d7f4c9cc2c882e (patch)
tree45d7915d636df24049f21e82bf64dd29fe73cfb4 /gcc
parenta1e03bc5bc4983bb0cda698575b45a2be16765a4 (diff)
downloadgcc-cdf47df08aba23c5b40fa3e4b8d7f4c9cc2c882e.zip
gcc-cdf47df08aba23c5b40fa3e4b8d7f4c9cc2c882e.tar.gz
gcc-cdf47df08aba23c5b40fa3e4b8d7f4c9cc2c882e.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/parser.c13
-rw-r--r--gcc/cp/semantics.c9
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/nsdmi-local.C8
5 files changed, 34 insertions, 3 deletions
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 <jason@redhat.com>
+ 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" }
+}