Opened 5 years ago

Closed 5 years ago

Last modified 5 years ago

#5994 closed defect (fixed)

Invalid code generation when accessing array index with size(array,1)

Reported by: a.d.e.suisse@… Owned by: Mahder Alemseged Gebremedhin
Priority: high Milestone: 1.16.0
Component: New Instantiation Version: v.1.15.0-dev
Keywords: Cc:

Description

Hello everybody

When accessing an array index inside a function by using the size() function, invalid C-code is generated. this leads to a compile error.

Function code:

within TestLib;

function modifyArray
    input Real values[:];
    output Real result[size(values, 1)];
  algorithm
    result := values;
    result[size(values, 1)] := 42.0;
end modifyArray;

Model code:

model Test
parameter
  Real sample[:] = {1.0, 2.0, 3.0};
  Real modified[:] = TestLib.modifyArray(values = sample);
algorithm
equation

end Test;

Generated C-code (Test_functions.c):

...
real_array omc_TestLib_modifyArray(threadData_t *threadData, real_array _values)
{
  real_array _result;
  modelica_integer tmp1;
  modelica_integer tmp2;
  _tailrecursive: OMC_LABEL_UNUSED
  tmp1 = size_of_dimension_base_array(_values, ((modelica_integer) 1));
  alloc_real_array(&(_result), 1, tmp1); // _result has no default value.
  copy_real_array_data(_values, &_result);

  tmp2 = size_of_dimension_base_array(_values, ((modelica_integer) 1));
  real_array_get(_result, 1, tmp3) = 42.0;
  _return: OMC_LABEL_UNUSED
  return _result;
}
...

As seen in the C-code, the variable "tmp2" is used to store the size of the array, but for accessing the array an undeclared variable "tmp3" is used.
This leads to following compiler output:

C:/Program Files/OpenModelica1.14.1-64bit//share/omc/scripts/Compile.bat Test gcc mingw64 parallel 8 0
PATH = "C:\PROGRA~1\OPENMO~1.1-6\tools\msys\mingw64\bin;C:\PROGRA~1\OPENMO~1.1-6\tools\msys\mingw64\bin\..\..\usr\bin;"
mingw32-make: Entering directory 'C:/Users/patri/AppData/Local/Temp/OPENMO~1/OMEdit/Test'
gcc  -Os -falign-functions -fno-ipa-pure-const -mstackrealign -msse2 -mfpmath=sse     -I"C:/Program Files/OpenModelica1.14.1-64bit//include/omc/c" -I. -DOPENMODELICA_XML_FROM_FILE_AT_RUNTIME -DOMC_MODEL_PREFIX=Test -DOMC_NUM_MIXED_SYSTEMS=0 -DOMC_NUM_LINEAR_SYSTEMS=0 -DOMC_NUM_NONLINEAR_SYSTEMS=0 -DOMC_NDELAY_EXPRESSIONS=0 -DOMC_NVAR_STRING=0  -c -o Test.o Test.c
gcc  -Os -falign-functions -fno-ipa-pure-const -mstackrealign -msse2 -mfpmath=sse     -I"C:/Program Files/OpenModelica1.14.1-64bit//include/omc/c" -I. -DOPENMODELICA_XML_FROM_FILE_AT_RUNTIME -DOMC_MODEL_PREFIX=Test -DOMC_NUM_MIXED_SYSTEMS=0 -DOMC_NUM_LINEAR_SYSTEMS=0 -DOMC_NUM_NONLINEAR_SYSTEMS=0 -DOMC_NDELAY_EXPRESSIONS=0 -DOMC_NVAR_STRING=0  -c -o Test_functions.o Test_functions.c
gcc  -Os -falign-functions -fno-ipa-pure-const -mstackrealign -msse2 -mfpmath=sse     -I"C:/Program Files/OpenModelica1.14.1-64bit//include/omc/c" -I. -DOPENMODELICA_XML_FROM_FILE_AT_RUNTIME -DOMC_MODEL_PREFIX=Test -DOMC_NUM_MIXED_SYSTEMS=0 -DOMC_NUM_LINEAR_SYSTEMS=0 -DOMC_NUM_NONLINEAR_SYSTEMS=0 -DOMC_NDELAY_EXPRESSIONS=0 -DOMC_NVAR_STRING=0  -c -o Test_records.o Test_records.c
gcc  -Os -falign-functions -fno-ipa-pure-const -mstackrealign -msse2 -mfpmath=sse     -I"C:/Program Files/OpenModelica1.14.1-64bit//include/omc/c" -I. -DOPENMODELICA_XML_FROM_FILE_AT_RUNTIME -DOMC_MODEL_PREFIX=Test -DOMC_NUM_MIXED_SYSTEMS=0 -DOMC_NUM_LINEAR_SYSTEMS=0 -DOMC_NUM_NONLINEAR_SYSTEMS=0 -DOMC_NDELAY_EXPRESSIONS=0 -DOMC_NVAR_STRING=0  -c -o Test_01exo.o Test_01exo.c
gcc  -Os -falign-functions -fno-ipa-pure-const -mstackrealign -msse2 -mfpmath=sse     -I"C:/Program Files/OpenModelica1.14.1-64bit//include/omc/c" -I. -DOPENMODELICA_XML_FROM_FILE_AT_RUNTIME -DOMC_MODEL_PREFIX=Test -DOMC_NUM_MIXED_SYSTEMS=0 -DOMC_NUM_LINEAR_SYSTEMS=0 -DOMC_NUM_NONLINEAR_SYSTEMS=0 -DOMC_NDELAY_EXPRESSIONS=0 -DOMC_NVAR_STRING=0  -c -o Test_02nls.o Test_02nls.c
gcc  -Os -falign-functions -fno-ipa-pure-const -mstackrealign -msse2 -mfpmath=sse     -I"C:/Program Files/OpenModelica1.14.1-64bit//include/omc/c" -I. -DOPENMODELICA_XML_FROM_FILE_AT_RUNTIME -DOMC_MODEL_PREFIX=Test -DOMC_NUM_MIXED_SYSTEMS=0 -DOMC_NUM_LINEAR_SYSTEMS=0 -DOMC_NUM_NONLINEAR_SYSTEMS=0 -DOMC_NDELAY_EXPRESSIONS=0 -DOMC_NVAR_STRING=0  -c -o Test_03lsy.o Test_03lsy.c
gcc  -Os -falign-functions -fno-ipa-pure-const -mstackrealign -msse2 -mfpmath=sse     -I"C:/Program Files/OpenModelica1.14.1-64bit//include/omc/c" -I. -DOPENMODELICA_XML_FROM_FILE_AT_RUNTIME -DOMC_MODEL_PREFIX=Test -DOMC_NUM_MIXED_SYSTEMS=0 -DOMC_NUM_LINEAR_SYSTEMS=0 -DOMC_NUM_NONLINEAR_SYSTEMS=0 -DOMC_NDELAY_EXPRESSIONS=0 -DOMC_NVAR_STRING=0  -c -o Test_04set.o Test_04set.c
gcc  -Os -falign-functions -fno-ipa-pure-const -mstackrealign -msse2 -mfpmath=sse     -I"C:/Program Files/OpenModelica1.14.1-64bit//include/omc/c" -I. -DOPENMODELICA_XML_FROM_FILE_AT_RUNTIME -DOMC_MODEL_PREFIX=Test -DOMC_NUM_MIXED_SYSTEMS=0 -DOMC_NUM_LINEAR_SYSTEMS=0 -DOMC_NUM_NONLINEAR_SYSTEMS=0 -DOMC_NDELAY_EXPRESSIONS=0 -DOMC_NVAR_STRING=0  -c -o Test_05evt.o Test_05evt.c
In file included from C:/Program Files/OpenModelica1.14.1-64bit/include/omc/c/util/modelica.h:56:0,
                 from Test_functions.h:4,
                 from Test_functions.c:2:
Test_functions.c: In function 'omc_TestLib_modifyArray':
Test_functions.c:22:30: error: 'tmp3' undeclared (first use in this function)
   real_array_get(_result, 1, tmp3) = 42.0;
                              ^
C:/Program Files/OpenModelica1.14.1-64bit/include/omc/c/util/generic_array.h:64:109: note: in definition of macro 'real_array_get'
 #define real_array_get(src,ndims,...)               (*(modelica_real*)(real_array_element_addr(&src, ndims, __VA_ARGS__)))
                                                                                                             ^
Test_functions.c:22:30: note: each undeclared identifier is reported only once for each function it appears in
   real_array_get(_result, 1, tmp3) = 42.0;
                              ^
C:/Program Files/OpenModelica1.14.1-64bit/include/omc/c/util/generic_array.h:64:109: note: in definition of macro 'real_array_get'
 #define real_array_get(src,ndims,...)               (*(modelica_real*)(real_array_element_addr(&src, ndims, __VA_ARGS__)))
                                                                                                             ^
<builtin>: recipe for target 'Test_functions.o' failed
mingw32-make: *** [Test_functions.o] Error 1
mingw32-make: *** Waiting for unfinished jobs....
mingw32-make: Leaving directory 'C:/Users/patri/AppData/Local/Temp/OPENMO~1/OMEdit/Test'
Compilation process failed. Exited with code 2.

This behavior was observed in three environments:

  • Two different Windows 10 PCs
    • OpenModelica 1.14.1 64 bit
    • One installed by Installer from OpenModelica,org
    • One installed using chocolatey
  • Ubuntu 18.04 LTS inside Hyper-V
    • OpenModelica 1.15.0-dev
    • Installed by apt from OpenModelica.org

Change History (9)

comment:1 by a.d.e.suisse@…, 5 years ago

Workaround:

By using an intermediate variable, the code is generated properly.
e.g.:

within TestLib;

function modifyArray
    input Real values[:];
    output Real result[size(values, 1)];
  protected
    Integer valuesSize = size(values, 1);
  algorithm
    result := values;
    result[valuesSize] := 42.0;
end modifyArray;

comment:2 by Martin Sjölund, 5 years ago

Component: Code GenerationNew Instantiation
Owner: changed from Lennart Ochel to Per Östlund

This only triggers with -d=newInst

comment:3 by Martin Sjölund, 5 years ago

Trying to make it trigger also for old instantiation triggered an error for the backend:

model Test

function modifyArray
    input Real values[:];
    output Real result[size(values, 1)];
  algorithm
    result := values;
    result[size(values, 1)] := 42.0;
end modifyArray;

  Real modified = max(modifyArray(1:time));
algorithm
equation

end Test;

The following triggers the error also for the old frontend, and passes the backend:

model Test

function modifyArray
    input Real values[:];
    output Real result[size(values, 1)];
  algorithm
    result := values;
    result[size(values, 1)] := 42.0;
end modifyArray;

function f
  input Real t;
  output Real m;
algorithm
  m := max(modifyArray(1:t));
end f;

  Real modified = f(time);
algorithm
equation

end Test;
Last edited 5 years ago by Martin Sjölund (previous) (diff)

comment:4 by Mahder Alemseged Gebremedhin, 5 years ago

Owner: changed from Per Östlund to Mahder Alemseged Gebremedhin
Status: newaccepted

comment:5 by Mahder Alemseged Gebremedhin, 5 years ago

This is caused because previous expressions (&preExp) and variable declarations (&varDecl) for subscript expressions are not used. So any un-evaluated complicated expression that is used as a subscript never worked. The reason it was not changed was because we need to pass these buffers to a chain of component reference handling functions if we wanted to get them to subscript generation and nothing in the testsuite seemed to need them.

I guess the time has come to pass them around and then use dummy &preExp and &varDecl where we do not have that info.

Last edited 5 years ago by Mahder Alemseged Gebremedhin (previous) (diff)

comment:6 by Martin Sjölund, 5 years ago

Yes, I came to the same conclusion now after looking into it and was going to say someone else needs to implement it because I need to grade some papers :)

comment:7 by Mahder Alemseged Gebremedhin, 5 years ago

This has been fixed in https://github.com/OpenModelica/OpenModelica/commit/cc6d66fce.
The model in the ticket has been added as a test case.

If there is nothing else I will close this ticket.

comment:8 by Mahder Alemseged Gebremedhin, 5 years ago

Resolution: fixed
Status: acceptedclosed

comment:9 by Francesco Casella, 5 years ago

Milestone: NeedsInput1.16.0
Note: See TracTickets for help on using tickets.