Uploaded image for project: 'Embedded Software & Tools'
  1. Embedded Software & Tools
  2. EXT_EP-9862

Unsigned range check expressions may generate incorrect code

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: Medium Medium
    • Code Generation Tools
    • CODEGEN-7715
    • Hide
      C2000_20.2.0.beta
      C2000_18.9.0.STS
      C7000_1.3.0.STS
      ARM_18.12.0.LTS
      C7000_1.2.0.STS
      C7000_1.4.0.LTS
      MSP430_18.9.0.STS
      C2000_19.6.0.STS
      ARM_18.9.0.STS
      ARM_19.6.0.STS
      MSP430_18.12.0.LTS
      MSP430_19.6.0.STS
      ARM_20.2.0.beta
      C2000_18.12.0.LTS
      MSP430_20.2.0.beta
      Show
      C2000_20.2.0.beta C2000_18.9.0.STS C7000_1.3.0.STS ARM_18.12.0.LTS C7000_1.2.0.STS C7000_1.4.0.LTS MSP430_18.9.0.STS C2000_19.6.0.STS ARM_18.9.0.STS ARM_19.6.0.STS MSP430_18.12.0.LTS MSP430_19.6.0.STS ARM_20.2.0.beta C2000_18.12.0.LTS MSP430_20.2.0.beta
    • Hide
      MSP430_20.2.2.LTS
      ARM_20.2.2.LTS
      C7000_1.4.1.LTS*
      MSP430_18.12.7.LTS*
      ARM_18.12.7.LTS*
      C2000_18.12.7.LTS*
      C2000_20.2.2.LTS
      Show
      MSP430_20.2.2.LTS ARM_20.2.2.LTS C7000_1.4.1.LTS* MSP430_18.12.7.LTS* ARM_18.12.7.LTS* C2000_18.12.7.LTS* C2000_20.2.2.LTS
    • default
    • Hide
      This bug can only occur if both parts of the range are constant values or are derived from constant values. To work around this issue, one end of the range check can be made "volatile" so that the compiler cannot treat the value as a constant. For example, the following code fragment will avoid the incorrect behavior and generate correct code:

      {noformat}
      volatile uint64_t low = 0x0800;
      uint64_t high = 0x8000;
      if ((x >= low) && (x < high)) { return 1; }
      else { return 0; }
      {noformat}
      Show
      This bug can only occur if both parts of the range are constant values or are derived from constant values. To work around this issue, one end of the range check can be made "volatile" so that the compiler cannot treat the value as a constant. For example, the following code fragment will avoid the incorrect behavior and generate correct code: {noformat} volatile uint64_t low = 0x0800; uint64_t high = 0x8000; if ((x >= low) && (x < high)) { return 1; } else { return 0; } {noformat}

      Unsigned range check expressions for unsigned integral types larger than int may result in incorrect code. This bug may also manifest with pointer range checks if the size of a pointer is larger than that of an int. The necessary conditions for this bug are:
      1. An unsigned integral's value is compared against a lower bound and an upper bound.
      2. The lower bound and upper bound values are either constants or are derived from constants.

      For example, the attached file has this code to check whether an address is within a certain range.

         if ((address_as_ulong < high) && (address_as_ulong >= low))
      

      To build it ...

      % cl7x -@options.txt try2.c
      FILE: try2.obj
      CODE  size (bytes): 256
      CONST size (bytes): 56
      

      A simple main routine calls the function with this test three times. Correct output is ...

      too_low gives 456
      in_range gives 123
      too_high gives 456
      

      However, the generated code is wrong, which causes the second call to get a wrong answer. The output actually seen is ...

      too_low gives 456
      in_range gives 456
      too_high gives 456
      

      The problem occurs when --opt_level=1 or higher.

            syncuser TI User
            syncuser TI User
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: