Keil Logo

Compiler V6.12 Bug?

Next Thread | Thread List | Previous Thread Start a Thread | Settings

Details Message
Author
Thomas Roob
Posted
9-Apr-2019 09:34 GMT
Toolset
ARM
New! Compiler V6.12 Bug?

Simulation of following code, compiled with V6.12 and optimzation level -O2

#include <stdio.h>


typedef struct {
  char data[23];
} device_t;


static device_t deviceList[100];


static device_t* rotate(device_t *device)
{
  int index;

  index = (device - &deviceList[0]) + 1;

  if (index < 0 || index > 30) {
    index = 0;
  }

  printf("index = %d\n", index);
  return &deviceList[index];
}


int main(void)
{
  unsigned int n = 0;

  while (1) {
    printf("n = %d: ", n);
    rotate((device_t*)(n));
    n += 1000;
  }
}


prints

n = 0: index = 0
n = 1000: index = 0
n = 2000: index = 0
n = 3000: index = 0
n = 4000: index = 0
n = 5000: index = 0
n = 6000: index = 163395741
n = 7000: index = 350133493
n = 8000: index = 536871245
n = 9000: index = 723608997
n = 10000: index = 910346749
n = 11000: index = 1097084501
n = 12000: index = 1283822253
n = 13000: index = 1470560005
n = 14000: index = 1657297757
n = 15000: index = 1844035509

into Debug (printf) Viewer, which is obviously incorrect.

Maybe a bug, or do I missunderstand something?


Author
Tamir Michael
Posted
9-Apr-2019 12:45 GMT
Toolset
ARM
New! RE: Compiler V6.12 Bug?
rotate((device_t*)(n));

There is no relation between the address you create and the actual location of data in memory - yet, you use that to calculate an index. Clearly wrong.

Author
Thomas Roob
Posted
9-Apr-2019 15:54 GMT
Toolset
ARM
New! Compiler V6.12 Bug?

Thanks Tamir fo replying,

cropping index to 0.. 30 fails with following code, too.
Printf output is

addr = 0X2000016C index = 373474418
addr = 0X20000183 index = 373474419
addr = 0X2000019A index = 373474420
addr = 0X200001B1 index = 373474421
addr = 0X200001C8 index = 373474422
addr = 0X200001DF index = 373474423
addr = 0X200001F6 index = 373474424

#include <stdio.h>
#include <stdint.h>


typedef struct {
  char data[23];
} device_t;


struct {
  device_t list1[1000];
  char dummy;
  device_t deviceList[31];
} list;


static device_t* rotate(device_t *device)
{
  int index;

  index = (device - &list.deviceList[0]) + 1;

  if (index < 0 || index > 30) {
    index = 0;
  }

  printf("index = %d\n", index);
  return &list.deviceList[index];
}


int main(void)
{
  device_t *device;

  device = &list.list1[0];

  while (1) {
    printf("addr = %#8X  ", (uint32_t)device);
    rotate(device);
    device++;
  }
}
Author
Tamir Michael
Posted
10-Apr-2019 07:31 GMT
Toolset
ARM
New! RE: Compiler V6.12 Bug?

Again, you're subtracting the addresses of pieces of memory that are (presumably) not logically related. Without knowing what you attempt to achieve, this code

index = (device - &list.deviceList[0]) + 1;


would make sense if it were written instead as:

index = (device - &list.deviceList[0]) ;

,
in conjunction with

for (uint32_t x = 0 ; x < sizeof(list.deviceList) / sizeof(device_t) ; x++)
{
    device = &list.deviceList[x];
    rotate(device);
}
Author
Andrew Neil
Posted
10-Apr-2019 09:22 GMT
Toolset
ARM
New! RE: Without knowing what you attempt to achieve

Perhaps start by saying what you expect the code to do (show your working), and why you think the actual results are "wrong".

What analysis / investigation / debugging have you done to see where the "unexpected" behaviour originates ?

Author
Thomas Roob
Posted
10-Apr-2019 12:44 GMT
Toolset
ARM
New! RE: Compiler V6.12 Bug?

you are rigth, I am violating the C Standard, 6.5.6 ISO/IEC 9899:2011

Thank you very much

Author
Thomas Roob
Posted
10-Apr-2019 13:03 GMT
Toolset
ARM
New! RE: Compiler V6.12 Bug?

For clarification.

The function

device_t *rotate(device_t *device);

returns next element to device. If device is last element, the first element is returned. If device does not point to an valid object in list, any list element could be returned.

Author
Hans-Bernhard Broeker
Posted
11-Apr-2019 17:25 GMT
Toolset
ARM
New! RE: Compiler V6.12 Bug?

If device does not point to an valid object in list, any list element could be returned.

Except that that part of the intended function is just impossible to implement without causing undefined behaviour via C99 6.5.6 or 6.5.8 along the way. In other words: forget about it.

If that's what you have to achieve, you have to change the signature from handling pointers to handling indices into the array.

In short: in C, there's no such thing as deriving a trustworthy pointer from garbage input. The only checks you can do on untrustworthy pointers are trivial variations on

(ptr != 0)
(ptr == 0)
Author
Thomas Roob
Posted
17-Apr-2019 10:42 GMT
Toolset
ARM
New! RE: Compiler V6.12 Bug?

Thanks for your advice.

Next Thread | Thread List | Previous Thread Start a Thread | Settings

  Arm logo
Important information

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies.

Change Settings

Privacy Policy Update

Arm’s Privacy Policy has been updated. By continuing to use our site, you consent to Arm’s Privacy Policy. Please review our Privacy Policy to learn more about our collection, use and transfers
of your data.