diff options
author | Jakub Jelinek <jakub@gcc.gnu.org> | 2016-08-31 20:42:08 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2016-08-31 20:42:08 +0200 |
commit | f25f40be277fe6687e86b6395a55781211811bef (patch) | |
tree | 9c780ac0e723481df09dc6e41511db61ca68b25f /gcc/fortran/openmp.c | |
parent | 9ff6fb6ede9ac2902088514067aca53e1133cc80 (diff) | |
download | gcc-f25f40be277fe6687e86b6395a55781211811bef.zip gcc-f25f40be277fe6687e86b6395a55781211811bef.tar.gz gcc-f25f40be277fe6687e86b6395a55781211811bef.tar.bz2 |
re PR fortran/77374 (ICE in resolve_omp_atomic, at fortran/openmp.c:3949)
PR fortran/77374
* parse.c (parse_omp_oacc_atomic): Copy over cp->ext.omp_atomic
to cp->block->ext.omp_atomic.
* resolve.c (gfc_resolve_blocks): Assert block with one or two
EXEC_ASSIGNs for EXEC_*_ATOMIC.
* openmp.c (resolve_omp_atomic): Don't assert one or two
EXEC_ASSIGNs, instead return quietly for EXEC_NOPs and otherwise
error unexpected statements.
* gfortran.dg/gomp/pr77374.f08: New test.
From-SVN: r239903
Diffstat (limited to 'gcc/fortran/openmp.c')
-rw-r--r-- | gcc/fortran/openmp.c | 33 |
1 files changed, 27 insertions, 6 deletions
diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c index f50e6e8..03e7dbe 100644 --- a/gcc/fortran/openmp.c +++ b/gcc/fortran/openmp.c @@ -3946,12 +3946,33 @@ resolve_omp_atomic (gfc_code *code) = (gfc_omp_atomic_op) (atomic_code->ext.omp_atomic & GFC_OMP_ATOMIC_MASK); code = code->block->next; - gcc_assert (code->op == EXEC_ASSIGN); - gcc_assert (((aop != GFC_OMP_ATOMIC_CAPTURE) && code->next == NULL) - || ((aop == GFC_OMP_ATOMIC_CAPTURE) - && code->next != NULL - && code->next->op == EXEC_ASSIGN - && code->next->next == NULL)); + /* resolve_blocks asserts this is initially EXEC_ASSIGN. + If it changed to EXEC_NOP, assume an error has been emitted already. */ + if (code->op == EXEC_NOP) + return; + if (code->op != EXEC_ASSIGN) + { + unexpected: + gfc_error ("unexpected !$OMP ATOMIC expression at %L", &code->loc); + return; + } + if (aop != GFC_OMP_ATOMIC_CAPTURE) + { + if (code->next != NULL) + goto unexpected; + } + else + { + if (code->next == NULL) + goto unexpected; + if (code->next->op == EXEC_NOP) + return; + if (code->next->op != EXEC_ASSIGN || code->next->next) + { + code = code->next; + goto unexpected; + } + } if (code->expr1->expr_type != EXPR_VARIABLE || code->expr1->symtree == NULL |