Skip to content

C++: handle cast arrays properly in off-by-one query#13117

Merged
MathiasVP merged 3 commits intogithub:mainfrom
rdmarsh2:rdmarsh2/cpp/cobo-handle-array-casts
Jun 28, 2023
Merged

C++: handle cast arrays properly in off-by-one query#13117
MathiasVP merged 3 commits intogithub:mainfrom
rdmarsh2:rdmarsh2/cpp/cobo-handle-array-casts

Conversation

@rdmarsh2
Copy link
Copy Markdown
Contributor

Previously, pointer arithmetic done using a different size than the original array were excluded in the constant size off-by-one query. This PR handles that case by using the byte length of the array and dividing by the element size at the pointer arithmetic.

This PR follows #13045 and #13116. Only 2b40498 is new.

@rdmarsh2 rdmarsh2 requested a review from a team as a code owner May 10, 2023 19:50
@github-actions github-actions Bot added the C++ label May 10, 2023
geoffw0
geoffw0 previously approved these changes May 11, 2023
Copy link
Copy Markdown
Contributor

@geoffw0 geoffw0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM (assuming the two PRs under it get merged first).

) {
pai.getElementSize() = v.getUnspecifiedType().(ArrayType).getBaseType().getSize() and
v.getUnspecifiedType().(ArrayType).getArraySize() = size and
v.getUnspecifiedType().(ArrayType).getByteSize() / pai.getElementSize() = size and
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to convince myself rounding down here is the right thing to do, by considering some examples.

The pointer size is larger than the array element size:

char buffer[100]; // getByteSize() = 100
int *ptr = (int *)buffer; // pai.getElementSize() will be sizeof(int) = 4 -> size = 25

ptr[24] = ...; // writes bytes 96, 97, 98, 99 - GOOD
ptr[25] = ...; // writes bytes 100, 101, 102, 103 - BAD

The pointer size is smaller than the array element size but does not divide it:

struct vec2 {
	int x, y;
}

struct vec3 {
	int x, y, z;
}

vec3 array[3]; // getByteSize() = 9 * sizeof(int)
vec2 *ptr = (vec2 *)array; // pai.getElementSize() will be 2 * sizeof(int) -> size = 4

ptr[3] = ... // writes ints 6, 7 - OK
ptr[4] = ... // writes ints 8, 9 - BAD

The pointer size is larger than the array element size and does not divide it:

vec2 array[2]; // getByteSize() = 4 * sizeof(int)
vec3 *ptr = (vec3 *)array; // pai.getElementSize() will be 3 * sizeof(int) -> size = 1

ptr[0] = ... // writes ints 0, 1, 2 - OK
ptr[1] = ... // writes ints 3, 4, 5 - BAD

(my examples are untested, may be naive about struct padding)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for those excellent testcases, Geoffrey! I've added them in 51176bd. It looks like we get the first two cases correct, but miss the last one. I haven't quite figured out why yet.

@rdmarsh2 rdmarsh2 force-pushed the rdmarsh2/cpp/cobo-handle-array-casts branch from 0a7ab85 to d18fb64 Compare May 26, 2023 17:16
Copy link
Copy Markdown
Contributor

@MathiasVP MathiasVP left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Performance looks fine (even with the cartesian product we've identified) and the new result LGTM. Let's fix that missing result in @geoffw0's testcases at a later point.

@MathiasVP MathiasVP merged commit 2c99009 into github:main Jun 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants