aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/parser.c18
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/range-for7.C117
4 files changed, 139 insertions, 7 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 7343b2d..2d6a17d 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2010-10-20 Rodrigo Rivas Costa <rodrigorivascosta@gmail.com>
+
+ PR c++/46056
+ * parser.c (cp_convert_range_for): Call cp_finish_decl
+ instead of finish_expr_stmt.
+
2010-10-20 Nicola Pero <nicola.pero@meta-innovation.com>
* cp-lang.c (finish_file): Removed.
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 4773486..8c0129b 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -8773,8 +8773,10 @@ cp_convert_range_for (tree statement, tree range_decl, tree range_expr)
TREE_USED (range_temp) = 1;
DECL_ARTIFICIAL (range_temp) = 1;
pushdecl (range_temp);
- finish_expr_stmt (cp_build_modify_expr (range_temp, INIT_EXPR, range_expr,
- tf_warning_or_error));
+ cp_finish_decl (range_temp, range_expr,
+ /*is_constant_init*/false, NULL_TREE,
+ LOOKUP_ONLYCONVERTING);
+
range_temp = convert_from_reference (range_temp);
if (TREE_CODE (TREE_TYPE (range_temp)) == ARRAY_TYPE)
@@ -8824,16 +8826,18 @@ cp_convert_range_for (tree statement, tree range_decl, tree range_expr)
TREE_USED (begin) = 1;
DECL_ARTIFICIAL (begin) = 1;
pushdecl (begin);
- finish_expr_stmt (cp_build_modify_expr (begin, INIT_EXPR, begin_expr,
- tf_warning_or_error));
+ cp_finish_decl (begin, begin_expr,
+ /*is_constant_init*/false, NULL_TREE,
+ LOOKUP_ONLYCONVERTING);
+
end = build_decl (input_location, VAR_DECL,
get_identifier ("__for_end"), iter_type);
TREE_USED (end) = 1;
DECL_ARTIFICIAL (end) = 1;
pushdecl (end);
-
- finish_expr_stmt (cp_build_modify_expr (end, INIT_EXPR, end_expr,
- tf_warning_or_error));
+ cp_finish_decl (end, end_expr,
+ /*is_constant_init*/false, NULL_TREE,
+ LOOKUP_ONLYCONVERTING);
finish_for_init_stmt (statement);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 519f7a7..2811af5 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2010-10-20 Rodrigo Rivas Costa <rodrigorivascosta@gmail.com>
+
+ PR c++/46056
+ * g++.dg/cpp0x/range-for7.C: New.
+
2010-10-20 Richard Guenther <rguenther@suse.de>
PR lto/45667
diff --git a/gcc/testsuite/g++.dg/cpp0x/range-for7.C b/gcc/testsuite/g++.dg/cpp0x/range-for7.C
new file mode 100644
index 0000000..ad89dc2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/range-for7.C
@@ -0,0 +1,117 @@
+// PR c++/46056
+// Check that range-based for loop calls destructors
+// when required
+// { dg-options "-std=c++0x" }
+// { dg-do run }
+extern "C" void abort();
+
+int value_counter = 0, it_counter = 0, seq_counter = 0;
+
+struct Int
+{
+ int x;
+ Int(int v)
+ :x(v)
+ {
+ ++value_counter;
+ }
+ Int(const Int &o)
+ :x(o.x)
+ {
+ ++value_counter;
+ }
+ ~Int()
+ {
+ --value_counter;
+ }
+};
+
+struct iterator
+{
+ int x;
+ iterator(int v)
+ :x(v)
+ {
+ ++it_counter;
+ }
+ iterator(const iterator &o)
+ :x(o.x)
+ {
+ ++it_counter;
+ }
+ ~iterator()
+ {
+ --it_counter;
+ }
+ iterator &operator ++() { ++x; return *this; }
+ int operator *() { return x; }
+ bool operator != (const iterator &o) { return x != o.x; }
+};
+
+struct container
+{
+ int min, max;
+ container(int a, int b) :min(a), max(b)
+ {
+ ++seq_counter;
+ }
+ container(const container &) = delete;
+ ~container()
+ {
+ --seq_counter;
+ }
+};
+
+iterator begin(container &c)
+{
+ return iterator(c.min);
+}
+
+iterator end(container &c)
+{
+ return iterator(c.max + 1);
+}
+
+int main()
+{
+ for (Int x : container(0, 10))
+ {
+ if (value_counter != 1) abort();
+ if (it_counter != 2) abort();
+ if (seq_counter != 1) abort();
+ }
+ if (value_counter != 0) abort();
+ if (it_counter != 0) abort();
+ if (seq_counter != 0) abort();
+
+ try
+ {
+ for (Int x : container(0, 10))
+ {
+ if (value_counter != 1) abort();
+ if (it_counter != 2) abort();
+ if (seq_counter != 1) abort();
+ }
+ if (value_counter != 0) abort();
+ if (it_counter != 0) abort();
+ if (seq_counter != 0) abort();
+
+ for (Int x : container(0, 10))
+ {
+ if (value_counter != 1) abort();
+ if (it_counter != 2) abort();
+ if (seq_counter != 1) abort();
+
+ if (x.x == 5)
+ throw 0;
+ }
+ }
+ catch (int)
+ {
+ if (value_counter != 0) abort();
+ if (it_counter != 0) abort();
+ if (seq_counter != 0) abort();
+ }
+
+ return 0;
+}