[flang-commits] [flang] ffc7f9d - [flang] Support external procedure passed as actual argument with implicit character type
via flang-commits
flang-commits at lists.llvm.org
Fri May 6 07:17:08 PDT 2022
Author: PeixinQiao
Date: 2022-05-06T22:14:51+08:00
New Revision: ffc7f9d542370eb72ad1f4bf79f763ca685bab8b
URL: https://github.com/llvm/llvm-project/commit/ffc7f9d542370eb72ad1f4bf79f763ca685bab8b
DIFF: https://github.com/llvm/llvm-project/commit/ffc7f9d542370eb72ad1f4bf79f763ca685bab8b.diff
LOG: [flang] Support external procedure passed as actual argument with implicit character type
As Fortran 2018 15.5.2.9 point 2, the actual argument and dummy argument
have the same type and type parameters and an external function with
assumed character length may be associated with a dummy argument with
explicit character length. As Fortran 2018 15.5.2.9 point 7, if an
external procedure is used as an actual argument, it can be explicitly
declared to have the EXTERNAL attribute. This supports the external
procedure passed as actual argument with implicit character type, either
explicit character length or assumed character length.
Reviewed By: Jean Perier, klausler
Differential Revision: https://reviews.llvm.org/D124345
Added:
flang/test/Lower/ext-proc-as-actual-argument-1.f90
flang/test/Lower/ext-proc-as-actual-argument-2.f90
Modified:
flang/include/flang/Optimizer/Builder/Character.h
flang/lib/Optimizer/Builder/Character.cpp
Removed:
################################################################################
diff --git a/flang/include/flang/Optimizer/Builder/Character.h b/flang/include/flang/Optimizer/Builder/Character.h
index e64a7044aec8c..8b952620d1fdd 100644
--- a/flang/include/flang/Optimizer/Builder/Character.h
+++ b/flang/include/flang/Optimizer/Builder/Character.h
@@ -204,8 +204,8 @@ class CharacterExprHelper {
mlir::Type getCharacterProcedureTupleType(mlir::Type funcPointerType);
/// Create a tuple<addr, len> given \p addr and \p len as well as the tuple
-/// type \p argTy. \p addr must be any function address, and \p len must be
-/// any integer. Converts will be inserted if needed if \addr and \p len
+/// type \p argTy. \p addr must be any function address, and \p len may be any
+/// integer or nullptr. Converts will be inserted if needed if \addr and \p len
/// types are not the same as the one inside the tuple type \p tupleType.
mlir::Value createCharacterProcedureTuple(fir::FirOpBuilder &builder,
mlir::Location loc,
diff --git a/flang/lib/Optimizer/Builder/Character.cpp b/flang/lib/Optimizer/Builder/Character.cpp
index 4a90a697aca51..c025270cf83ea 100644
--- a/flang/lib/Optimizer/Builder/Character.cpp
+++ b/flang/lib/Optimizer/Builder/Character.cpp
@@ -718,7 +718,10 @@ mlir::Value fir::factory::createCharacterProcedureTuple(
mlir::Value addr, mlir::Value len) {
mlir::TupleType tupleType = argTy.cast<mlir::TupleType>();
addr = builder.createConvert(loc, tupleType.getType(0), addr);
- len = builder.createConvert(loc, tupleType.getType(1), len);
+ if (len)
+ len = builder.createConvert(loc, tupleType.getType(1), len);
+ else
+ len = builder.create<fir::UndefOp>(loc, tupleType.getType(1));
mlir::Value tuple = builder.create<fir::UndefOp>(loc, tupleType);
tuple = builder.create<fir::InsertValueOp>(
loc, tupleType, tuple, addr,
diff --git a/flang/test/Lower/ext-proc-as-actual-argument-1.f90 b/flang/test/Lower/ext-proc-as-actual-argument-1.f90
new file mode 100644
index 0000000000000..e121a82a3e021
--- /dev/null
+++ b/flang/test/Lower/ext-proc-as-actual-argument-1.f90
@@ -0,0 +1,31 @@
+! RUN: bbc -emit-fir %s -o - | FileCheck %s
+
+! Test external procedure as actual argument with the implicit character type.
+
+! CHECK-LABEL: func @_QQmain
+! CHECK: %[[VAL_0:.*]] = fir.address_of(@_QPext_func) : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
+! CHECK: %[[VAL_1:.*]] = fir.emboxproc %[[VAL_0]] : ((!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>) -> !fir.boxproc<() -> ()>
+! CHECK: %[[VAL_2:.*]] = fir.undefined i64
+! CHECK: %[[VAL_3:.*]] = fir.undefined tuple<!fir.boxproc<() -> ()>, i64>
+! CHECK: %[[VAL_4:.*]] = fir.insert_value %[[VAL_3]], %[[VAL_1]], [0 : index] : (tuple<!fir.boxproc<() -> ()>, i64>, !fir.boxproc<() -> ()>) -> tuple<!fir.boxproc<() -> ()>, i64>
+! CHECK: %[[VAL_5:.*]] = fir.insert_value %[[VAL_4]], %[[VAL_2]], [1 : index] : (tuple<!fir.boxproc<() -> ()>, i64>, i64) -> tuple<!fir.boxproc<() -> ()>, i64>
+! CHECK: fir.call @_QFPsub(%[[VAL_5]]) : (tuple<!fir.boxproc<() -> ()>, i64>) -> ()
+! CHECK: return
+
+! CHECK-LABEL: func @_QPext_func(
+! CEHCK: %[[ARG_0:.*]]: !fir.ref<!fir.char<1,?>>, %[[ARG_1:.*]]: index) -> !fir.boxchar<1> {
+program m
+ external :: ext_func
+ call sub(ext_func)
+
+contains
+ subroutine sub(arg)
+ character(20), external :: arg
+ print *, arg()
+ end
+end
+
+function ext_func() result(res)
+ character(*) res
+ res = "hello world"
+end
diff --git a/flang/test/Lower/ext-proc-as-actual-argument-2.f90 b/flang/test/Lower/ext-proc-as-actual-argument-2.f90
new file mode 100644
index 0000000000000..8c04e8617f49e
--- /dev/null
+++ b/flang/test/Lower/ext-proc-as-actual-argument-2.f90
@@ -0,0 +1,31 @@
+! RUN: bbc -emit-fir %s -o - | FileCheck %s
+
+! Test external procedure as actual argument with the implicit character type.
+
+! CHECK-LABEL: func @_QQmain
+! CHECK: %[[VAL_0:.*]] = fir.address_of(@_QPext_func) : (!fir.ref<!fir.char<1,20>>, index) -> !fir.boxchar<1>
+! CHECK: %[[VAL_1:.*]] = fir.emboxproc %[[VAL_0]] : ((!fir.ref<!fir.char<1,20>>, index) -> !fir.boxchar<1>) -> !fir.boxproc<() -> ()>
+! CHECK: %[[VAL_2:.*]] = fir.undefined i64
+! CHECK: %[[VAL_3:.*]] = fir.undefined tuple<!fir.boxproc<() -> ()>, i64>
+! CHECK: %[[VAL_4:.*]] = fir.insert_value %[[VAL_3]], %[[VAL_1]], [0 : index] : (tuple<!fir.boxproc<() -> ()>, i64>, !fir.boxproc<() -> ()>) -> tuple<!fir.boxproc<() -> ()>, i64>
+! CHECK: %[[VAL_5:.*]] = fir.insert_value %[[VAL_4]], %[[VAL_2]], [1 : index] : (tuple<!fir.boxproc<() -> ()>, i64>, i64) -> tuple<!fir.boxproc<() -> ()>, i64>
+! CHECK: fir.call @_QFPsub(%[[VAL_5]]) : (tuple<!fir.boxproc<() -> ()>, i64>) -> ()
+! CHECK: return
+
+! CHECK-LABEL: func @_QPext_func(
+! CEHCK: %[[ARG_0:.*]]: !fir.ref<!fir.char<1,20>>, %[[ARG_1:.*]]: index) -> !fir.boxchar<1> {
+program m
+ external :: ext_func
+ call sub(ext_func)
+
+contains
+ subroutine sub(arg)
+ character(20), external :: arg
+ print *, arg()
+ end
+end
+
+function ext_func() result(res)
+ character(20) res
+ res = "hello world"
+end
More information about the flang-commits
mailing list