diff options
author | Bernhard Rosenkraenzer <Bernhard.Rosenkranzer@linaro.org> | 2013-05-08 01:49:25 +0000 |
---|---|---|
committer | Bernhard Rosenkraenzer <Bernhard.Rosenkranzer@linaro.org> | 2013-05-08 01:49:25 +0000 |
commit | 2ebacea7ce44a8c8d99d4ec0460f4379caa89b49 (patch) | |
tree | 73aed2f961456068d5ba1fc2051bf143823e35d0 | |
parent | 47308a030ce399bb2bd016d27cd8666abf82a4e7 (diff) | |
download | gcc-aarch64-aarch64-4.7.tar.gz |
Sync with svn rev. 198689aarch64-4.7
Signed-off-by: Bernhard Rosenkraenzer <Bernhard.Rosenkranzer@linaro.org>
27 files changed, 604 insertions, 44 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 32689ee77..23819af08 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,32 @@ +2013-05-07 Ian Bolton <ian.bolton@arm.com> + + Backport from mainline + 2013-03-28 Ian Bolton <ian.bolton@arm.com> + + * config/aarch64/aarch64.md (aarch64_can_eliminate): Keep frame + record only when desired or required. + +2013-04-30 Uros Bizjak <ubizjak@gmail.com> + + Backport from mainline + 2013-04-29 Uros Bizjak <ubizjak@gmail.com> + + PR target/44578 + * config/i386/i386.md (*zero_extendsidi2_rex64): Add "!" to m->?*y + alternative. + (*zero_extendsidi2): Ditto. + + Backport from mainline + 2013-04-29 Uros Bizjak <ubizjak@gmail.com> + + PR target/57098 + * config/i386/i386.c (ix86_expand_vec_perm): Validize constant memory. + +2013-04-29 Christian Bruel <christian.bruel@st.com> + + PR target/57108 + * sh.md (tstsi_t_zero_extract_eq): Set mode for operand 0. + 2013-04-27 Jakub Jelinek <jakub@redhat.com> PR target/56866 diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 320055fed..d9a931acd 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20130428 +20130503 diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index 5bc6f8433..2a1ada29d 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -3865,14 +3865,21 @@ aarch64_can_eliminate (const int from, const int to) } else { - /* If we decided that we didn't need a frame pointer but then used - LR in the function, then we do need a frame pointer after all, so - prevent this elimination to ensure a frame pointer is used. */ - + /* If we decided that we didn't need a leaf frame pointer but then used + LR in the function, then we'll want a frame pointer after all, so + prevent this elimination to ensure a frame pointer is used. + + NOTE: the original value of flag_omit_frame_pointer gets trashed + IFF flag_omit_leaf_frame_pointer is true, so we check the value + of faked_omit_frame_pointer here (which is true when we always + wish to keep non-leaf frame pointers but only wish to keep leaf frame + pointers when LR is clobbered). */ if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM - && df_regs_ever_live_p (LR_REGNUM)) + && df_regs_ever_live_p (LR_REGNUM) + && faked_omit_frame_pointer) return false; } + return true; } diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 440bd82dd..cd117d40d 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -20026,7 +20026,7 @@ ix86_expand_vec_perm (rtx operands[]) vec[i * 2 + 1] = const1_rtx; } vt = gen_rtx_CONST_VECTOR (maskmode, gen_rtvec_v (w, vec)); - vt = force_const_mem (maskmode, vt); + vt = validize_mem (force_const_mem (maskmode, vt)); t1 = expand_simple_binop (maskmode, PLUS, t1, vt, t1, 1, OPTAB_DIRECT); @@ -20223,7 +20223,7 @@ ix86_expand_vec_perm (rtx operands[]) for (i = 0; i < 16; ++i) vec[i] = GEN_INT (i/e * e); vt = gen_rtx_CONST_VECTOR (V16QImode, gen_rtvec_v (16, vec)); - vt = force_const_mem (V16QImode, vt); + vt = validize_mem (force_const_mem (V16QImode, vt)); if (TARGET_XOP) emit_insn (gen_xop_pperm (mask, mask, mask, vt)); else @@ -20234,7 +20234,7 @@ ix86_expand_vec_perm (rtx operands[]) for (i = 0; i < 16; ++i) vec[i] = GEN_INT (i % e); vt = gen_rtx_CONST_VECTOR (V16QImode, gen_rtvec_v (16, vec)); - vt = force_const_mem (V16QImode, vt); + vt = validize_mem (force_const_mem (V16QImode, vt)); emit_insn (gen_addv16qi3 (mask, mask, vt)); } diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index d462b76cb..627beee98 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -3444,9 +3444,9 @@ }) (define_insn "*zero_extendsidi2_rex64" - [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*x") + [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?!*y,?*Yi,*x") (zero_extend:DI - (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))] + (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))] "TARGET_64BIT" "@ mov{l}\t{%1, %k0|%k0, %1} @@ -3469,9 +3469,9 @@ ;; %%% Kill me once multi-word ops are sane. (define_insn "zero_extendsidi2_1" - [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*x") + [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?!*y,?*Yi,*x") (zero_extend:DI - (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m"))) + (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m"))) (clobber (reg:CC FLAGS_REG))] "!TARGET_64BIT" "@ diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md index cbe0b2c01..14e6557d9 100644 --- a/gcc/config/sh/sh.md +++ b/gcc/config/sh/sh.md @@ -654,7 +654,7 @@ (define_insn "tstsi_t_zero_extract_eq" [(set (reg:SI T_REG) - (eq:SI (zero_extract:SI (match_operand 0 "logical_operand" "z") + (eq:SI (zero_extract:SI (match_operand:SI 0 "logical_operand" "z") (match_operand:SI 1 "const_int_operand") (match_operand:SI 2 "const_int_operand")) (const_int 0)))] diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8a237420a..a4b6b3e51 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,74 @@ +2013-05-07 Ian Bolton <ian.bolton@arm.com> + + Backport from mainline (fix to botched commit) + 2013-04-04 Tejas Belagod <tejas.belagod@arm.com> + + * gcc.target/aarch64/inc/asm-adder-clobber-lr.c: Remove duplication. + * gcc.target/aarch64/inc/asm-adder-no-clobber-lr.c: Likewise. + * gcc.target/aarch64/test-framepointer-1.c: Likewise. + * gcc.target/aarch64/test-framepointer-2.c: Likewise. + * gcc.target/aarch64/test-framepointer-3.c: Likewise. + * gcc.target/aarch64/test-framepointer-4.c: Likewise. + * gcc.target/aarch64/test-framepointer-5.c: Likewise. + * gcc.target/aarch64/test-framepointer-6.c: Likewise. + * gcc.target/aarch64/test-framepointer-7.c: Likewise. + * gcc.target/aarch64/test-framepointer-8.c: Likewise. + + Backport from mainline + 2013-03-28 Ian Bolton <ian.bolton@arm.com> + + * gcc.target/aarch64/inc/asm-adder-clobber-lr.c: New test. + * gcc.target/aarch64/inc/asm-adder-no-clobber-lr.c: Likewise. + * gcc.target/aarch64/test-framepointer-1.c: Likewise. + * gcc.target/aarch64/test-framepointer-2.c: Likewise. + * gcc.target/aarch64/test-framepointer-3.c: Likewise. + * gcc.target/aarch64/test-framepointer-4.c: Likewise. + * gcc.target/aarch64/test-framepointer-5.c: Likewise. + * gcc.target/aarch64/test-framepointer-6.c: Likewise. + * gcc.target/aarch64/test-framepointer-7.c: Likewise. + * gcc.target/aarch64/test-framepointer-8.c: Likewise. + +2013-04-30 Uros Bizjak <ubizjak@gmail.com> + + Backport from mainline + 2013-04-29 Uros Bizjak <ubizjak@gmail.com> + + PR target/44578 + * gcc.target/i386/pr44578.c: New test. + + Backport from mainline + 2013-04-29 Uros Bizjak <ubizjak@gmail.com> + + PR target/57098 + * gcc.target/i386/pr57098.c: New test. + +2013-04-29 Christian Bruel <christian.bruel@st.com> + + PR target/57108 + * gcc.target/sh/pr57108.c: New test. + +2013-04-28 Jerry DeLisle <jvdelisle@gcc.gnu.org> + + Backport from trunk: + + PR fortran/51825 + * gfortran.dg/namelist_77.f90: New test. + * gfortran.dg/namelist_78.f90: New test. + +2013-04-28 Jerry DeLisle <jvdelisle@gcc.gnu.org> + + Backport from trunk: + + PR fortran/56786 + * gfortran.dg/namelist_81.f90: New test. + +2013-04-28 Jerry DeLisle <jvdelisle@gcc.gnu.org> + + Backport from trunk: + + PR fortran/52512 + * gfortran.dg/namelist_79.f90: New test. + 2013-04-27 Jakub Jelinek <jakub@redhat.com> PR target/56866 diff --git a/gcc/testsuite/gcc.target/aarch64/asm-adder-clobber-lr.c b/gcc/testsuite/gcc.target/aarch64/asm-adder-clobber-lr.c new file mode 100644 index 000000000..540c79b01 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/asm-adder-clobber-lr.c @@ -0,0 +1,23 @@ +extern void abort (void); + +int +adder (int a, int b) +{ + int result; + __asm__ ("add %w0,%w1,%w2" : "=r"(result) : "r"(a), "r"(b) : "x30"); + return result; +} + +int +main (int argc, char** argv) +{ + int i; + int total = argc; + for (i = 0; i < 20; i++) + total = adder (total, i); + + if (total != (190 + argc)) + abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/aarch64/asm-adder-no-clobber-lr.c b/gcc/testsuite/gcc.target/aarch64/asm-adder-no-clobber-lr.c new file mode 100644 index 000000000..2543d50e7 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/asm-adder-no-clobber-lr.c @@ -0,0 +1,23 @@ +extern void abort (void); + +int +adder (int a, int b) +{ + int result; + __asm__ ("add %w0,%w1,%w2" : "=r"(result) : "r"(a), "r"(b) : ); + return result; +} + +int +main (int argc, char** argv) +{ + int i; + int total = argc; + for (i = 0; i < 20; i++) + total = adder (total, i); + + if (total != (190 + argc)) + abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/aarch64/test-framepointer-1.c b/gcc/testsuite/gcc.target/aarch64/test-framepointer-1.c new file mode 100644 index 000000000..e44ca6d4c --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/test-framepointer-1.c @@ -0,0 +1,15 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -fno-inline --save-temps" } */ + +#include "asm-adder-no-clobber-lr.c" + +/* omit-frame-pointer is FALSE. + omit-leaf-frame-pointer is FALSE. + LR is not being clobbered in the leaf. + + With no frame pointer omissions, we expect a frame record + for main and the leaf. */ + +/* { dg-final { scan-assembler-times "stp\tx29, x30, \\\[sp, -\[0-9\]+\\\]!" 2 } } */ + +/* { dg-final { cleanup-saved-temps } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/test-framepointer-2.c b/gcc/testsuite/gcc.target/aarch64/test-framepointer-2.c new file mode 100644 index 000000000..40e483526 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/test-framepointer-2.c @@ -0,0 +1,15 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -fomit-frame-pointer -mno-omit-leaf-frame-pointer -fno-inline --save-temps" } */ + +#include "asm-adder-no-clobber-lr.c" + +/* omit-frame-pointer is TRUE. + omit-leaf-frame-pointer is false, but irrelevant due to omit-frame-pointer. + LR is not being clobbered in the leaf. + + Since we asked to have no frame pointers anywhere, we expect no frame + record in main or the leaf. */ + +/* { dg-final { scan-assembler-not "stp\tx29, x30, \\\[sp, -\[0-9\]+\\\]!" } } */ + +/* { dg-final { cleanup-saved-temps } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/test-framepointer-3.c b/gcc/testsuite/gcc.target/aarch64/test-framepointer-3.c new file mode 100644 index 000000000..98cb2e0b6 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/test-framepointer-3.c @@ -0,0 +1,15 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -fomit-frame-pointer -momit-leaf-frame-pointer -fno-inline --save-temps" } */ + +#include "asm-adder-no-clobber-lr.c" + +/* omit-frame-pointer is TRUE. + omit-leaf-frame-pointer is true, but irrelevant due to omit-frame-pointer. + LR is not being clobbered in the leaf. + + Since we asked to have no frame pointers anywhere, we expect no frame + record in main or the leaf. */ + +/* { dg-final { scan-assembler-not "stp\tx29, x30, \\\[sp, -\[0-9\]+\\\]!" } } */ + +/* { dg-final { cleanup-saved-temps } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/test-framepointer-4.c b/gcc/testsuite/gcc.target/aarch64/test-framepointer-4.c new file mode 100644 index 000000000..4143a7a9c --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/test-framepointer-4.c @@ -0,0 +1,16 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -fno-omit-frame-pointer -momit-leaf-frame-pointer -fno-inline --save-temps" } */ + +#include "asm-adder-no-clobber-lr.c" + +/* omit-frame-pointer is FALSE. + omit-leaf-frame-pointer is TRUE. + LR is not being clobbered in the leaf. + + Unless we are removing all frame records, it's OK to remove the frame + record for a leaf where LR is not clobbered. Therefore, we expect a + frame record only in main. */ + +/* { dg-final { scan-assembler-times "stp\tx29, x30, \\\[sp, -\[0-9\]+\\\]!" 1 } } */ + +/* { dg-final { cleanup-saved-temps } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/test-framepointer-5.c b/gcc/testsuite/gcc.target/aarch64/test-framepointer-5.c new file mode 100644 index 000000000..c22bdc304 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/test-framepointer-5.c @@ -0,0 +1,15 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -fno-inline --save-temps" } */ + +#include "asm-adder-clobber-lr.c" + +/* omit-frame-pointer is FALSE. + omit-leaf-frame-pointer is FALSE. + LR is being clobbered in the leaf. + + With no frame pointer omissions, we expect a frame record for main + and the leaf. */ + +/* { dg-final { scan-assembler-times "stp\tx29, x30, \\\[sp, -\[0-9\]+\\\]!" 2 } } */ + +/* { dg-final { cleanup-saved-temps } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/test-framepointer-6.c b/gcc/testsuite/gcc.target/aarch64/test-framepointer-6.c new file mode 100644 index 000000000..e08ee43e5 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/test-framepointer-6.c @@ -0,0 +1,15 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -fomit-frame-pointer -mno-omit-leaf-frame-pointer -fno-inline --save-temps" } */ + +#include "asm-adder-clobber-lr.c" + +/* omit-frame-pointer is TRUE. + omit-leaf-frame-pointer is false, but irrelevant due to omit-frame-pointer. + LR is being clobbered in the leaf. + + Since we asked to have no frame pointers anywhere, we expect no frame + record in main or the leaf. */ + +/* { dg-final { scan-assembler-not "stp\tx29, x30, \\\[sp, -\[0-9\]+\\\]!" } } */ + +/* { dg-final { cleanup-saved-temps } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/test-framepointer-7.c b/gcc/testsuite/gcc.target/aarch64/test-framepointer-7.c new file mode 100644 index 000000000..e8f7cabe7 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/test-framepointer-7.c @@ -0,0 +1,15 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -fomit-frame-pointer -momit-leaf-frame-pointer -fno-inline --save-temps" } */ + +#include "asm-adder-clobber-lr.c" + +/* omit-frame-pointer is TRUE. + omit-leaf-frame-pointer is true, but irrelevant due to omit-frame-pointer. + LR is being clobbered in the leaf. + + Since we asked to have no frame pointers anywhere, we expect no frame + record in main or the leaf. */ + +/* { dg-final { scan-assembler-not "stp\tx29, x30, \\\[sp, -\[0-9\]+\\\]!" } } */ + +/* { dg-final { cleanup-saved-temps } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/test-framepointer-8.c b/gcc/testsuite/gcc.target/aarch64/test-framepointer-8.c new file mode 100644 index 000000000..c09b68759 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/test-framepointer-8.c @@ -0,0 +1,16 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -fno-omit-frame-pointer -momit-leaf-frame-pointer -fno-inline --save-temps" } */ + +#include "asm-adder-clobber-lr.c" + +/* omit-frame-pointer is FALSE. + omit-leaf-frame-pointer is TRUE. + LR is being clobbered in the leaf. + + Unless we are removing all frame records (which we aren't), it's + not OK to remove the frame record for a leaf where LR is clobbered. + Therefore, we expect a frame record in main and leaf. */ + +/* { dg-final { scan-assembler-times "stp\tx29, x30, \\\[sp, -\[0-9\]+\\\]!" 2 } } */ + +/* { dg-final { cleanup-saved-temps } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr44578.c b/gcc/testsuite/gcc.target/i386/pr44578.c new file mode 100644 index 000000000..20f76c31c --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr44578.c @@ -0,0 +1,31 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -mtune=athlon64" } */ + +extern void abort (void); + +long double +__attribute__((noinline, noclone)) +test (float num) +{ + unsigned int i; + + if (num < 0.0) + num = 0.0; + + __builtin_memcpy (&i, &num, sizeof(unsigned int)); + + return (long double)(unsigned long long) i; +} + +int +main () +{ + long double x; + + x = test (0.0); + + if (x != 0.0) + abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/i386/pr57098.c b/gcc/testsuite/gcc.target/i386/pr57098.c new file mode 100644 index 000000000..37598d7ce --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr57098.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-options "-msse4 -mcmodel=large" } */ + +typedef int V __attribute__((vector_size(16))); + +void foo (V *p, V *mask) +{ + *p = __builtin_shuffle (*p, *mask); +} diff --git a/gcc/testsuite/gcc.target/sh/pr57108.c b/gcc/testsuite/gcc.target/sh/pr57108.c new file mode 100644 index 000000000..3d39637b6 --- /dev/null +++ b/gcc/testsuite/gcc.target/sh/pr57108.c @@ -0,0 +1,19 @@ +/* { dg-do compile { target "sh*-*-*" } } */ +/* { dg-options "-O1" } */ + +void __assert_func (void) __attribute__ ((__noreturn__)) ; + +void ATATransfer (int num, int buffer) +{ + int wordCount; + + while (num > 0) + { + wordCount = num * 512 / sizeof (int); + + ((0 == (buffer & 63)) ? (void)0 : __assert_func () ); + ((0 == (wordCount & 31)) ? (void)0 : __assert_func ()); + } + + + } diff --git a/gcc/testsuite/gfortran.dg/namelist_77.f90 b/gcc/testsuite/gfortran.dg/namelist_77.f90 new file mode 100644 index 000000000..5cbfe3aad --- /dev/null +++ b/gcc/testsuite/gfortran.dg/namelist_77.f90 @@ -0,0 +1,49 @@ +! { dg-do run } +! +! PR libfortran/51825 - Fortran runtime error: Cannot match namelist object name +! Test case derived from PR. + +module local_mod + + type mytype1 + integer :: int1 + end type + + type mytype2 + integer :: n_x + integer :: n_px + end type + + type beam_init_struct + character(16) :: chars(1) = '' + type (mytype1) dummy + type (mytype2) grid(1) + end type + +end module + +program error_namelist + + use local_mod + + implicit none + + type (beam_init_struct) beam_init + + namelist / error_params / beam_init + + open (10, status='scratch') + write (10, '(a)') "&error_params" + write (10, '(a)') " beam_init%chars(1)='JUNK'" + write (10, '(a)') " beam_init%grid(1)%n_x=3" + write (10, '(a)') " beam_init%grid(1)%n_px=2" + write (10, '(a)') "/" + rewind(10) + read(10, nml=error_params) + close (10) + + if (beam_init%chars(1) /= 'JUNK') call abort + if (beam_init%grid(1)%n_x /= 3) call abort + if (beam_init%grid(1)%n_px /= 2) call abort + +end program diff --git a/gcc/testsuite/gfortran.dg/namelist_78.f90 b/gcc/testsuite/gfortran.dg/namelist_78.f90 new file mode 100644 index 000000000..d4e29ab82 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/namelist_78.f90 @@ -0,0 +1,34 @@ +! { dg-do run } +! +! PR libfortran/51825 +! Test case regarding namelist problems with derived types + +program namelist + + type d1 + integer :: j = 0 + end type d1 + + type d2 + type(d1) k + end type d2 + + type d3 + type(d2) d(2) + end type d3 + + type(d3) der + namelist /nmlst/ der + + open (10, status='scratch') + write (10, '(a)') "&NMLST" + write (10, '(a)') " DER%D(1)%K%J = 1," + write (10, '(a)') " DER%D(2)%K%J = 2," + write (10, '(a)') "/" + rewind(10) + read(10, nml=nmlst) + close (10) + + if (der%d(1)%k%j /= 1) call abort + if (der%d(2)%k%j /= 2) call abort +end program namelist diff --git a/gcc/testsuite/gfortran.dg/namelist_79.f90 b/gcc/testsuite/gfortran.dg/namelist_79.f90 new file mode 100644 index 000000000..2b2ef310d --- /dev/null +++ b/gcc/testsuite/gfortran.dg/namelist_79.f90 @@ -0,0 +1,43 @@ +! { dg-do run } +! PR libfortran/52512 - Cannot match namelist object name +! Test case derived from PR. + +program testje + + implicit none + + integer :: getal, jn + type ptracer + character(len = 8) :: sname !: short name + logical :: lini !: read in a file or not + end type ptracer + type(ptracer) , dimension(3) :: tracer + namelist/namtoptrc/ getal,tracer + + ! standard values + getal = 9999 + do jn = 1, 3 + tracer(jn)%sname = 'default_name' + tracer(jn)%lini = .false. + end do + + open (10, status='scratch') + write (10, '(a)') "&namtoptrc" + write (10, '(a)') " getal = 7" + write (10, '(a)') " tracer(1) = 'DIC ', .true." + write (10, '(a)') " tracer(2) = 'Alkalini', .true." + write (10, '(a)') " tracer(3) = 'O2 ', .true." + write (10, '(a)') "/" + rewind(10) + read(10, nml=namtoptrc) + close (10) + + if (getal /= 7) call abort + if (tracer(1)%sname /= 'DIC ') call abort + if (tracer(2)%sname /= 'Alkalini') call abort + if (tracer(3)%sname /= 'O2 ') call abort + if (.not. tracer(1)%lini) call abort + if (.not. tracer(2)%lini) call abort + if (.not. tracer(3)%lini) call abort + +end program testje diff --git a/gcc/testsuite/gfortran.dg/namelist_81.f90 b/gcc/testsuite/gfortran.dg/namelist_81.f90 new file mode 100644 index 000000000..ddb100bf8 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/namelist_81.f90 @@ -0,0 +1,43 @@ +! { dg-do run } +! PR56786 Error on embedded spaces +integer :: i(3) +namelist /nml/ i + +i = -42 +open(99,status='scratch') +write(99,'(a)') '&nml i(3 ) = 5 /' +rewind(99) +read(99,nml=nml) +close(99) +if (i(1)/=-42 .or. i(2)/=-42 .or. i(3)/=5) call abort() + +! Shorten the file so the read hits EOF + +open(99,status='scratch') +write(99,'(a)') '&nml i(3 ) = 5 ' +rewind(99) +read(99,nml=nml, end=30) +call abort() +! Shorten some more + 30 close(99) +open(99,status='scratch') +write(99,'(a)') '&nml i(3 ) =' +rewind(99) +read(99,nml=nml, end=40) +call abort() +! Shorten some more + 40 close(99) +open(99,status='scratch') +write(99,'(a)') '&nml i(3 )' +rewind(99) +read(99,nml=nml, end=50) +call abort() +! Shorten some more + 50 close(99) +open(99,status='scratch') +write(99,'(a)') '&nml i(3 ' +rewind(99) +read(99,nml=nml, end=60) +call abort() + 60 close(99) +end diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index d0e034d47..7b1cda1e5 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,38 @@ +2013-04-28 Jerry DeLisle <jvdelisle@gcc.gnu.org> + + Backport from mainline: + 2013-03-20 Tilo Schwarz <tilo@tilo-schwarz.de> + + PR libfortran/51825 + * io/list_read.c (nml_read_obj): Don't end the component loop on a + nested derived type, but continue with the next loop iteration. + (nml_get_obj_data): Don't move the first_nl pointer further in the + list if a qualifier was found. + +2013-04-28 Jerry DeLisle <jvdelisle@gcc.gnu.org> + + Backport from mainline: + + PR libfortran/56786 + * io/list_read.c (nml_parse_qualifier): Remove spurious next_char call + when checking for EOF. Use error return mechanism when EOF detected. + Do not return FAILURE unless parse_err_msg and parse_err_msg_size have + been set. Use hit_eof. + (nml_get_obj_data): Likewise use the correct error mechanism. + * io/transfer.c (hit_eof): Do not set AFTER_ENDFILE if in namelist + mode. + +2013-04-28 Jerry DeLisle <jvdelisle@gcc.gnu.org> + + Backport from mainline: + 2013-03-25 Tilo Schwarz <tilo@tilo-schwarz.de> + + PR libfortran/52512 + * io/list_read.c (nml_parse_qualifier): To check for a derived type + don't use the namelist head element type but the current element type. + (nml_get_obj_data): Add current namelist element type to + nml_parse_qualifier call. + 2013-04-11 Release Manager * GCC 4.7.3 released. diff --git a/libgfortran/io/list_read.c b/libgfortran/io/list_read.c index efb43f872..e44cc14a7 100644 --- a/libgfortran/io/list_read.c +++ b/libgfortran/io/list_read.c @@ -2028,8 +2028,8 @@ calls: static try nml_parse_qualifier (st_parameter_dt *dtp, descriptor_dimension *ad, - array_loop_spec *ls, int rank, char *parse_err_msg, - size_t parse_err_msg_size, + array_loop_spec *ls, int rank, bt nml_elem_type, + char *parse_err_msg, size_t parse_err_msg_size, int *parsed_rank) { int dim; @@ -2053,7 +2053,7 @@ nml_parse_qualifier (st_parameter_dt *dtp, descriptor_dimension *ad, /* The next character in the stream should be the '('. */ if ((c = next_char (dtp)) == EOF) - return FAILURE; + goto err_ret; /* Process the qualifier, by dimension and triplet. */ @@ -2067,7 +2067,7 @@ nml_parse_qualifier (st_parameter_dt *dtp, descriptor_dimension *ad, /* Process a potential sign. */ if ((c = next_char (dtp)) == EOF) - return FAILURE; + goto err_ret; switch (c) { case '-': @@ -2085,11 +2085,12 @@ nml_parse_qualifier (st_parameter_dt *dtp, descriptor_dimension *ad, /* Process characters up to the next ':' , ',' or ')'. */ for (;;) { - if ((c = next_char (dtp)) == EOF) - return FAILURE; - + c = next_char (dtp); switch (c) { + case EOF: + goto err_ret; + case ':': is_array_section = 1; break; @@ -2112,10 +2113,8 @@ nml_parse_qualifier (st_parameter_dt *dtp, descriptor_dimension *ad, push_char (dtp, c); continue; - case ' ': case '\t': + case ' ': case '\t': case '\r': case '\n': eat_spaces (dtp); - if ((c = next_char (dtp) == EOF)) - return FAILURE; break; default: @@ -2204,7 +2203,7 @@ nml_parse_qualifier (st_parameter_dt *dtp, descriptor_dimension *ad, do not allow excess data to be processed. */ if (is_array_section == 1 || !(compile_options.allow_std & GFC_STD_GNU) - || dtp->u.p.ionml->type == BT_DERIVED) + || nml_elem_type == BT_DERIVED) ls[dim].end = ls[dim].start; else dtp->u.p.expanded_read = 1; @@ -2257,6 +2256,15 @@ nml_parse_qualifier (st_parameter_dt *dtp, descriptor_dimension *ad, err_ret: + /* The EOF error message is issued by hit_eof. Return true so that the + caller does not use parse_err_msg and parse_err_msg_size to generate + an unrelated error message. */ + if (c == EOF) + { + hit_eof (dtp); + dtp->u.p.input_complete = 1; + return SUCCESS; + } return FAILURE; } @@ -2553,17 +2561,17 @@ nml_read_obj (st_parameter_dt *dtp, namelist_info * nl, index_type offset, since a single object can have multiple reads. */ dtp->u.p.expanded_read = 0; - /* Now loop over the components. Update the component pointer - with the return value from nml_write_obj. This loop jumps - past nested derived types by testing if the potential - component name contains '%'. */ + /* Now loop over the components. */ for (cmp = nl->next; cmp && - !strncmp (cmp->var_name, obj_name, obj_name_len) && - !strchr (cmp->var_name + obj_name_len, '%'); + !strncmp (cmp->var_name, obj_name, obj_name_len); cmp = cmp->next) { + /* Jump over nested derived type by testing if the potential + component name contains '%'. */ + if (strchr (cmp->var_name + obj_name_len, '%')) + continue; if (nml_read_obj (dtp, cmp, (index_type)(pdata - nl->mem_pos), pprev_nl, nml_err_msg, nml_err_msg_size, @@ -2726,12 +2734,12 @@ nml_get_obj_data (st_parameter_dt *dtp, namelist_info **pprev_nl, return SUCCESS; if ((c = next_char (dtp)) == EOF) - return FAILURE; + goto nml_err_ret; switch (c) { case '=': if ((c = next_char (dtp)) == EOF) - return FAILURE; + goto nml_err_ret; if (c != '?') { snprintf (nml_err_msg, nml_err_msg_size, @@ -2781,8 +2789,9 @@ get_name: if (!is_separator (c)) push_char (dtp, tolower(c)); if ((c = next_char (dtp)) == EOF) - return FAILURE; - } while (!( c=='=' || c==' ' || c=='\t' || c =='(' || c =='%' )); + goto nml_err_ret; + } + while (!( c=='=' || c==' ' || c=='\t' || c =='(' || c =='%' )); unget_char (dtp, c); @@ -2842,7 +2851,7 @@ get_name: { parsed_rank = 0; if (nml_parse_qualifier (dtp, nl->dim, nl->ls, nl->var_rank, - nml_err_msg, nml_err_msg_size, + nl->type, nml_err_msg, nml_err_msg_size, &parsed_rank) == FAILURE) { char *nml_err_msg_end = strchr (nml_err_msg, '\0'); @@ -2857,7 +2866,7 @@ get_name: qualifier_flag = 1; if ((c = next_char (dtp)) == EOF) - return FAILURE; + goto nml_err_ret; unget_char (dtp, c); } else if (nl->var_rank > 0) @@ -2876,14 +2885,15 @@ get_name: goto nml_err_ret; } - if (*pprev_nl == NULL || !component_flag) + /* Don't move first_nl further in the list if a qualifier was found. */ + if ((*pprev_nl == NULL && !qualifier_flag) || !component_flag) first_nl = nl; root_nl = nl; component_flag = 1; if ((c = next_char (dtp)) == EOF) - return FAILURE; + goto nml_err_ret; goto get_name; } @@ -2898,8 +2908,8 @@ get_name: descriptor_dimension chd[1] = { {1, clow, nl->string_length} }; array_loop_spec ind[1] = { {1, clow, nl->string_length, 1} }; - if (nml_parse_qualifier (dtp, chd, ind, -1, nml_err_msg, - nml_err_msg_size, &parsed_rank) + if (nml_parse_qualifier (dtp, chd, ind, -1, nl->type, + nml_err_msg, nml_err_msg_size, &parsed_rank) == FAILURE) { char *nml_err_msg_end = strchr (nml_err_msg, '\0'); @@ -2921,7 +2931,7 @@ get_name: } if ((c = next_char (dtp)) == EOF) - return FAILURE; + goto nml_err_ret; unget_char (dtp, c); } @@ -2961,7 +2971,7 @@ get_name: return SUCCESS; if ((c = next_char (dtp)) == EOF) - return FAILURE; + goto nml_err_ret; if (c != '=') { @@ -2996,6 +3006,17 @@ get_name: nml_err_ret: + /* The EOF error message is issued by hit_eof. Return true so that the + caller does not use nml_err_msg and nml_err_msg_size to generate + an unrelated error message. */ + if (c == EOF) + { + dtp->u.p.input_complete = 1; + unget_char (dtp, c); + hit_eof (dtp); + return SUCCESS; + } + return FAILURE; } diff --git a/libgfortran/io/transfer.c b/libgfortran/io/transfer.c index f71e96f75..63e3af1b2 100644 --- a/libgfortran/io/transfer.c +++ b/libgfortran/io/transfer.c @@ -3748,7 +3748,7 @@ hit_eof (st_parameter_dt * dtp) case NO_ENDFILE: case AT_ENDFILE: generate_error (&dtp->common, LIBERROR_END, NULL); - if (!is_internal_unit (dtp)) + if (!is_internal_unit (dtp) && !dtp->u.p.namelist_mode) { dtp->u.p.current_unit->endfile = AFTER_ENDFILE; dtp->u.p.current_unit->current_record = 0; |