https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110360
--- Comment #32 from David Edelsohn <dje at gcc dot gnu.org> --- i think that I see part of the difference. The 005t.original dump shows (intermingled with sources) ! call val ("B","B") val (&"B"[1]{lb: 1 sz: 1}, "B", 1, 1); ! call val ("A",char(65)) val (&"A"[1]{lb: 1 sz: 1}, "A", 1, 1); ! call val ("A",char(a)) { character(kind=1) char.6; char.6 = (character(kind=1)) a; val (&"A"[1]{lb: 1 sz: 1}, char.6, 1, 1); } ! call val ("A",mychar(65)) { static integer(kind=4) C.2654 = 65; character(kind=1) str.7[1]; mychar ((character(kind=1)[1:1] *) &str.7, 1, &C.2654); val (&"A"[1]{lb: 1 sz: 1}, str.7[0], 1, 1); } ! call val ("A",mychar(a)) { character(kind=1) str.8[1]; mychar ((character(kind=1)[1:1] *) &str.8, 1, &a); val (&"A"[1]{lb: 1 sz: 1}, str.8[0], 1, 1); } char(65) is folded by the FORTRAN front-end to "A", so it is passed in the same manner that elicits the shift. The rest of the calls pass 65. The string is left-shifted and the number is right-shifted. GFORTRAN seems to assume that passing a STRING by value will be padded the same as a number or character, which isn't accurate. I'm leaning back to big-endian vs little-endian, and not a struct issue. A little-endian STRING will start at the lowest address and a big-endian STRING will start at the highest address.