diff options
author | Jakub Jelinek <jakub@redhat.com> | 2010-12-14 14:56:25 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2010-12-14 14:56:25 +0100 |
commit | af3fcdb4acc278514bb50398558a79754f746609 (patch) | |
tree | 5b50de920ec355e80344945e3a433b52bd6cdc9e /gcc/fortran/trans-openmp.c | |
parent | ae9fd6b7cd6ab8d777612aa1b721a8c3112e2c5e (diff) | |
download | gcc-af3fcdb4acc278514bb50398558a79754f746609.zip gcc-af3fcdb4acc278514bb50398558a79754f746609.tar.gz gcc-af3fcdb4acc278514bb50398558a79754f746609.tar.bz2 |
re PR fortran/46874 ([OpenMP] ICE in gfc_conv_descriptor_data_get, at fortran/trans-array.c:147)
PR fortran/46874
* trans-openmp.c (gfc_trans_omp_array_reduction): Handle allocatable
dummy variables.
* libgomp.fortran/allocatable6.f90: New test.
From-SVN: r167798
Diffstat (limited to 'gcc/fortran/trans-openmp.c')
-rw-r--r-- | gcc/fortran/trans-openmp.c | 28 |
1 files changed, 20 insertions, 8 deletions
diff --git a/gcc/fortran/trans-openmp.c b/gcc/fortran/trans-openmp.c index a8c861e..53eb999 100644 --- a/gcc/fortran/trans-openmp.c +++ b/gcc/fortran/trans-openmp.c @@ -482,13 +482,23 @@ gfc_trans_omp_array_reduction (tree c, gfc_symbol *sym, locus where) gfc_symbol init_val_sym, outer_sym, intrinsic_sym; gfc_expr *e1, *e2, *e3, *e4; gfc_ref *ref; - tree decl, backend_decl, stmt; + tree decl, backend_decl, stmt, type, outer_decl; locus old_loc = gfc_current_locus; const char *iname; gfc_try t; decl = OMP_CLAUSE_DECL (c); gfc_current_locus = where; + type = TREE_TYPE (decl); + outer_decl = create_tmp_var_raw (type, NULL); + if (TREE_CODE (decl) == PARM_DECL + && TREE_CODE (type) == REFERENCE_TYPE + && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (type)) + && GFC_TYPE_ARRAY_AKIND (TREE_TYPE (type)) == GFC_ARRAY_ALLOCATABLE) + { + decl = build_fold_indirect_ref (decl); + type = TREE_TYPE (type); + } /* Create a fake symbol for init value. */ memset (&init_val_sym, 0, sizeof (init_val_sym)); @@ -507,7 +517,9 @@ gfc_trans_omp_array_reduction (tree c, gfc_symbol *sym, locus where) outer_sym.attr.dummy = 0; outer_sym.attr.result = 0; outer_sym.attr.flavor = FL_VARIABLE; - outer_sym.backend_decl = create_tmp_var_raw (TREE_TYPE (decl), NULL); + outer_sym.backend_decl = outer_decl; + if (decl != OMP_CLAUSE_DECL (c)) + outer_sym.backend_decl = build_fold_indirect_ref (outer_decl); /* Create fake symtrees for it. */ symtree1 = gfc_new_symtree (&root1, sym->name); @@ -624,12 +636,12 @@ gfc_trans_omp_array_reduction (tree c, gfc_symbol *sym, locus where) /* Create the init statement list. */ pushlevel (0); - if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)) - && GFC_TYPE_ARRAY_AKIND (TREE_TYPE (decl)) == GFC_ARRAY_ALLOCATABLE) + if (GFC_DESCRIPTOR_TYPE_P (type) + && GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ALLOCATABLE) { /* If decl is an allocatable array, it needs to be allocated with the same bounds as the outer var. */ - tree type = TREE_TYPE (decl), rank, size, esize, ptr; + tree rank, size, esize, ptr; stmtblock_t block; gfc_start_block (&block); @@ -669,8 +681,8 @@ gfc_trans_omp_array_reduction (tree c, gfc_symbol *sym, locus where) /* Create the merge statement list. */ pushlevel (0); - if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)) - && GFC_TYPE_ARRAY_AKIND (TREE_TYPE (decl)) == GFC_ARRAY_ALLOCATABLE) + if (GFC_DESCRIPTOR_TYPE_P (type) + && GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ALLOCATABLE) { /* If decl is an allocatable array, it needs to be deallocated afterwards. */ @@ -691,7 +703,7 @@ gfc_trans_omp_array_reduction (tree c, gfc_symbol *sym, locus where) OMP_CLAUSE_REDUCTION_MERGE (c) = stmt; /* And stick the placeholder VAR_DECL into the clause as well. */ - OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = outer_sym.backend_decl; + OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = outer_decl; gfc_current_locus = old_loc; |