@@ -207,34 +207,37 @@ static bool hasExplicitLowerBounds(mlir::Value shape) {
207207 mlir::isa<fir::ShapeShiftType, fir::ShiftType>(shape.getType ());
208208}
209209
210- static std::pair<mlir::Type, mlir::Value> updateDeclaredInputTypeWithVolatility (
211- mlir::Type inputType, mlir::Value memref, mlir::OpBuilder &builder,
212- fir::FortranVariableFlagsAttr fortran_attrs) {
213- if (fortran_attrs &&
214- bitEnumContainsAny (fortran_attrs.getFlags (),
215- fir::FortranVariableFlagsEnum::fortran_volatile)) {
216- // A volatile pointer's pointee is volatile.
217- const bool isPointer = bitEnumContainsAny (
218- fortran_attrs.getFlags (), fir::FortranVariableFlagsEnum::pointer);
219- // An allocatable's inner type's volatility matches that of the reference.
220- const bool isAllocatable = bitEnumContainsAny (
221- fortran_attrs.getFlags (), fir::FortranVariableFlagsEnum::allocatable);
222- auto updateType = [&](auto t) {
223- using FIRT = decltype (t);
224- auto elementType = t.getEleTy ();
225- const bool elementTypeIsBox = mlir::isa<fir::BoxType>(elementType);
226- const bool elementTypeIsVolatile = isPointer || isAllocatable ||
227- elementTypeIsBox ||
228- fir::isa_volatile_type (elementType);
229- auto newEleTy =
230- fir::updateTypeWithVolatility (elementType, elementTypeIsVolatile);
231- inputType = FIRT::get (newEleTy, true );
232- };
233- llvm::TypeSwitch<mlir::Type>(inputType)
234- .Case <fir::ReferenceType, fir::BoxType, fir::ClassType>(updateType);
235- memref =
236- builder.create <fir::VolatileCastOp>(memref.getLoc (), inputType, memref);
210+ static std::pair<mlir::Type, mlir::Value>
211+ updateDeclaredInputTypeWithVolatility (mlir::Type inputType, mlir::Value memref,
212+ mlir::OpBuilder &builder,
213+ fir::FortranVariableFlagsEnum flags) {
214+ if (!bitEnumContainsAny (flags,
215+ fir::FortranVariableFlagsEnum::fortran_volatile)) {
216+ return std::make_pair (inputType, memref);
237217 }
218+
219+ // A volatile pointer's pointee is volatile.
220+ const bool isPointer =
221+ bitEnumContainsAny (flags, fir::FortranVariableFlagsEnum::pointer);
222+ // An allocatable's inner type's volatility matches that of the reference.
223+ const bool isAllocatable =
224+ bitEnumContainsAny (flags, fir::FortranVariableFlagsEnum::allocatable);
225+
226+ auto updateType = [&](auto t) {
227+ using FIRT = decltype (t);
228+ auto elementType = t.getEleTy ();
229+ const bool elementTypeIsBox = mlir::isa<fir::BaseBoxType>(elementType);
230+ const bool elementTypeIsVolatile = isPointer || isAllocatable ||
231+ elementTypeIsBox ||
232+ fir::isa_volatile_type (elementType);
233+ auto newEleTy =
234+ fir::updateTypeWithVolatility (elementType, elementTypeIsVolatile);
235+ inputType = FIRT::get (newEleTy, true );
236+ };
237+ llvm::TypeSwitch<mlir::Type>(inputType)
238+ .Case <fir::ReferenceType, fir::BoxType, fir::ClassType>(updateType);
239+ memref =
240+ builder.create <fir::VolatileCastOp>(memref.getLoc (), inputType, memref);
238241 return std::make_pair (inputType, memref);
239242}
240243
@@ -248,8 +251,11 @@ void hlfir::DeclareOp::build(mlir::OpBuilder &builder,
248251 auto nameAttr = builder.getStringAttr (uniq_name);
249252 mlir::Type inputType = memref.getType ();
250253 bool hasExplicitLbs = hasExplicitLowerBounds (shape);
251- std::tie (inputType, memref) = updateDeclaredInputTypeWithVolatility (
252- inputType, memref, builder, fortran_attrs);
254+ if (fortran_attrs) {
255+ const auto flags = fortran_attrs.getFlags ();
256+ std::tie (inputType, memref) = updateDeclaredInputTypeWithVolatility (
257+ inputType, memref, builder, flags);
258+ }
253259 mlir::Type hlfirVariableType =
254260 getHLFIRVariableType (inputType, hasExplicitLbs);
255261 build (builder, result, {hlfirVariableType, inputType}, memref, shape,
0 commit comments