cpp:S3519 seems to ignore pointer increment in first loop iteration

We are using SonarQube verson 8.9.1

We have code that triggers rule S3519, Rules explorer

Our code has a more involved version of this, but morally behaves in the same way.

constexpr int format[] = {0, 11, 21};
int foo(const int arg)
{
	int arr[4] {};
	const int fmt = format[arg];
	auto *ptr = &arr[0];
	int power = 1;
	for (std::size_t i = 0; i != 2; ++i) {
		const int digit = fmt % (power * 10) / power;
		power *= 10;
		switch (digit) {
		case 0:
			return 0;
		case 2:
			*(ptr - 1) = 0;
			break;
		default:
			*(ptr++) = 10;
		}
	}
	return arr[0];
}

Which triggers the specified rule on this line *(ptr - 1) = 0;

This also appears to trigger the same rule in SonarLint version 4.37.0.34839

The moral of the story is that we have one array of format integers, and one array that gets written to. A format integer gets chosen, and we iterate over the digits of the format integer. In this case, if the given int is 0, we return immediately, if it is anything other than 2 we write some value to the current position in the data array and increment the index, otherwise if the digit is 2 then we write something to the previous index.

Sonar detects this as an out of bounds access because it sees the decremented pointer and thinks we access the address one before the beginning of the array. But in reality, all the format values work out in such a way that the pointer always gets incremented by at least one before we hit the condition where we access the previous index.

Hello @torgeir.skogen,

Thanks for your detailed report. you are right it is a false-positive. We should be able to detect that the path on which the issue is raise is unreachable. I created this ticket to improve the engine. Until then you can resolve the issue as false-positive.

Thanks,

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.