Re: Bug 104404 - Incorrect CFI_cdesc_t "type" member for assumed-type, assumed-rank complex dummy arguments
Hi Damian, Tobias Burnus fixed it in 12-branch: GNU Fortran (GCC) 12.0.1 20220203 (experimental) ./a.out - complex(c_float_complex) a_desc->type = 1028 a_desc->elem_len = 8 CFI_type_float_Complex = 1028 CFI_type_double_Complex = 2052 - complex(c_double_complex) --- a_desc->type = 2052 a_desc->elem_len = 16 CFI_type_float_Complex = 1028 CFI_type_double_Complex = 2052 Cheers Paul On Sun, 6 Feb 2022 at 03:39, Damian Rouson via Fortran wrote: > For an assumed-type, assumed-rank complex dummy argument in a C interface, > gfortran 11.2.0 passes a CFI_cdesc_t object with a "type" member that does > not match the corresponding CFI_type_float_Complex and > CFI_type_double_Complex values. In the case of a complex(c_float_complex) > argument, the passed "type" member corresponds to CFI_type_double_Complex. > For a complex(c_double_complex) argument, the "type" member has a value > that I don't recognize. Does anyone know whether this has been fixed on > the 12 branch? > > % cat c_descriptor.c > #include > #include > > void c_descriptor(CFI_cdesc_t* c) > { > printf("a_desc->type = %d \n", c->type); > printf("a_desc->elem_len = %d \n", c->elem_len); > printf("CFI_type_float_Complex = %d \n", CFI_type_float_Complex); > printf("CFI_type_double_Complex = %d \n", CFI_type_double_Complex); > } > > % cat c_descriptor.c > #include > #include > > void c_descriptor(CFI_cdesc_t* c) > { > printf("a_desc->type = %d \n", c->type); > printf("a_desc->elem_len = %d \n", c->elem_len); > printf("CFI_type_float_Complex = %d \n", CFI_type_float_Complex); > printf("CFI_type_double_Complex = %d \n", CFI_type_double_Complex); > } > (base) rouson@CLaSS adhoc % cat assumed-type.f90 > module c_descriptor_m > implicit none > contains > module subroutine print_type_info(a) > type(*), intent(inout), contiguous, target :: a(..) > > interface > subroutine c_descriptor(a) bind(C) > implicit none > type(*) a(..) > end subroutine > end interface > > call c_descriptor(a) > > end subroutine > end module > > use c_descriptor_m > use iso_c_binding > implicit none > > complex(c_float_complex) :: z_float = (0._c_float, 0._c_float) > complex(c_double_complex):: z_double = (0._c_double, 0._c_double) > > print*, "- complex(c_float_complex) " > call print_type_info(z_float) > print*, "- complex(c_double_complex) ---" > call print_type_info(z_double) > end > > % gfortran c_descriptor.c assumed-type.f90 > > % ./a.out > - complex(c_float_complex) > a_desc->type = 2052 > a_desc->elem_len = 8 > CFI_type_float_Complex = 1028 > CFI_type_double_Complex = 2052 > - complex(c_double_complex) --- > a_desc->type = 4100 > a_desc->elem_len = 16 > CFI_type_float_Complex = 1028 > CFI_type_double_Complex = 2052 > > % gfortran --version > GNU Fortran (Homebrew GCC 11.2.0_3) 11.2.0 > -- "If you can't explain it simply, you don't understand it well enough" - Albert Einstein
Re: Bug 104404 - Incorrect CFI_cdesc_t "type" member for assumed-type, assumed-rank complex dummy arguments
That's great news. Thanks for letting me know. Damian On Sun, Feb 6, 2022 at 12:48 AM Paul Richard Thomas < paul.richard.tho...@gmail.com> wrote: > Hi Damian, > > Tobias Burnus fixed it in 12-branch: > GNU Fortran (GCC) 12.0.1 20220203 (experimental) > ./a.out > - complex(c_float_complex) > a_desc->type = 1028 > a_desc->elem_len = 8 > CFI_type_float_Complex = 1028 > CFI_type_double_Complex = 2052 > - complex(c_double_complex) --- > a_desc->type = 2052 > a_desc->elem_len = 16 > CFI_type_float_Complex = 1028 > CFI_type_double_Complex = 2052 > > Cheers > > Paul > > > On Sun, 6 Feb 2022 at 03:39, Damian Rouson via Fortran < > fortran@gcc.gnu.org> wrote: > >> For an assumed-type, assumed-rank complex dummy argument in a C interface, >> gfortran 11.2.0 passes a CFI_cdesc_t object with a "type" member that does >> not match the corresponding CFI_type_float_Complex and >> CFI_type_double_Complex values. In the case of a complex(c_float_complex) >> argument, the passed "type" member corresponds to CFI_type_double_Complex. >> For a complex(c_double_complex) argument, the "type" member has a value >> that I don't recognize. Does anyone know whether this has been fixed on >> the 12 branch? >> >> % cat c_descriptor.c >> #include >> #include >> >> void c_descriptor(CFI_cdesc_t* c) >> { >> printf("a_desc->type = %d \n", c->type); >> printf("a_desc->elem_len = %d \n", c->elem_len); >> printf("CFI_type_float_Complex = %d \n", CFI_type_float_Complex); >> printf("CFI_type_double_Complex = %d \n", CFI_type_double_Complex); >> } >> >> % cat c_descriptor.c >> #include >> #include >> >> void c_descriptor(CFI_cdesc_t* c) >> { >> printf("a_desc->type = %d \n", c->type); >> printf("a_desc->elem_len = %d \n", c->elem_len); >> printf("CFI_type_float_Complex = %d \n", CFI_type_float_Complex); >> printf("CFI_type_double_Complex = %d \n", CFI_type_double_Complex); >> } >> (base) rouson@CLaSS adhoc % cat assumed-type.f90 >> module c_descriptor_m >> implicit none >> contains >> module subroutine print_type_info(a) >> type(*), intent(inout), contiguous, target :: a(..) >> >> interface >> subroutine c_descriptor(a) bind(C) >> implicit none >> type(*) a(..) >> end subroutine >> end interface >> >> call c_descriptor(a) >> >> end subroutine >> end module >> >> use c_descriptor_m >> use iso_c_binding >> implicit none >> >> complex(c_float_complex) :: z_float = (0._c_float, 0._c_float) >> complex(c_double_complex):: z_double = (0._c_double, 0._c_double) >> >> print*, "- complex(c_float_complex) " >> call print_type_info(z_float) >> print*, "- complex(c_double_complex) ---" >> call print_type_info(z_double) >> end >> >> % gfortran c_descriptor.c assumed-type.f90 >> >> % ./a.out >> - complex(c_float_complex) >> a_desc->type = 2052 >> a_desc->elem_len = 8 >> CFI_type_float_Complex = 1028 >> CFI_type_double_Complex = 2052 >> - complex(c_double_complex) --- >> a_desc->type = 4100 >> a_desc->elem_len = 16 >> CFI_type_float_Complex = 1028 >> CFI_type_double_Complex = 2052 >> >> % gfortran --version >> GNU Fortran (Homebrew GCC 11.2.0_3) 11.2.0 >> > > > -- > "If you can't explain it simply, you don't understand it well enough" - > Albert Einstein >
Re: [PATCH] PR/101135 - Load of null pointer when passing absent assumed-shape array argument for an optional dummy argument
Hi Mikael, Am 04.02.22 um 11:45 schrieb Mikael Morin: Hello, Le 29/01/2022 à 22:41, Harald Anlauf via Fortran a écrit : The least invasive change - already pointed out by the reporter - is to check the presence of the argument before dereferencing the data pointer after the offset calculation. This requires adjusting the checking pattern for gfortran.dg/missing_optional_dummy_6a.f90. Regtesting reminded me that procedures with bind(c) attribute are doing their own stuff, which is why they need to be excluded here, otherwise testcase bind-c-contiguous-4.f90 would regress on the expected output. only after submitting the patch I figured that the patch is incomplete. When we have a call chain of procedures with and without bind(c), there are still cases left where the failure with the sanitizer is not fixed. Just add "bind(c)" to subroutine test_wrapper only in the original PR. I have added a corresponding comment in the PR. There is a potential alternative solution which I did not pursue, as I think it is more invasive, but also that I didn't succeed to implement: A non-present dummy array argument should not need to get its descriptor set up. Pursuing this is probably not the right thing to do during the current stage of development and could be implemented later. If somebody believes this is important, feel free to open a PR for this. I have an other (equally unimportant) concern that it may create an unnecessary conditional when passing a subobject of an optional argument. In that case we can assume that the optional is present. It’s not a correctness issue, so let’s not bother at this stage. Judging from the dump tree of the cases I looked at I did not see anything that would pose a problem to the optimizer. Regtested on x86_64-pc-linux-gnu. OK for mainline? OK. Given my latest observations I'd rather withdraw the current version of the patch and rethink. I also did not see an issue with bind(c) procedures calling alikes. It would help if one would not only know the properties of the actual argument, but also of the formal one, which is not available at that point in the code. I'll have another look and resubmit. Thanks. Thanks for the review! Harald
[PATCH] PR fortran/66193 - ICE for initialisation of some non-zero-sized arrays
Dear Fortranners, some instances of valid constant array constructors did lead to ICEs. It turned out that on the one hand we need to attempt simplification of elements of the constructor, especially when we encounter parenthesized expression. On the other hand the occurence of type specs and empty constructors need to be handled more gracefully. Parts of the PR have been fixed previously, so the remaining part was rather simple. The testcase is based on Gerhards latest example attached to the PR. Regtested on x86_64-pc-linux-gnu. OK for mainline? Given the simplicity of the patch and that it is an ICE on valid code, would this qualify for later application to 11-branch? Thanks, Harald From 65966b608cff757f43316e1aeed37bd07ce63fe2 Mon Sep 17 00:00:00 2001 From: Harald Anlauf Date: Sun, 6 Feb 2022 21:47:20 +0100 Subject: [PATCH] Fortran: try simplifications during reductions of array constructors gcc/fortran/ChangeLog: PR fortran/66193 * arith.cc (reduce_binary_ac): When reducing binary expressions, try simplification. Handle case of empty constructor. (reduce_binary_ca): Likewise. gcc/testsuite/ChangeLog: PR fortran/66193 * gfortran.dg/array_constructor_55.f90: New test. --- gcc/fortran/arith.cc | 36 ++-- .../gfortran.dg/array_constructor_55.f90 | 55 +++ 2 files changed, 85 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/array_constructor_55.f90 diff --git a/gcc/fortran/arith.cc b/gcc/fortran/arith.cc index b3323ecf640..06e032e22db 100644 --- a/gcc/fortran/arith.cc +++ b/gcc/fortran/arith.cc @@ -1305,6 +1305,8 @@ reduce_binary_ac (arith (*eval) (gfc_expr *, gfc_expr *, gfc_expr **), head = gfc_constructor_copy (op1->value.constructor); for (c = gfc_constructor_first (head); c; c = gfc_constructor_next (c)) { + gfc_simplify_expr (c->expr, 0); + if (c->expr->expr_type == EXPR_CONSTANT) rc = eval (c->expr, op2, &r); else @@ -1321,9 +1323,19 @@ reduce_binary_ac (arith (*eval) (gfc_expr *, gfc_expr *, gfc_expr **), else { gfc_constructor *c = gfc_constructor_first (head); - r = gfc_get_array_expr (c->expr->ts.type, c->expr->ts.kind, - &op1->where); - r->shape = gfc_copy_shape (op1->shape, op1->rank); + if (c) + { + r = gfc_get_array_expr (c->expr->ts.type, c->expr->ts.kind, + &op1->where); + r->shape = gfc_copy_shape (op1->shape, op1->rank); + } + else + { + gcc_assert (op1->ts.type != BT_UNKNOWN); + r = gfc_get_array_expr (op1->ts.type, op1->ts.kind, + &op1->where); + r->shape = gfc_get_shape (op1->rank); + } r->rank = op1->rank; r->value.constructor = head; *result = r; @@ -1345,6 +1357,8 @@ reduce_binary_ca (arith (*eval) (gfc_expr *, gfc_expr *, gfc_expr **), head = gfc_constructor_copy (op2->value.constructor); for (c = gfc_constructor_first (head); c; c = gfc_constructor_next (c)) { + gfc_simplify_expr (c->expr, 0); + if (c->expr->expr_type == EXPR_CONSTANT) rc = eval (op1, c->expr, &r); else @@ -1361,9 +1375,19 @@ reduce_binary_ca (arith (*eval) (gfc_expr *, gfc_expr *, gfc_expr **), else { gfc_constructor *c = gfc_constructor_first (head); - r = gfc_get_array_expr (c->expr->ts.type, c->expr->ts.kind, - &op2->where); - r->shape = gfc_copy_shape (op2->shape, op2->rank); + if (c) + { + r = gfc_get_array_expr (c->expr->ts.type, c->expr->ts.kind, + &op2->where); + r->shape = gfc_copy_shape (op2->shape, op2->rank); + } + else + { + gcc_assert (op2->ts.type != BT_UNKNOWN); + r = gfc_get_array_expr (op2->ts.type, op2->ts.kind, + &op2->where); + r->shape = gfc_get_shape (op2->rank); + } r->rank = op2->rank; r->value.constructor = head; *result = r; diff --git a/gcc/testsuite/gfortran.dg/array_constructor_55.f90 b/gcc/testsuite/gfortran.dg/array_constructor_55.f90 new file mode 100644 index 000..52142cb10c0 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/array_constructor_55.f90 @@ -0,0 +1,55 @@ +! { dg-do run } +! PR fortran/66193 - ICE for initialisation of some non-zero-sized arrays +! Testcase by G.Steinmetz + +program p + implicit none + call s1 + call s2 + call s3 + call s4 +contains + subroutine s1 +integer(8), parameter :: z1(2) = 10 + [ integer(8) :: [ integer(4) ::],1,2] +integer(8):: z2(2) = 10 + [ integer(8) :: [ integer(4) ::],1,2] +integer(8):: z3(2) +z3 = 10 + [ integer(8) :: [ integer(4) :: ], 1, 2 ] +if ( z1(1) /= 11 .or. z1(2) /= 12 ) stop 1 +if ( z2(1) /= 11 .or. z2(2) /= 12 ) stop 2 +if ( z3(1) /= 11 .or. z3(2) /= 12 ) stop 3 + end subroutine s1 + + subroutine s2 +logical(8), parameter :: z1(3) = .true. .or. & + [ logical(8) :: [ logical(4) :: ], .false., .false., .true. ] +logical(8):: z2(3) = .true. .or. & + [ logical(8) :: [ logical(4) :: ], .false.,