diff --git a/flang/lib/Optimizer/Dialect/FIROps.cpp b/flang/lib/Optimizer/Dialect/FIROps.cpp index 6443d5c6eca4..4b863f9b8734 100644 --- a/flang/lib/Optimizer/Dialect/FIROps.cpp +++ b/flang/lib/Optimizer/Dialect/FIROps.cpp @@ -3122,11 +3122,13 @@ mlir::LogicalResult fir::StoreOp::verify() { // StringLitOp //===----------------------------------------------------------------------===// -bool fir::StringLitOp::isWideValue() { - auto eleTy = getType().cast().getEleTy(); - return eleTy.cast().getFKind() != 1; +inline fir::CharacterType::KindTy stringLitOpGetKind(fir::StringLitOp op) { + auto eleTy = op.getType().cast().getEleTy(); + return eleTy.cast().getFKind(); } +bool fir::StringLitOp::isWideValue() { return stringLitOpGetKind(*this) != 1; } + static mlir::NamedAttribute mkNamedIntegerAttr(mlir::OpBuilder &builder, llvm::StringRef name, int64_t v) { assert(v > 0); @@ -3205,6 +3207,9 @@ mlir::ParseResult fir::StringLitOp::parse(mlir::OpAsmParser &parser, if (auto v = val.dyn_cast()) result.attributes.push_back( builder.getNamedAttr(fir::StringLitOp::value(), v)); + else if (auto v = val.dyn_cast()) + result.attributes.push_back( + builder.getNamedAttr(fir::StringLitOp::xlist(), v)); else if (auto v = val.dyn_cast()) result.attributes.push_back( builder.getNamedAttr(fir::StringLitOp::xlist(), v)); @@ -3238,10 +3243,15 @@ mlir::LogicalResult fir::StringLitOp::verify() { if (getSize().cast().getValue().isNegative()) return emitOpError("size must be non-negative"); if (auto xl = getOperation()->getAttr(fir::StringLitOp::xlist())) { - auto xList = xl.cast(); - for (auto a : xList) - if (!a.isa()) - return emitOpError("values in list must be integers"); + if (auto xList = xl.dyn_cast()) { + for (auto a : xList) + if (!a.isa()) + return emitOpError("values in initializer must be integers"); + } else if (xl.isa()) { + // do nothing + } else { + return emitOpError("has unexpected attribute"); + } } return mlir::success(); } diff --git a/flang/test/Fir/invalid.fir b/flang/test/Fir/invalid.fir index 8d2a68fad87a..ee384fc4a5af 100644 --- a/flang/test/Fir/invalid.fir +++ b/flang/test/Fir/invalid.fir @@ -12,7 +12,7 @@ // ----- -// expected-error@+1{{'fir.string_lit' op values in list must be integers}} +// expected-error@+1{{'fir.string_lit' op values in initializer must be integers}} %2 = fir.string_lit [158, 2.0](2) : !fir.char<2> // ----- diff --git a/flang/test/Lower/array-wide-char.f90 b/flang/test/Lower/array-wide-char.f90 new file mode 100644 index 000000000000..43d9e9d546bd --- /dev/null +++ b/flang/test/Lower/array-wide-char.f90 @@ -0,0 +1,30 @@ +! RUN: bbc %s -o - | tco | FileCheck %s + +character(LEN=128, KIND=4), PARAMETER :: conarr(3) = & + [ character(128,4) :: "now is the time", "for all good men to come", & + "to the aid of the country" ] +character(LEN=10, KIND=4) :: arr(3) = & + [ character(10,4) :: "good buddy", "best buddy", " " ] +call action_on_char4(conarr) +call action_on_char4(arr) +end program + +subroutine sub1 + integer, parameter :: k = 4 + character(63,k), parameter :: wiggle = k_"wiggle" + call sub2(wiggle) +end subroutine sub1 + +! CHECK-LABEL: @_QFEarr = internal global [3 x [10 x i32]] [ +! CHECK-SAME: [10 x i32] [i32 103, i32 111, i32 111, i32 100, i32 32, i32 98, i32 117, i32 100, i32 100, i32 121], +! CHECK-SAME: [10 x i32] [i32 98, i32 101, i32 115, i32 116, i32 32, i32 98, i32 117, i32 100, i32 100, i32 121], +! CHECK-SAME: [10 x i32] [i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 32]] +! CHECK-LABEL: @_QFsub1ECwiggle = internal constant [63 x i32] [i32 119, +! CHECK-SAME: i32 105, i32 103, i32 103, i32 108, i32 101, i32 32, i32 32, +! CHECK: @_QQcl[[inline:.*]] = linkonce constant [63 x i32] [i32 119, i32 105, i32 103, i32 103, i32 108, i32 101, i32 32, + +! CHECK-LABEL: define void @_QQmain() +! CHECK: call void @_QPaction_on_char4(ptr @_QFEarr, i64 10) + +! CHECK-LABEL: define void @_QPsub1( +! CHECK: call void @_QPsub2(ptr @_QQcl.77, i64 63)