https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124049

            Bug ID: 124049
           Summary: Inconsistent assignment of union overhead values
           Product: gcc
           Version: 16.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: algol68
          Assignee: algol68 at gcc dot gnu.org
          Reporter: bohlj47 at gmail dot com
  Target Milestone: ---

The following code produces incorrect output:

module-a.a68:

  module Module_a =
  def
     pub mode Union_a = union (int,real);
     pub proc union_a_string = (Union_a x) string:
        case x
        in (int): "int'n",
           (real): "real'n"
        esac;
     skip
  fed

module-b.a68:

  module Module_b =
  def
      pub mode Union_b = union (real,int);
      pub proc union_b_string = (Union_b x) string:
          case x
          in (int): "int'n",
             (real): "real'n"
          esac;
      skip
  fed

program.a68:

  access Module_a,Module_b begin
      Union_a a = 1;
      Union_b b = 1;
      puts(union_a_string(a));
      puts(union_a_string(b));
      puts(union_b_string(a));
      puts(union_b_string(b))
  end

To compile:

  ga68 -c module-a.a68
  ga68 -c module-b.a68
  ga68 program.a68 module-a.o module-b.o

To run:

  ./a.out

The program outputs:

int
int
real
real

instead of the expected:

int
int
int
int

I have tracked the problem down to the union overhead values being assigned
differently when the packets are compiled. In modules-a.a68 and module-b.a68,
the overhead values are assigned in the order that the modes in the union are
specified. In program.a68 the overhead values are assigned the same as in
module-a.a68. When the union_b_string procedure is called it acts upon the
integer value as a real since it was compiled with the opposite overhead
assignment.

Reply via email to