Index: flang/lib/Evaluate/intrinsics.cpp =================================================================== --- flang/lib/Evaluate/intrinsics.cpp +++ flang/lib/Evaluate/intrinsics.cpp @@ -859,10 +859,9 @@ // Tables 16.2 and 16.3 in Fortran 2018. The "unrestricted" functions // in Table 16.2 can be used as actual arguments, PROCEDURE() interfaces, // and procedure pointer targets. -// Note that the restricted conversion functions dcmplx, dreal, float, idint, -// ifix, and sngl are extended to accept any argument kind because this is a -// common Fortran compilers behavior, and as far as we can tell, is safe and -// useful. +// Note that the restricted conversion functions dcmplx, float, idint, ifix, and +// sngl are extended to accept any argument kind because this is a common +// Fortran compilers behavior, and as far as we can tell, is safe and useful. struct SpecificIntrinsicInterface : public IntrinsicInterface { const char *generic{nullptr}; bool isRestrictedSpecific{false}; @@ -955,7 +954,8 @@ {"y", AnyIntOrReal, Rank::elementalOrBOZ, Optionality::optional}}, DoublePrecisionComplex}, "cmplx", true}, - {{"dconjg", {{"z", AnyComplex}}, DoublePrecisionComplex}, "conjg"}, + {{"dconjg", {{"z", DoublePrecisionComplex}}, DoublePrecisionComplex}, + "conjg", true}, {{"dcos", {{"x", DoublePrecision}}, DoublePrecision}, "cos"}, {{"dcosh", {{"x", DoublePrecision}}, DoublePrecision}, "cosh"}, {{"ddim", {{"x", DoublePrecision}, {"y", DoublePrecision}}, @@ -964,7 +964,8 @@ {{"dexp", {{"x", DoublePrecision}}, DoublePrecision}, "exp"}, {{"dfloat", {{"a", AnyInt}}, DoublePrecision}, "real", true}, {{"dim", {{"x", DefaultReal}, {"y", DefaultReal}}, DefaultReal}}, - {{"dimag", {{"z", AnyComplex}}, DoublePrecision}, "aimag"}, + {{"dimag", {{"z", DoublePrecisionComplex}}, DoublePrecision}, "aimag", + true}, {{"dint", {{"a", DoublePrecision}}, DoublePrecision}, "aint"}, {{"dlog", {{"x", DoublePrecision}}, DoublePrecision}, "log"}, {{"dlog10", {{"x", DoublePrecision}}, DoublePrecision}, "log10"}, @@ -983,7 +984,7 @@ "mod"}, {{"dnint", {{"a", DoublePrecision}}, DoublePrecision}, "anint"}, {{"dprod", {{"x", DefaultReal}, {"y", DefaultReal}}, DoublePrecision}}, - {{"dreal", {{"a", AnyComplex}}, DoublePrecision}, "real", true}, + {{"dreal", {{"a", DoublePrecisionComplex}}, DoublePrecision}, "real", true}, {{"dsign", {{"a", DoublePrecision}, {"b", DoublePrecision}}, DoublePrecision}, "sign"}, Index: flang/test/Lower/intrinsics-1.f90 =================================================================== --- /dev/null +++ flang/test/Lower/intrinsics-1.f90 @@ -0,0 +1,31 @@ +! Test intrinsics DREAL, DIMAG, DCONJG +! RUN: bbc -emit-fir %s -o - | FileCheck %s + +subroutine test_dreal_dimag_dconjg(r1, r2, r3, c) + real(8), intent(out) :: r1, r2 + complex(8), intent(out) :: r3 + complex(8), intent(in) :: c + +! CHECK-LABEL: func @_QPtest_dreal_dimag_dconjg( +! CHECK-SAME: %[[ARG_0:.*]]: !fir.ref {fir.bindc_name = "r1"}, +! CHECK-SAME: %[[ARG_1:.*]]: !fir.ref {fir.bindc_name = "r2"}, +! CHECK-SAME: %[[ARG_2:.*]]: !fir.ref> {fir.bindc_name = "r3"}, +! CHECK-SAME: %[[ARG_3:.*]]: !fir.ref> {fir.bindc_name = "c"}) { +! CHECK: %[[VAL_0:.*]] = fir.load %[[ARG_3]] : !fir.ref> +! CHECK: %[[VAL_1:.*]] = fir.extract_value %[[VAL_0]], [0 : index] : (!fir.complex<8>) -> f64 +! CHECK: fir.store %[[VAL_1]] to %[[ARG_0]] : !fir.ref +! CHECK: %[[VAL_2:.*]] = fir.load %[[ARG_3]] : !fir.ref> +! CHECK: %[[VAL_3:.*]] = fir.extract_value %[[VAL_2]], [1 : index] : (!fir.complex<8>) -> f64 +! CHECK: fir.store %[[VAL_3]] to %[[ARG_1]] : !fir.ref +! CHECK: %[[VAL_4:.*]] = fir.load %[[ARG_3]] : !fir.ref> +! CHECK: %[[VAL_5:.*]] = fir.extract_value %[[VAL_4]], [1 : index] : (!fir.complex<8>) -> f64 +! CHECK: %[[VAL_6:.*]] = arith.negf %[[VAL_5]] : f64 +! CHECK: %[[VAL_7:.*]] = fir.insert_value %[[VAL_4]], %[[VAL_6]], [1 : index] : (!fir.complex<8>, f64) -> !fir.complex<8> +! CHECK: fir.store %[[VAL_7]] to %[[ARG_2]] : !fir.ref> +! CHECK: return +! CHECK: } + + r1 = dreal(c) + r2 = dimag(c) + r3 = dconjg(c) +end Index: flang/test/Semantics/intrinsics01.f90 =================================================================== --- /dev/null +++ flang/test/Semantics/intrinsics01.f90 @@ -0,0 +1,43 @@ +! RUN: %python %S/test_errors.py %s %flang_fc1 +! Check for semantic errors for DREAL, DIMAG, DCONJG intrinsics + +subroutine s() + real :: a + complex(4) :: c4 ! test scalar + complex(8) :: c8 + complex(16) :: c16(2) ! test array + + !ERROR: Actual argument for 'a=' has bad type 'REAL(4)' + print *, dreal(a) + + !ERROR: Actual argument for 'a=' has bad type or kind 'COMPLEX(4)' + print *, dreal(c4) + + print *, dreal(c8) + + !ERROR: Actual argument for 'a=' has bad type or kind 'COMPLEX(16)' + print *, dreal(c16) + + !ERROR: Actual argument for 'z=' has bad type 'REAL(4)' + print *, dimag(a) + + !ERROR: Actual argument for 'z=' has bad type or kind 'COMPLEX(4)' + print *, dimag(c4) + + print *, dimag(c8) + + !ERROR: Actual argument for 'z=' has bad type or kind 'COMPLEX(16)' + print *, dimag(c16) + + !ERROR: Actual argument for 'z=' has bad type 'REAL(4)' + print *, dconjg(a) + + !ERROR: Actual argument for 'z=' has bad type or kind 'COMPLEX(4)' + print *, dconjg(c4) + + print *, dconjg(c8) + + !ERROR: Actual argument for 'z=' has bad type or kind 'COMPLEX(16)' + print *, dconjg(c16) + +end subroutine Index: flang/unittests/Evaluate/intrinsics.cpp =================================================================== --- flang/unittests/Evaluate/intrinsics.cpp +++ flang/unittests/Evaluate/intrinsics.cpp @@ -237,9 +237,6 @@ TestCall{defaults, table, "conjg"} .Push(Const(Scalar{})) .DoCall(Complex8::GetType()); - TestCall{defaults, table, "dconjg"} - .Push(Const(Scalar{})) - .DoCall(Complex8::GetType()); TestCall{defaults, table, "dconjg"} .Push(Const(Scalar{})) .DoCall(Complex8::GetType());