Forbid !<integer> preceding or succeeding '='.

This commit is contained in:
Dejan Mircevski 2015-09-11 15:03:54 -04:00 committed by David Neto
parent b30a0c529b
commit e3a19c0d63
3 changed files with 25 additions and 8 deletions

View File

@ -601,6 +601,11 @@ spv_result_t encodeInstructionStartingWithImmediate(
return error;
}
if (operandValue == "=") {
DIAGNOSTIC << firstWord << " not allowed before =.";
return SPV_ERROR_INVALID_TEXT;
}
// Needed to pass to spvTextEncodeOpcode(), but it shouldn't ever be
// expanded.
spv_operand_pattern_t dummyExpectedOperands;

View File

@ -138,7 +138,7 @@ encountered, it begins a new instruction and parsing returns to normal. (If a
subsequent OpCode is never found, then this alternate parsing mode handles all
the remaining words in the program. If a subsequent OpCode is in an
[assignment form](#assignment-form), the ID preceding it begins a new
instruction, even if that ID is itself a `!<integer>`.)
instruction.)
The assembler processes the words encountered in alternate parsing mode as
follows:
@ -169,6 +169,10 @@ Note that this has some interesting consequences, including:
by the alternate parsing mode. They must be replaced by `!<integer>` for
successful assembly.
* The `<result-id>` on the left-hand side of an assignment cannot be
a`!<integer>`. But it can be a number prefixed by `%`, which still gives the
user control over its value.
* The `=` sign cannot be processed by the alternate parsing mode if the OpCode
following it is a `!<integer>`.

View File

@ -78,19 +78,27 @@ TEST_F(ImmediateIntTest, AnyWordInSimpleStatement) {
// EXPECT_EQ(original, CompileSuccessfully("!0x0004002B !1 !2 !123", kCAF));
}
TEST_F(ImmediateIntTest, AnyWordInAssignmentStatement) {
TEST_F(ImmediateIntTest, AnyWordAfterEqualsAndOpCode) {
const SpirvVector original =
CompileSuccessfully("%2 = OpArrayLength %12 %1 123");
// TODO(deki): uncomment assertions below and make them pass.
// EXPECT_EQ(original, CompileSuccessfully("!2 = OpArrayLength %12 %1 123"));
// EXPECT_EQ(original, CompileSuccessfully("%2 = !0x00040044 %12 %1 123"));
EXPECT_EQ(original, CompileSuccessfully("%2 = OpArrayLength !12 %1 123"));
EXPECT_EQ(original, CompileSuccessfully("%2 = OpArrayLength %12 !1 123"));
EXPECT_EQ(original, CompileSuccessfully("%2 = OpArrayLength %12 %1 !123"));
// Instead of checking all possible multiple-! combinations, only probe a few.
EXPECT_EQ(original, CompileSuccessfully("%2 = OpArrayLength %12 !1 !123"));
// EXPECT_EQ(original, CompileSuccessfully("%2 = !0x00040044 !12 !1 !123"));
// EXPECT_EQ(original, CompileSuccessfully("!2 = !0x00040044 %12 %1 123"));
EXPECT_EQ(original, CompileSuccessfully("%2 = OpArrayLength !12 !1 123"));
EXPECT_EQ(original, CompileSuccessfully("%2 = OpArrayLength !12 !1 !123"));
}
TEST_F(ImmediateIntTest, ResultIdInAssignment) {
EXPECT_EQ("!2 not allowed before =.",
CompileFailure("!2 = OpArrayLength %12 %1 123"));
EXPECT_EQ("!2 not allowed before =.",
CompileFailure("!2 = !0x00040044 %12 %1 123"));
}
TEST_F(ImmediateIntTest, OpCodeInAssignment) {
EXPECT_EQ("Invalid Opcode prefix '!0x00040044'.",
CompileFailure("%2 = !0x00040044 %12 %1 123"));
}
// Literal integers after !<integer> are handled correctly.