Hi all, here is a follow-up patch to my recent commit for PR 85599, also dealing with the short-circuiting of logical operators. In the course of the extensive discussion of that PR it became clear that the Fortran standard allows the short-circuiting of .AND. and .OR. operators, but does not mandate it.
gfortran currently does short-circuiting, and after my patch for PR 85599 warns about cases where this might remove an impure function call (which potentially can change results). Now, this PR (57160) is about code which relies on the short-circuiting behavior. Since short-circuiting is not guaranteed by the standard, such code is invalid. Generating a warning or an error at compile-time is a bit harder here, though, since there are multiple variations of such a situation, e.g.: * ASSOCIATED(p) .AND. p%T * ALLOCATED(a) .AND. a%T * i<ubound(x) .AND. x(i) * ... The suggestion in the PR was to do short-circuiting only with optimization flags, but inhibit it with -O0, so that the faulty code will run into a segfault (or runtime error) at least when optimizations are disabled, and the problem can be identified. I find this suggestion very reasonable. It makes it possible to detect invalid code at -O0, while keeping good performance for valid code at -O{1,2,3}. Also it is technically very simple to implement, and it immediately identified a faulty test case that has lived in the testsuite for eleven years without being detected. The attached patch regtests cleanly on x86_64-linux-gnu. Ok for trunk? Cheers, Janus 2018-07-20 Janus Weil <ja...@gcc.gnu.org> PR fortran/57160 * trans-expr.c (gfc_conv_expr_op): Use short-circuiting operators only with -ffrontend-optimize. Without that flag, make sure that both operands are evaluated. 2018-07-20 Janus Weil <ja...@gcc.gnu.org> PR fortran/57160 * gfortran.dg/actual_pointer_function_1.f90: Fix invalid test case.
Index: gcc/fortran/trans-expr.c =================================================================== --- gcc/fortran/trans-expr.c (revision 262908) +++ gcc/fortran/trans-expr.c (working copy) @@ -3348,12 +3348,12 @@ gfc_conv_expr_op (gfc_se * se, gfc_expr * expr) return; case INTRINSIC_AND: - code = TRUTH_ANDIF_EXPR; + code = flag_frontend_optimize ? TRUTH_ANDIF_EXPR : TRUTH_AND_EXPR; lop = 1; break; case INTRINSIC_OR: - code = TRUTH_ORIF_EXPR; + code = flag_frontend_optimize ? TRUTH_ORIF_EXPR : TRUTH_OR_EXPR; lop = 1; break; Index: gcc/testsuite/gfortran.dg/actual_pointer_function_1.f90 =================================================================== --- gcc/testsuite/gfortran.dg/actual_pointer_function_1.f90 (revision 262908) +++ gcc/testsuite/gfortran.dg/actual_pointer_function_1.f90 (working copy) @@ -17,7 +17,11 @@ CONTAINS logical function cp_logger_log(logger) TYPE(cp_logger_type), POINTER ::logger - cp_logger_log = associated (logger) .and. (logger%a .eq. 42) + if (associated (logger)) then + cp_logger_log = (logger%a .eq. 42) + else + cp_logger_log = .false. + end if END function FUNCTION cp_get_default_logger(v) RESULT(res)