diff --git a/flang/docs/Extensions.md b/flang/docs/Extensions.md index c1591eb49732b..480039911719c 100644 --- a/flang/docs/Extensions.md +++ b/flang/docs/Extensions.md @@ -101,6 +101,8 @@ end * `$` and `@` as legal characters in names * Initialization in type declaration statements using `/values/` * Saved variables without explicit or default initializers are zero initialized. +* In a saved entity of a type with a default initializer, components without default + values are zero initialized. * Kind specification with `*`, e.g. `REAL*4` * `DOUBLE COMPLEX` as a synonym for `COMPLEX(KIND(0.D0))` -- but not when spelled `TYPE(DOUBLECOMPLEX)`. diff --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp index 87b570d1ac4b7..74e07ec77c0cb 100644 --- a/flang/lib/Lower/ConvertVariable.cpp +++ b/flang/lib/Lower/ConvertVariable.cpp @@ -352,8 +352,9 @@ static mlir::Value genDefaultInitializerValue( componentValue = genDefaultInitializerValue(converter, loc, component, componentTy, stmtCtx); } else { - // Component has no initial value. - componentValue = builder.create(loc, componentTy); + // Component has no initial value. Set its bits to zero by extension + // to match what is expected because other compilers are doing it. + componentValue = builder.create(loc, componentTy); } } else if (const auto *proc{ component @@ -361,7 +362,7 @@ static mlir::Value genDefaultInitializerValue( if (proc->init().has_value()) TODO(loc, "procedure pointer component default initialization"); else - componentValue = builder.create(loc, componentTy); + componentValue = builder.create(loc, componentTy); } assert(componentValue && "must have been computed"); componentValue = builder.createConvert(loc, componentTy, componentValue); @@ -890,7 +891,7 @@ static fir::GlobalOp defineGlobalAggregateStore( Fortran::lower::createGlobalInitialization( builder, global, [&](fir::FirOpBuilder &builder) { Fortran::lower::StatementContext stmtCtx; - mlir::Value initVal = builder.create(loc, aggTy); + mlir::Value initVal = builder.create(loc, aggTy); builder.create(loc, initVal); }); return global; @@ -1171,7 +1172,7 @@ static void finalizeCommonBlockDefinition( mlir::TupleType commonTy = global.getType().cast(); auto initFunc = [&](fir::FirOpBuilder &builder) { mlir::IndexType idxTy = builder.getIndexType(); - mlir::Value cb = builder.create(loc, commonTy); + mlir::Value cb = builder.create(loc, commonTy); unsigned tupIdx = 0; std::size_t offset = 0; LLVM_DEBUG(llvm::dbgs() << "block {\n"); diff --git a/flang/test/Lower/array.f90 b/flang/test/Lower/array.f90 index e6e1286285838..3371887d04127 100644 --- a/flang/test/Lower/array.f90 +++ b/flang/test/Lower/array.f90 @@ -4,7 +4,7 @@ ! CHECK-DAG: %[[VAL_1:.*]] = arith.constant 1.000000e+00 : f32 ! CHECK-DAG: %[[VAL_2:.*]] = arith.constant 2.400000e+00 : f32 ! CHECK-DAG: %[[VAL_3:.*]] = arith.constant 0.000000e+00 : f32 -! CHECK: %[[VAL_4:.*]] = fir.undefined tuple> +! CHECK: %[[VAL_4:.*]] = fir.zero_bits tuple> ! CHECK: %[[VAL_5:.*]] = fir.undefined !fir.array<5x5xf32> ! CHECK: %[[VAL_6:.*]] = fir.insert_on_range %[[VAL_5]], %[[VAL_1]] from (0, 0) to (1, 0) : (!fir.array<5x5xf32>, f32) -> !fir.array<5x5xf32> ! CHECK: %[[VAL_7:.*]] = fir.insert_on_range %[[VAL_6]], %[[VAL_3]] from (2, 0) to (4, 0) : (!fir.array<5x5xf32>, f32) -> !fir.array<5x5xf32> diff --git a/flang/test/Lower/common-block-2.f90 b/flang/test/Lower/common-block-2.f90 index 31916f4be9fcb..4b12860a48ffa 100644 --- a/flang/test/Lower/common-block-2.f90 +++ b/flang/test/Lower/common-block-2.f90 @@ -6,12 +6,12 @@ ! - A common block that is initialized outside of a BLOCK DATA. ! CHECK-LABEL: fir.global @__BLNK__ : tuple> { -! CHECK: %[[undef:.*]] = fir.undefined tuple> +! CHECK: %[[undef:.*]] = fir.zero_bits tuple> ! CHECK: %[[init:.*]] = fir.insert_value %[[undef]], %c42{{.*}}, [0 : index] : (tuple>, i32) -> tuple> ! CHECK: fir.has_value %[[init]] : tuple> ! CHECK-LABEL: fir.global @a_ : tuple> { -! CHECK: %[[undef:.*]] = fir.undefined tuple> +! CHECK: %[[undef:.*]] = fir.zero_bits tuple> ! CHECK: %[[init:.*]] = fir.insert_value %[[undef]], %c42{{.*}}, [0 : index] : (tuple>, i32) -> tuple> ! CHECK: fir.has_value %[[init]] : tuple> diff --git a/flang/test/Lower/common-block.f90 b/flang/test/Lower/common-block.f90 index bd3fab507c0ef..3934b71b75694 100644 --- a/flang/test/Lower/common-block.f90 +++ b/flang/test/Lower/common-block.f90 @@ -6,7 +6,7 @@ ! CHECK: @with_empty_equiv_ = common global [8 x i8] zeroinitializer ! CHECK: @x_ = global { float, float } { float 1.0{{.*}}, float 2.0{{.*}} } ! CHECK: @y_ = common global [12 x i8] zeroinitializer -! CHECK: @z_ = global { i32, [4 x i8], float } { i32 42, [4 x i8] undef, float 3.000000e+00 } +! CHECK: @z_ = global { i32, [4 x i8], float } { i32 42, [4 x i8] zeroinitializer, float 3.000000e+00 } ! CHECK-LABEL: _QPs0 subroutine s0 diff --git a/flang/test/Lower/default-initialization-globals.f90 b/flang/test/Lower/default-initialization-globals.f90 index bbcea75a5b1f9..2b5e3c36367e2 100644 --- a/flang/test/Lower/default-initialization-globals.f90 +++ b/flang/test/Lower/default-initialization-globals.f90 @@ -97,7 +97,7 @@ module tinit ! CHECK-DAG: %[[VAL_15:.*]] = arith.constant 66 : i32 ! CHECK: %[[VAL_16:.*]] = fir.undefined !fir.type<_QMtinitTt1{{.*}}> ! CHECK: %[[VAL_17:.*]] = fir.insert_value %[[VAL_16]], %[[VAL_11]], ["i", !fir.type<_QMtinitTt1{{.*}}>] : (!fir.type<_QMtinitTt1{{.*}}>, i32) -> !fir.type<_QMtinitTt1{{.*}}> - ! CHECK: %[[VAL_18:.*]] = fir.undefined i32 + ! CHECK: %[[VAL_18:.*]] = fir.zero_bits i32 ! CHECK: %[[VAL_19:.*]] = fir.insert_value %[[VAL_17]], %[[VAL_18]], ["j", !fir.type<_QMtinitTt1{{.*}}>] : (!fir.type<_QMtinitTt1{{.*}}>, i32) -> !fir.type<_QMtinitTt1{{.*}}> ! CHECK: %[[VAL_20:.*]] = fir.address_of(@_QMtinitEziel) : !fir.ref> ! CHECK: %[[VAL_21:.*]] = fir.shape %[[VAL_12]] : (index) -> !fir.shape<1> @@ -111,12 +111,12 @@ module tinit ! CHECK: %[[VAL_28:.*]] = fir.insert_value %[[VAL_27]], %[[VAL_26]], ["z", !fir.type<_QMtinitTt1{{.*}}>] : (!fir.type<_QMtinitTt1{{.*}}>, !fir.box>>) -> !fir.type<_QMtinitTt1{{.*}}> ! CHECK: %[[VAL_29:.*]] = fir.string_lit "hello "(10) : !fir.char<1,10> ! CHECK: %[[VAL_30:.*]] = fir.insert_value %[[VAL_28]], %[[VAL_29]], ["c1", !fir.type<_QMtinitTt1{{.*}}>] : (!fir.type<_QMtinitTt1{{.*}}>, !fir.char<1,10>) -> !fir.type<_QMtinitTt1{{.*}}> - ! CHECK: %[[VAL_31:.*]] = fir.undefined !fir.char<1,10> + ! CHECK: %[[VAL_31:.*]] = fir.zero_bits !fir.char<1,10> ! CHECK: %[[VAL_32:.*]] = fir.insert_value %[[VAL_30]], %[[VAL_31]], ["c2", !fir.type<_QMtinitTt1{{.*}}>] : (!fir.type<_QMtinitTt1{{.*}}>, !fir.char<1,10>) -> !fir.type<_QMtinitTt1{{.*}}> ! CHECK: %[[VAL_33:.*]] = fir.undefined !fir.type<_QMtinitTt0{k:i32}> ! CHECK: %[[VAL_34:.*]] = fir.insert_value %[[VAL_33]], %[[VAL_15]], ["k", !fir.type<_QMtinitTt0{k:i32}>] : (!fir.type<_QMtinitTt0{k:i32}>, i32) -> !fir.type<_QMtinitTt0{k:i32}> ! CHECK: %[[VAL_35:.*]] = fir.insert_value %[[VAL_32]], %[[VAL_34]], ["somet0", !fir.type<_QMtinitTt1{{.*}}>] : (!fir.type<_QMtinitTt1{{.*}}>, !fir.type<_QMtinitTt0{k:i32}>) -> !fir.type<_QMtinitTt1{{.*}}> - ! CHECK: %[[VAL_36:.*]] = fir.undefined !fir.type<_QMtinitTtno_init{k:i32}> + ! CHECK: %[[VAL_36:.*]] = fir.zero_bits !fir.type<_QMtinitTtno_init{k:i32}> ! CHECK: %[[VAL_37:.*]] = fir.insert_value %[[VAL_35]], %[[VAL_36]], ["sometno_init", !fir.type<_QMtinitTt1{{.*}}>] : (!fir.type<_QMtinitTt1{{.*}}>, !fir.type<_QMtinitTtno_init{k:i32}>) -> !fir.type<_QMtinitTt1{{.*}}> ! CHECK: %[[VAL_38:.*]] = fir.insert_value %[[VAL_33]], %[[VAL_14]], ["k", !fir.type<_QMtinitTt0{k:i32}>] : (!fir.type<_QMtinitTt0{k:i32}>, i32) -> !fir.type<_QMtinitTt0{k:i32}> ! CHECK: %[[VAL_39:.*]] = fir.insert_value %[[VAL_37]], %[[VAL_38]], ["somet0_2", !fir.type<_QMtinitTt1{{.*}}>] : (!fir.type<_QMtinitTt1{{.*}}>, !fir.type<_QMtinitTt0{k:i32}>) -> !fir.type<_QMtinitTt1{{.*}}> @@ -129,7 +129,7 @@ module tinit ! CHECK: %[[VAL_42:.*]] = arith.constant 66 : i32 ! CHECK: %[[VAL_43:.*]] = fir.undefined !fir.type<_QMtinitTtextendst0{k:i32,l:i32}> ! CHECK: %[[VAL_44:.*]] = fir.insert_value %[[VAL_43]], %[[VAL_42]], ["k", !fir.type<_QMtinitTtextendst0{k:i32,l:i32}>] : (!fir.type<_QMtinitTtextendst0{k:i32,l:i32}>, i32) -> !fir.type<_QMtinitTtextendst0{k:i32,l:i32}> - ! CHECK: %[[VAL_45:.*]] = fir.undefined i32 + ! CHECK: %[[VAL_45:.*]] = fir.zero_bits i32 ! CHECK: %[[VAL_46:.*]] = fir.insert_value %[[VAL_44]], %[[VAL_45]], ["l", !fir.type<_QMtinitTtextendst0{k:i32,l:i32}>] : (!fir.type<_QMtinitTtextendst0{k:i32,l:i32}>, i32) -> !fir.type<_QMtinitTtextendst0{k:i32,l:i32}> ! CHECK: fir.has_value %[[VAL_46]] : !fir.type<_QMtinitTtextendst0{k:i32,l:i32}> diff --git a/flang/test/Lower/equivalence-static-init.f90 b/flang/test/Lower/equivalence-static-init.f90 index 6b4b0ccff4c5e..4c52a4a7d8448 100644 --- a/flang/test/Lower/equivalence-static-init.f90 +++ b/flang/test/Lower/equivalence-static-init.f90 @@ -8,7 +8,7 @@ module module_without_init equivalence(i(1), x) end module ! CHECK-LABEL: fir.global @_QMmodule_without_initEi : !fir.array<8xi8> { - ! CHECK: %0 = fir.undefined !fir.array<8xi8> + ! CHECK: %0 = fir.zero_bits !fir.array<8xi8> ! CHECK: fir.has_value %0 : !fir.array<8xi8> ! CHECK} diff --git a/flang/test/Lower/pointer-default-init.f90 b/flang/test/Lower/pointer-default-init.f90 index 4697d601347e7..6dde5d56aaa82 100644 --- a/flang/test/Lower/pointer-default-init.f90 +++ b/flang/test/Lower/pointer-default-init.f90 @@ -21,7 +21,7 @@ module test type(t) :: test_module_var ! CHECK-LABEL: fir.global @_QMtestEtest_module_var : !fir.type<_QMtestTt{i:i32,x:!fir.box>>}> { ! CHECK: %[[VAL_0:.*]] = fir.undefined !fir.type<_QMtestTt{i:i32,x:!fir.box>>}> -! CHECK: %[[VAL_1:.*]] = fir.undefined i32 +! CHECK: %[[VAL_1:.*]] = fir.zero_bits i32 ! CHECK: %[[VAL_2:.*]] = fir.field_index i ! CHECK: %[[VAL_3:.*]] = fir.insert_value %[[VAL_0]], %[[VAL_1]] ! CHECK: %[[VAL_4:.*]] = fir.zero_bits !fir.ptr> @@ -97,7 +97,7 @@ subroutine test_saved_pointer() ! CHECK-LABEL: fir.global internal @_QFtest_savedEx : !fir.type<_QMtestTt{i:i32,x:!fir.box>>}> { ! CHECK: %[[VAL_0:.*]] = fir.undefined !fir.type<_QMtestTt{i:i32,x:!fir.box>>}> -! CHECK: %[[VAL_1:.*]] = fir.undefined i32 +! CHECK: %[[VAL_1:.*]] = fir.zero_bits i32 ! CHECK: %[[VAL_2:.*]] = fir.field_index i ! CHECK: %[[VAL_3:.*]] = fir.insert_value %[[VAL_0]], %[[VAL_1]] ! CHECK: %[[VAL_4:.*]] = fir.zero_bits !fir.ptr> diff --git a/flang/test/Lower/pointer-initial-target-2.f90 b/flang/test/Lower/pointer-initial-target-2.f90 index 69e9f23126708..a3f2292e7fb76 100644 --- a/flang/test/Lower/pointer-initial-target-2.f90 +++ b/flang/test/Lower/pointer-initial-target-2.f90 @@ -12,7 +12,7 @@ common /a/ p data p /b/ ! CHECK-LABEL: fir.global @a_ : tuple>> - ! CHECK: %[[undef:.*]] = fir.undefined tuple>> + ! CHECK: %[[undef:.*]] = fir.zero_bits tuple>> ! CHECK: %[[b:.*]] = fir.address_of(@_QEb) : !fir.ref ! CHECK: %[[box:.*]] = fir.embox %[[b]] : (!fir.ref) -> !fir.box ! CHECK: %[[rebox:.*]] = fir.rebox %[[box]] : (!fir.box) -> !fir.box> @@ -41,7 +41,7 @@ block data bdsnake integer, pointer :: p => b common /snake/ p, b ! CHECK-LABEL: fir.global @snake_ : tuple>, i32> - ! CHECK: %[[tuple0:.*]] = fir.undefined tuple>, i32> + ! CHECK: %[[tuple0:.*]] = fir.zero_bits tuple>, i32> ! CHECK: %[[snakeAddr:.*]] = fir.address_of(@snake_) : !fir.ref>, i32>> ! CHECK: %[[byteView:.*]] = fir.convert %[[snakeAddr:.*]] : (!fir.ref>, i32>>) -> !fir.ref> ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[byteView]], %c24{{.*}} : (!fir.ref>, index) -> !fir.ref