Skip to content

Fix validation of array length.#169

Closed
dekimir wants to merge 9 commits intomasterfrom
speconstop
Closed

Fix validation of array length.#169
dekimir wants to merge 9 commits intomasterfrom
speconstop

Conversation

@dekimir
Copy link
Copy Markdown

@dekimir dekimir commented Apr 1, 2016

auto length = usedefs_.FindDef(inst->words[lengthIndex]);
if (!length.first || (SpvOpConstant != length.second.opcode &&
SpvOpSpecConstant != length.second.opcode)) {
if (!length.first || !spvOpcodeIsConstant(length.second.opcode)) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This is too permissive given the code that later checks the value.
The later code uses the lengths of the instructions and maps that to an assumption about it being a SpvOpConstant or SpvOpSpecConstant.
Should have a TODO saying the remaining cases should be handled (or punted entirely)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

That comment no longer applies now that the later code switches on opcode.

@qining
Copy link
Copy Markdown
Contributor

qining commented Apr 1, 2016

+1, but I don't quite understand the 'remaining cases' in David's comments :(

@dekimir
Copy link
Copy Markdown
Author

dekimir commented Apr 1, 2016

Feedback addressed.

const bool is_signed = typeWords[3];
if (width == 64) {
if (is_signed) {
int64_t value = constWords[3] | (int64_t{constWords[4]} << 32);
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.

This doesn't compile with VS 2013:

error C2397: conversion from 'const unsigned int' to 'int64_t' requires a narrowing conversion

which I find a bit strange, since it's 32-bit to 64-bit, so there's clearly enough bits.
I'd change it to:

(uint64_t{constWords[4]} << 32)

We're shifting left, so signedness makes no difference.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Thanks @yavn. I changed it to uint64_t, as you suggest. Aside from the VS2013 error, I've realized that shifting a signed value runs into undefined behaviour all too easily.

Use uint64_t instead of int64_t to shift left a SPIR-V word representing
high-order bits of a signed 64-bit value.  That way shifting left by 32
bits is well defined.
int64_t value = constWords[3] | (uint64_t{constWords[4]} << 32);
return value > 0;
} else {
uint64_t value = constWords[3] | (uint64_t{constWords[4]} << 32);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

An unsigned value is non-zero if any of its bits are non-zero. So you could have saved some work here. Or you could have been a little more DRY by sharing this computation with the signed case, and then had the signed case do the constructor-cast.

@dneto0
Copy link
Copy Markdown
Collaborator

dneto0 commented Apr 4, 2016

-1 for invalid code for 48 bit widths, and missing test cases.

@dekimir
Copy link
Copy Markdown
Author

dekimir commented Apr 4, 2016

Made aboveZero() DRY, covered all widths between 32 and 64, and added many more tests. PTAL.

if (width > 32) {
// The spec currently doesn't allow integers wider than 64 bits.
const auto hiWord = constWords[4]; // Must exist, per spec.
if (is_signed && (hiWord >> 31)) return false;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This depends critically on the fact that hiWord is an unsigned type, and yet you declare it via auto.
Ok, I guess.

@dneto0
Copy link
Copy Markdown
Collaborator

dneto0 commented Apr 4, 2016

-1
Fine except it fails the GCC Travis builds.

@dekimir
Copy link
Copy Markdown
Author

dekimir commented Apr 4, 2016

Fixed auto and GCC failure.

@dneto0
Copy link
Copy Markdown
Collaborator

dneto0 commented Apr 4, 2016

+2 yay

@dekimir
Copy link
Copy Markdown
Author

dekimir commented Apr 4, 2016

Squashed and merged to master via 3fb2676.

@dekimir dekimir closed this Apr 4, 2016
@dekimir dekimir deleted the speconstop branch April 4, 2016 19:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants