sliceframa-cprogram-slicing

/*undefined sequence*/ in sliced code from Frama-C


I am trying to slice code using Frama-C.

The source code is

static uint8_T ALARM_checkOverInfusionFlowRate(void)
{
uint8_T ov;
ov = 0U;
if (ALARM_Functional_B.In_Therapy) {
  if (ALARM_Functional_B.Flow_Rate > ALARM_Functional_B.Flow_Rate_High) {
     ov = 1U;
   } else if (ALARM_Functional_B.Flow_Rate >
       ALARM_Functional_B.Commanded_Flow_Rate * div_s32
           (ALARM_Functional_B.Tolerance_Max, 100) +
                  ALARM_Functional_B.Commanded_Flow_Rate) {
                     ov = 1U;
                  } else {
                      if (ALARM_Functional_B.Flow_Rate > ALARM_Functional_B.Commanded_Flow_Rate *                div_s32(ALARM_Functional_B.Tolerance_Min, 100) + ALARM_Functional_B.Commanded_Flow_Rate) {
                         ov = 2U;
                      }
                }
      }
  return ov;
}

When I sliced the code usig Frama-C, I get the following. I don't know what this “undefined sequence” means.

static uint8_T ALARM_checkOverInfusionFlowRate(void)
{
  uint8_T ov;
  ov = 0U;
  if (ALARM_Functional_B.In_Therapy)
    if ((int)ALARM_Functional_B.Flow_Rate > (int)ALARM_Functional_B.Flow_Rate_High)
      ov = 1U;
    else {
      int32_T tmp_0;
      {
        /*undefined sequence*/
        tmp_0 = div_s32((int)ALARM_Functional_B.Tolerance_Max,100);
      }
      if ((int)ALARM_Functional_B.Flow_Rate > (int)ALARM_Functional_B.Commanded_Flow_Rate * tmp_0 + (int)ALARM_Functional_B.Commanded_Flow_Rate)
        ov = 1U;
      else {
        int32_T tmp;
        {
          /*undefined sequence*/
          tmp = div_s32((int)ALARM_Functional_B.Tolerance_Min,100);
        }
        if ((int)ALARM_Functional_B.Flow_Rate > (int)ALARM_Functional_B.Commanded_Flow_Rate * tmp + (int)ALARM_Functional_B.Commanded_Flow_Rate)
          ov = 2U;
      }
    }
  return ov;
}

Appreciate any help in explaining why this happens.


Solution

  • /* undefined sequence */ in a block simply means that the block has been generated during the code normalization at parsing time but that with respect to C semantics there is no sequence point between the statements composing it. For instance x++ + x++ will be normalized as

     {
        /*undefined sequence*/
        tmp = x;
        x ++;
        tmp_0 = x;
        x ++;
        ;
     }
    

    Internally, each statement in such a sequence is decorated with lists of locations that are accessed for writing or reading (use -kernel-debug 1 with -print to see them in the output). Option -unspecified-access used together with -val will check that such accesses are correct, i.e. that there is at most one statement inside the sequence that write to a given location and if this is the case, that there is no read access to it (except for building the value it is assigned to). In addition, this option does not take care of side-effects occurring in a function call inside the sequence. There is a special plug-in for that, but it has not been released yet.

    Finally note that since Frama-C Neon, the comment reads only /*sequence*/, which seems to be less daunting for the user. Indeed, the original code may be correct or may show undefined behavior, but syntactic analysis is too weak to decide in the general case. For instance, (*p)++ + (*q)++ is correct as long as p and q do not overlap. This is why the normalization phase only points out the sequences and leaves it up to more powerful analysis plug-ins to check whether there might be an issue.