summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--flang/lib/Lower/Bridge.cpp14
-rw-r--r--flang/test/Lower/HLFIR/function-return.f9026
2 files changed, 40 insertions, 0 deletions
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 875f8624e448..19ae9576dfac 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -857,6 +857,20 @@ private:
},
[](auto x) -> Fortran::lower::SymbolBox { return x; });
}
+
+ // Entry character result represented as an argument pair
+ // needs to be represented in the symbol table even before
+ // we can create DeclareOp for it. The temporary mapping
+ // is EmboxCharOp that conveys the address and length information.
+ // After mapSymbolAttributes is done, the mapping is replaced
+ // with the new DeclareOp, and the following table lookups
+ // do not reach here.
+ if (sym.IsFuncResult())
+ if (const Fortran::semantics::DeclTypeSpec *declTy = sym.GetType())
+ if (declTy->category() ==
+ Fortran::semantics::DeclTypeSpec::Category::Character)
+ return symMap->lookupSymbol(sym);
+
// Procedure dummies are not mapped with an hlfir.declare because
// they are not "variable" (cannot be assigned to), and it would
// make hlfir.declare more complex than it needs to to allow this.
diff --git a/flang/test/Lower/HLFIR/function-return.f90 b/flang/test/Lower/HLFIR/function-return.f90
index dbabb0597ab6..a4ceed55d335 100644
--- a/flang/test/Lower/HLFIR/function-return.f90
+++ b/flang/test/Lower/HLFIR/function-return.f90
@@ -42,3 +42,29 @@ end function
! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_2]]{{.*}} {uniq_name = "_QFchar_array_returnEchar_array_return"} : (!fir.ref<!fir.array<10x!fir.char<1,5>>>, !fir.shape<1>, index) -> (!fir.ref<!fir.array<10x!fir.char<1,5>>>, !fir.ref<!fir.array<10x!fir.char<1,5>>>)
! CHECK: %[[VAL_5:.*]] = fir.load %[[VAL_4]]#1 : !fir.ref<!fir.array<10x!fir.char<1,5>>>
! CHECK: return %[[VAL_5]] : !fir.array<10x!fir.char<1,5>>
+
+character*(*) function char_var_len_return()
+ character*(*) char_var_len_return2
+ entry char_var_len_return2
+end function char_var_len_return
+! CHECK-LABEL: func.func @_QPchar_var_len_return(
+! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.char<1,?>>,
+! CHECK-SAME: %[[VAL_1:.*]]: index) -> !fir.boxchar<1> {
+! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_0]] typeparams %[[VAL_1]] {uniq_name = "_QFchar_var_len_returnEchar_var_len_return"} : (!fir.ref<!fir.char<1,?>>, index) -> (!fir.boxchar<1>, !fir.ref<!fir.char<1,?>>)
+! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_0]] typeparams %[[VAL_1]] {uniq_name = "_QFchar_var_len_returnEchar_var_len_return2"} : (!fir.ref<!fir.char<1,?>>, index) -> (!fir.boxchar<1>, !fir.ref<!fir.char<1,?>>)
+! CHECK: cf.br ^bb1
+! CHECK: ^bb1:
+! CHECK: %[[VAL_4:.*]] = fir.emboxchar %[[VAL_2]]#1, %[[VAL_1]] : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
+! CHECK: return %[[VAL_4]] : !fir.boxchar<1>
+! CHECK: }
+
+! CHECK-LABEL: func.func @_QPchar_var_len_return2(
+! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.char<1,?>>,
+! CHECK-SAME: %[[VAL_1:.*]]: index) -> !fir.boxchar<1> {
+! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_0]] typeparams %[[VAL_1]] {uniq_name = "_QFchar_var_len_returnEchar_var_len_return"} : (!fir.ref<!fir.char<1,?>>, index) -> (!fir.boxchar<1>, !fir.ref<!fir.char<1,?>>)
+! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_0]] typeparams %[[VAL_1]] {uniq_name = "_QFchar_var_len_returnEchar_var_len_return2"} : (!fir.ref<!fir.char<1,?>>, index) -> (!fir.boxchar<1>, !fir.ref<!fir.char<1,?>>)
+! CHECK: cf.br ^bb1
+! CHECK: ^bb1:
+! CHECK: %[[VAL_4:.*]] = fir.emboxchar %[[VAL_3]]#1, %[[VAL_1]] : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
+! CHECK: return %[[VAL_4]] : !fir.boxchar<1>
+! CHECK: }