summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0233-PR-c-48446.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0233-PR-c-48446.patch')
-rw-r--r--meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0233-PR-c-48446.patch183
1 files changed, 183 insertions, 0 deletions
diff --git a/meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0233-PR-c-48446.patch b/meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0233-PR-c-48446.patch
new file mode 100644
index 0000000000..c27ea1c398
--- /dev/null
+++ b/meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0233-PR-c-48446.patch
@@ -0,0 +1,183 @@
1From dfb9470529df202844f4b5dfe757ff07fa9bd27f Mon Sep 17 00:00:00 2001
2From: jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
3Date: Fri, 6 May 2011 21:58:30 +0000
4Subject: [PATCH] PR c++/48446
5 * decl.c (stabilize_save_expr_r, stabilize_vla_size): New.
6 (grokdeclarator): Use stabilize_vla_size.
7 * init.c (get_temp_regvar): No longer static.
8 * cp-tree.h: Declare it.
9
10git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_6-branch@173514 138bc75d-0d04-0410-961f-82ee72b054a4
11
12index 9fbca57..be61dad 100644
13--- a/gcc/cp/cp-tree.h
14+++ b/gcc/cp/cp-tree.h
15@@ -4958,6 +4958,7 @@ extern tree build_offset_ref (tree, tree, bool);
16 extern tree build_new (VEC(tree,gc) **, tree, tree,
17 VEC(tree,gc) **, int,
18 tsubst_flags_t);
19+extern tree get_temp_regvar (tree, tree);
20 extern tree build_vec_init (tree, tree, tree, bool, int,
21 tsubst_flags_t);
22 extern tree build_delete (tree, tree,
23diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
24index 6f8bb9f..74bae0b 100644
25--- a/gcc/cp/decl.c
26+++ b/gcc/cp/decl.c
27@@ -7499,6 +7499,39 @@ check_static_variable_definition (tree decl, tree type)
28 return 0;
29 }
30
31+/* *expr_p is part of the TYPE_SIZE of a variably-sized array. If any
32+ SAVE_EXPRs in *expr_p wrap expressions with side-effects, break those
33+ expressions out into temporary variables so that walk_tree doesn't
34+ step into them (c++/15764). */
35+
36+static tree
37+stabilize_save_expr_r (tree *expr_p, int *walk_subtrees, void *data)
38+{
39+ struct pointer_set_t *pset = (struct pointer_set_t *)data;
40+ tree expr = *expr_p;
41+ if (TREE_CODE (expr) == SAVE_EXPR)
42+ {
43+ tree op = TREE_OPERAND (expr, 0);
44+ cp_walk_tree (&op, stabilize_save_expr_r, data, pset);
45+ if (TREE_SIDE_EFFECTS (op))
46+ TREE_OPERAND (expr, 0) = get_temp_regvar (TREE_TYPE (op), op);
47+ *walk_subtrees = 0;
48+ }
49+ else if (!EXPR_P (expr) || !TREE_SIDE_EFFECTS (expr))
50+ *walk_subtrees = 0;
51+ return NULL;
52+}
53+
54+/* Entry point for the above. */
55+
56+static void
57+stabilize_vla_size (tree size)
58+{
59+ struct pointer_set_t *pset = pointer_set_create ();
60+ /* Break out any function calls into temporary variables. */
61+ cp_walk_tree (&size, stabilize_save_expr_r, pset, pset);
62+}
63+
64 /* Given the SIZE (i.e., number of elements) in an array, compute an
65 appropriate index type for the array. If non-NULL, NAME is the
66 name of the thing being declared. */
67@@ -8951,7 +8984,12 @@ grokdeclarator (const cp_declarator *declarator,
68 && (decl_context == NORMAL || decl_context == FIELD)
69 && at_function_scope_p ()
70 && variably_modified_type_p (type, NULL_TREE))
71- finish_expr_stmt (TYPE_SIZE (type));
72+ {
73+ /* First break out any side-effects. */
74+ stabilize_vla_size (TYPE_SIZE (type));
75+ /* And then force evaluation of the SAVE_EXPR. */
76+ finish_expr_stmt (TYPE_SIZE (type));
77+ }
78
79 if (declarator->kind == cdk_reference)
80 {
81@@ -9026,6 +9064,14 @@ grokdeclarator (const cp_declarator *declarator,
82 }
83 }
84
85+ /* We need to stabilize side-effects in VLA sizes for regular array
86+ declarations too, not just pointers to arrays. */
87+ if (type != error_mark_node && !TYPE_NAME (type)
88+ && (decl_context == NORMAL || decl_context == FIELD)
89+ && at_function_scope_p ()
90+ && variably_modified_type_p (type, NULL_TREE))
91+ stabilize_vla_size (TYPE_SIZE (type));
92+
93 /* A `constexpr' specifier used in an object declaration declares
94 the object as `const'. */
95 if (constexpr_p && innermost_code != cdk_function)
96diff --git a/gcc/cp/init.c b/gcc/cp/init.c
97index 4798257..ff94b71 100644
98--- a/gcc/cp/init.c
99+++ b/gcc/cp/init.c
100@@ -45,7 +45,6 @@ static void expand_virtual_init (tree, tree);
101 static tree sort_mem_initializers (tree, tree);
102 static tree initializing_context (tree);
103 static void expand_cleanup_for_base (tree, tree);
104-static tree get_temp_regvar (tree, tree);
105 static tree dfs_initialize_vtbl_ptrs (tree, void *);
106 static tree build_dtor_call (tree, special_function_kind, int);
107 static tree build_field_list (tree, tree, int *);
108@@ -2871,7 +2870,7 @@ create_temporary_var (tree type)
109 things when it comes time to do final cleanups (which take place
110 "outside" the binding contour of the function). */
111
112-static tree
113+tree
114 get_temp_regvar (tree type, tree init)
115 {
116 tree decl;
117new file mode 100644
118index 0000000..401c4e0
119--- /dev/null
120+++ b/gcc/testsuite/c-c++-common/vla-1.c
121@@ -0,0 +1,21 @@
122+/* Test that changes to a variable are reflected in a VLA later in the
123+ expression. */
124+/* { dg-options "" } */
125+
126+#ifdef __cplusplus
127+extern "C"
128+#endif
129+void abort();
130+
131+int i = 4;
132+int f()
133+{
134+ return i;
135+}
136+
137+int main()
138+{
139+ if (i+=2, sizeof(*(int(*)[f()])0) != 6*sizeof(int))
140+ abort();
141+ return 0;
142+}
143diff --git a/gcc/testsuite/g++.dg/ext/vla10.C b/gcc/testsuite/g++.dg/ext/vla10.C
144new file mode 100644
145index 0000000..17cdb2f
146--- /dev/null
147+++ b/gcc/testsuite/g++.dg/ext/vla10.C
148@@ -0,0 +1,32 @@
149+// PR c++/48446
150+// { dg-options "" }
151+
152+template<typename T>
153+struct A
154+{
155+ ~A ();
156+ T *operator-> () const;
157+};
158+
159+struct B
160+{
161+ typedef A <B> P;
162+ static P foo (int);
163+};
164+
165+struct C
166+{
167+ typedef A<C> P;
168+ static const int c = 80;
169+};
170+
171+C::P bar ();
172+
173+void
174+baz ()
175+{
176+ char z[bar ()->c];
177+ {
178+ B::P m = B::foo (sizeof (z));
179+ }
180+}
181--
1821.7.0.4
183