GCC has started warning about array access out of bounds when it shouldn't. It appears that the compiler writers are trying very hard to warn against this problem but it is messing things up. I upgraded from the 9.2 distribution to 9.3 but the results were the same. My problem is with this code:
/* Compute a checksum on the TLV data area and compare it to the value stored there. If they match, return true. Checked before using the ADC calibration data and DCO settings stored there. */ int tlv_good(void) { int *p, chk, i; chk = 0; p = (int *)(&TLV_CHECKSUM + 1); for(i = 0; i < 31; i++) chk ^= *p++; chk += TLV_CHECKSUM; return ~chk; } /* Use factory calibration data to correct ADC readings. Starts with filtered Q4 fixed point numbers but just throws away the fractional bits. Remembers if the TLV structure checksum has checked out previously. */ uint16_t corrected(int val) { int32_t tmp; static int *p = 0; if(p || tlv_good()) { p = (int *)&TLV_ADC10_1_TAG; tmp = val >> 3; tmp *= *(p + CAL_ADC_25VREF_FACTOR/2); tmp >>= 16; tmp *= *(p+CAL_ADC_GAIN_FACTOR/2); tmp >>= 16; tmp += *(p+CAL_ADC_OFFSET/2); return tmp; } else return val >> 4; }
The first function (tlv_good()) is fine but the second results in several warnings:
beeper.c: In function 'corrected': beeper.c:86:14: warning: array subscript 6 is outside array bounds of 'volatile unsigned char[1]' [-Warray-bounds] 86 | tmp *= *(p + CAL_ADC_25VREF_FACTOR/2); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from /usr/ti/gcc/include/msp430g2553.h:65, from /usr/ti/gcc/include/msp430.h:1423, from beeper.c:1: /usr/ti/gcc/include/msp430g2553.h:904:1: note: while referencing 'TLV_ADC10_1_TAG' 904 | sfr_b(TLV_ADC10_1_TAG); /* TLV ADC10_1 TAG */ | ^~~~~
Notice how even though I am using a pointer to an integer, the compiler is complaining about the source of the address I used and as an array of characters. It did not make any such complaint about the pointer references in tlv_good(). The only difference is in the size of the item referenced. One is defined as a word (sfr_w) and the other as a char. (sfr_b) in the device header file.
Even worse is that when I look at the code it is beyond awful. In spite of my using a pointer to an integer, the compiler fetches the data one byte at a time. Doing a slow and painful eight bit shift on one byte before combining the bytes into an integer.
The problem probably starts with these data structures stored in memory being tagged as special function registers in the device header file but the compiler propagating those attributes is causing the most trouble. Short of disabling the array bounds warning I have found no way around the warning. And no way to make it generate sane code.