aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2014-02-24 17:17:43 -0500
committerJason Merrill <jason@gcc.gnu.org>2014-02-24 17:17:43 -0500
commit2105f1a796d2fa126313b6568b573af6e330ce80 (patch)
tree27f413ac47c693fc1d6fd0c7415c9ec933552c2c /gcc
parent016895178d73bf9e4b0dea6ed253adea4f9af4f9 (diff)
downloadgcc-2105f1a796d2fa126313b6568b573af6e330ce80.zip
gcc-2105f1a796d2fa126313b6568b573af6e330ce80.tar.gz
gcc-2105f1a796d2fa126313b6568b573af6e330ce80.tar.bz2
re PR c++/60146 (ICE when compiling this code with -fopenmp)
PR c++/60146 * pt.c (tsubst_omp_for_iterator): Don't let substitution of the DECL_EXPR initialize a non-class iterator. From-SVN: r208094
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog4
-rw-r--r--gcc/cp/pt.c46
-rw-r--r--gcc/testsuite/g++.dg/gomp/for-20.C16
3 files changed, 52 insertions, 14 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 5369ee6..20589c3 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,9 @@
2014-02-24 Jason Merrill <jason@redhat.com>
+ PR c++/60146
+ * pt.c (tsubst_omp_for_iterator): Don't let substitution of the
+ DECL_EXPR initialize a non-class iterator.
+
PR c++/60312
* parser.c (cp_parser_template_type_arg): Check for invalid 'auto'.
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 2dc5f32..bd59142 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -13063,31 +13063,43 @@ tsubst_omp_for_iterator (tree t, int i, tree declv, tree initv,
tsubst_expr ((NODE), args, complain, in_decl, \
integral_constant_expression_p)
tree decl, init, cond, incr;
- bool init_decl;
init = TREE_VEC_ELT (OMP_FOR_INIT (t), i);
gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
decl = TREE_OPERAND (init, 0);
init = TREE_OPERAND (init, 1);
- /* Do this before substituting into decl to handle 'auto'. */
- init_decl = (init && TREE_CODE (init) == DECL_EXPR);
- init = RECUR (init);
- decl = RECUR (decl);
-
- if (decl == error_mark_node || init == error_mark_node)
- return;
-
- if (init_decl)
+ tree decl_expr = NULL_TREE;
+ if (init && TREE_CODE (init) == DECL_EXPR)
{
- gcc_assert (!processing_template_decl);
- init = DECL_INITIAL (decl);
- DECL_INITIAL (decl) = NULL_TREE;
+ /* We need to jump through some hoops to handle declarations in the
+ for-init-statement, since we might need to handle auto deduction,
+ but we need to keep control of initialization. */
+ decl_expr = init;
+ init = DECL_INITIAL (DECL_EXPR_DECL (init));
+ decl = tsubst_decl (decl, args, complain);
}
+ else
+ decl = RECUR (decl);
+ init = RECUR (init);
+
+ tree auto_node = type_uses_auto (TREE_TYPE (decl));
+ if (auto_node && init)
+ TREE_TYPE (decl)
+ = do_auto_deduction (TREE_TYPE (decl), init, auto_node);
gcc_assert (!type_dependent_expression_p (decl));
if (!CLASS_TYPE_P (TREE_TYPE (decl)))
{
+ if (decl_expr)
+ {
+ /* Declare the variable, but don't let that initialize it. */
+ tree init_sav = DECL_INITIAL (DECL_EXPR_DECL (decl_expr));
+ DECL_INITIAL (DECL_EXPR_DECL (decl_expr)) = NULL_TREE;
+ RECUR (decl_expr);
+ DECL_INITIAL (DECL_EXPR_DECL (decl_expr)) = init_sav;
+ }
+
cond = RECUR (TREE_VEC_ELT (OMP_FOR_COND (t), i));
incr = TREE_VEC_ELT (OMP_FOR_INCR (t), i);
if (TREE_CODE (incr) == MODIFY_EXPR)
@@ -13104,7 +13116,13 @@ tsubst_omp_for_iterator (tree t, int i, tree declv, tree initv,
return;
}
- if (init && !init_decl)
+ if (decl_expr)
+ {
+ /* Declare and initialize the variable. */
+ RECUR (decl_expr);
+ init = NULL_TREE;
+ }
+ else if (init)
{
tree c;
for (c = *clauses; c ; c = OMP_CLAUSE_CHAIN (c))
diff --git a/gcc/testsuite/g++.dg/gomp/for-20.C b/gcc/testsuite/g++.dg/gomp/for-20.C
new file mode 100644
index 0000000..7b57b16
--- /dev/null
+++ b/gcc/testsuite/g++.dg/gomp/for-20.C
@@ -0,0 +1,16 @@
+// PR c++/60146
+// { dg-do compile }
+// { dg-options -fopenmp }
+
+int foo() { return 0; }
+
+template<typename T> void bar()
+{
+#pragma omp parallel for
+ for (T i = foo(); i < 8; ++i) {}
+}
+
+void baz()
+{
+ bar<int>();
+}