https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113412
--- Comment #13 from kargls at comcast dot net --- On 8/27/24 12:25, anlauf at gcc dot gnu.org wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113412 > > --- Comment #12 from anlauf at gcc dot gnu.org --- > (In reply to kargls from comment #11) > > I tried a simpler variation of your patch that aims at a more coherent > error message: > > diff --git a/gcc/fortran/intrinsic.cc b/gcc/fortran/intrinsic.cc > index f7cbb4bb5e2..28b27874298 100644 > --- a/gcc/fortran/intrinsic.cc > +++ b/gcc/fortran/intrinsic.cc > @@ -4377,10 +4377,22 @@ sort_actual (const char *name, gfc_actual_arglist > **ap, > if (a == NULL) > goto do_sort; > > + /* The generic interface of the following intrinsics was extended in F2008. > + A specific interface may not be available at a selected standard. */ > + if ((gfc_option.allow_std & GFC_STD_F2008) != 0 > + && (strcmp (name, "atan") == 0 > + || strcmp (name, "atand") == 0)) > + goto no_specific; > + atand is a F2023 intrinsic, so you need to check against GFC_STD_F2028. > whoops: > gfc_error ("Too many arguments in call to %qs at %L", name, where); > return false; > > +no_specific: > + gfc_error ("Generic function %qs at %L is not consistent with a " > + "specific intrinsic interface", name, where); > + return false; > + > keywords: > /* Associate the remaining actual arguments, all of which have > to be keyword arguments. */ > > > With this you get the message: > > Error: Generic function 'atan' at (1) is not consistent with a specific > intrinsic interface > > whether atan is explicitly declared as intrinsic or not. > >> Now, to real cause so head scratching. keywords are not honored! >> >> subroutine s3 >> real :: r = 1. >> print *, atan (y=-1.d0,x=r) ! Should give error similar to s1 case >> end >> >> % gfcx -c a.f90 >> a.f90:3:10: >> >> 3 | print *, atan (y=-1.d0,x=r) ! Should give error similar to >> s1 case >> | 1 >> Error: Cannot find keyword named ‘y’ in call to ‘atan’ at (1) >> >> I think we need to rethink the handling of the 2 argument case, where we >> make the second argument optional. Then, in gfc_check_atan, we need to >> swap expressions to align Y with arg1 and X with arg2. > Yes, this is because once a keyword is used, we never reach the check. > Which makes me think whether sort_actual is the right place for the check. I'm inclined to agree with you. > Is there any generic intrinsic where a keyword is needed for resolving? > Besides the weird ALLOCATED(), where there can be only one argument > (ARRAY or SCALAR), but then this is a fixed number. I'm not aware on any. AFAIK, all optional arguments come after any required actual arguments. Positional resolution occurs before keyword resolution unless the first argument uses a keyword. I tried modifying in intrinsic.cc add_sym_1 ("atan", GFC_ISYM_ATAN, CLASS_ELEMENTAL, ACTUAL_YES, BT_REAL, dr, GFC_STD_F77, gfc_check_fn_rc2008, gfc_simplify_atan, gfc_resolve_atan, x, BT_REAL, dr, REQUIRED); to add_sym_2 ("atan", GFC_ISYM_ATAN, CLASS_ELEMENTAL, ACTUAL_YES, BT_REAL, dr, GFC_STD_F77, gfc_check_atan, NULL, NULL, /* NULLs are temps */ y, BT_REAL, dr, OPTIONAL, x, BT_REAL, dr, REQUIRED); which compiles (with modifications to gfc_check_atan) but gfortran is not expecting an optional argument to occur before a required argument. This then caused gfortran to reject atan(1.) but accept atan(x=1.). Unfortunately, J3 defines atan(x) and atan(y,x). So, I think we need to have add_sym_2 ("atan", GFC_ISYM_ATAN, CLASS_ELEMENTAL, ACTUAL_YES, BT_REAL, dr, GFC_STD_F77, gfc_check_atan, NULL, NULL, /* NULLs are temps */ x, BT_REAL, dr, REQUIRED, y, BT_REAL, dr, OPTIONAL); If 'y' is non-null in gfc_check_atan(), then we'll need to swap the expressions for 'x' and 'y'. But, we'll need to be mindful of atan(y=0.5, x=1.) as these should be swapped. AFAIK, atan, atand, and atanpi need this treatment.