From 4eab303404d6bb2252b4baf807c5ac87a0fa3125 Mon Sep 17 00:00:00 2001 From: Slava Zakharin Date: Tue, 16 May 2023 20:05:22 -0700 Subject: [flang][hlfir] Fixed symbol lookup for character returns. Symbols corresponding to entries returning character results must be mapped to EmboxCharOp, first, before we can map them to DeclareOp. The code may be reworked after HLFIR is enabled by default, but right now it seems like an acceptable solution to me. Differential Revision: https://reviews.llvm.org/D150749 --- flang/lib/Lower/Bridge.cpp | 14 ++++++++++++++ flang/test/Lower/HLFIR/function-return.f90 | 26 ++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) (limited to 'flang') 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.shape<1>, index) -> (!fir.ref>>, !fir.ref>>) ! CHECK: %[[VAL_5:.*]] = fir.load %[[VAL_4]]#1 : !fir.ref>> ! 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>, +! 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>, index) -> (!fir.boxchar<1>, !fir.ref>) +! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_0]] typeparams %[[VAL_1]] {uniq_name = "_QFchar_var_len_returnEchar_var_len_return2"} : (!fir.ref>, index) -> (!fir.boxchar<1>, !fir.ref>) +! CHECK: cf.br ^bb1 +! CHECK: ^bb1: +! CHECK: %[[VAL_4:.*]] = fir.emboxchar %[[VAL_2]]#1, %[[VAL_1]] : (!fir.ref>, 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>, +! 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>, index) -> (!fir.boxchar<1>, !fir.ref>) +! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_0]] typeparams %[[VAL_1]] {uniq_name = "_QFchar_var_len_returnEchar_var_len_return2"} : (!fir.ref>, index) -> (!fir.boxchar<1>, !fir.ref>) +! CHECK: cf.br ^bb1 +! CHECK: ^bb1: +! CHECK: %[[VAL_4:.*]] = fir.emboxchar %[[VAL_3]]#1, %[[VAL_1]] : (!fir.ref>, index) -> !fir.boxchar<1> +! CHECK: return %[[VAL_4]] : !fir.boxchar<1> +! CHECK: } -- cgit v1.2.1