@@ -180,26 +180,46 @@ void hlfir::AssignOp::getEffects(
180
180
// DeclareOp
181
181
// ===----------------------------------------------------------------------===//
182
182
183
- // / Given a FIR memory type, and information about non default lower bounds, get
184
- // / the related HLFIR variable type.
185
- mlir::Type hlfir::DeclareOp::getHLFIRVariableType (mlir::Type inputType,
186
- bool hasExplicitLowerBounds) {
183
+ static std::pair<mlir::Type, mlir::Type>
184
+ getDeclareOutputTypes (mlir::Type inputType, bool hasExplicitLowerBounds) {
185
+ // Drop pointer/allocatable attribute of descriptor values. Only descriptor
186
+ // addresses are ALLOCATABLE/POINTER. The HLFIR box result of an hlfir.declare
187
+ // without those attributes should not have these attributes set.
188
+ if (auto baseBoxType = mlir::dyn_cast<fir::BaseBoxType>(inputType))
189
+ if (baseBoxType.isPointerOrAllocatable ()) {
190
+ mlir::Type boxWithoutAttributes =
191
+ baseBoxType.getBoxTypeWithNewAttr (fir::BaseBoxType::Attribute::None);
192
+ return {boxWithoutAttributes, boxWithoutAttributes};
193
+ }
187
194
mlir::Type type = fir::unwrapRefType (inputType);
188
195
if (mlir::isa<fir::BaseBoxType>(type))
189
- return inputType;
196
+ return { inputType, inputType} ;
190
197
if (auto charType = mlir::dyn_cast<fir::CharacterType>(type))
191
- if (charType.hasDynamicLen ())
192
- return fir::BoxCharType::get (charType.getContext (), charType.getFKind ());
198
+ if (charType.hasDynamicLen ()) {
199
+ mlir::Type hlfirType =
200
+ fir::BoxCharType::get (charType.getContext (), charType.getFKind ());
201
+ return {hlfirType, inputType};
202
+ }
193
203
194
204
auto seqType = mlir::dyn_cast<fir::SequenceType>(type);
195
205
bool hasDynamicExtents =
196
206
seqType && fir::sequenceWithNonConstantShape (seqType);
197
207
mlir::Type eleType = seqType ? seqType.getEleTy () : type;
198
208
bool hasDynamicLengthParams = fir::characterWithDynamicLen (eleType) ||
199
209
fir::isRecordWithTypeParameters (eleType);
200
- if (hasExplicitLowerBounds || hasDynamicExtents || hasDynamicLengthParams)
201
- return fir::BoxType::get (type, fir::isa_volatile_type (inputType));
202
- return inputType;
210
+ if (hasExplicitLowerBounds || hasDynamicExtents || hasDynamicLengthParams) {
211
+ mlir::Type boxType =
212
+ fir::BoxType::get (type, fir::isa_volatile_type (inputType));
213
+ return {boxType, inputType};
214
+ }
215
+ return {inputType, inputType};
216
+ }
217
+
218
+ // / Given a FIR memory type, and information about non default lower bounds, get
219
+ // / the related HLFIR variable type.
220
+ mlir::Type hlfir::DeclareOp::getHLFIRVariableType (mlir::Type inputType,
221
+ bool hasExplicitLowerBounds) {
222
+ return getDeclareOutputTypes (inputType, hasExplicitLowerBounds).first ;
203
223
}
204
224
205
225
static bool hasExplicitLowerBounds (mlir::Value shape) {
@@ -256,17 +276,18 @@ void hlfir::DeclareOp::build(mlir::OpBuilder &builder,
256
276
std::tie (inputType, memref) = updateDeclaredInputTypeWithVolatility (
257
277
inputType, memref, builder, flags);
258
278
}
259
- mlir::Type hlfirVariableType =
260
- getHLFIRVariableType (inputType, hasExplicitLbs);
261
- build (builder, result, {hlfirVariableType, inputType }, memref, shape,
279
+ auto [ hlfirVariableType, firVarType] =
280
+ getDeclareOutputTypes (inputType, hasExplicitLbs);
281
+ build (builder, result, {hlfirVariableType, firVarType }, memref, shape,
262
282
typeparams, dummy_scope, nameAttr, fortran_attrs, data_attr);
263
283
}
264
284
265
285
llvm::LogicalResult hlfir::DeclareOp::verify () {
266
- if (getMemref ().getType () != getResult (1 ).getType ())
267
- return emitOpError (" second result type must match input memref type" );
268
- mlir::Type hlfirVariableType = getHLFIRVariableType (
286
+ auto [hlfirVariableType, firVarType] = getDeclareOutputTypes (
269
287
getMemref ().getType (), hasExplicitLowerBounds (getShape ()));
288
+ if (firVarType != getResult (1 ).getType ())
289
+ return emitOpError (" second result type must match input memref type, "
290
+ " unless it is a box with heap or pointer attribute" );
270
291
if (hlfirVariableType != getResult (0 ).getType ())
271
292
return emitOpError (" first result type is inconsistent with variable "
272
293
" properties: expected " )
@@ -1608,7 +1629,7 @@ void hlfir::AssociateOp::build(
1608
1629
mlir::Type firVarType;
1609
1630
auto sourceExprType = mlir::dyn_cast<hlfir::ExprType>(source.getType ());
1610
1631
if (sourceExprType && sourceExprType.isPolymorphic ())
1611
- firVarType = fir::ClassType::get (fir::HeapType::get ( dataType) );
1632
+ firVarType = fir::ClassType::get (dataType);
1612
1633
else
1613
1634
firVarType = fir::ReferenceType::get (dataType);
1614
1635
0 commit comments