"BuiltIn, consumed per entry-point. Entry Point id "
<< entry_point << " does not meet this requirement.";
}
+ // The LinkageAttributes Decoration cannot be applied to functions targeted
+ // by an OpEntryPoint instruction
+ for (auto& decoration : vstate.id_decorations(entry_point)) {
+ if (SpvDecorationLinkageAttributes == decoration.dec_type()) {
+ const char* linkage_name =
+ reinterpret_cast<const char*>(&decoration.params()[0]);
+ return vstate.diag(SPV_ERROR_INVALID_BINARY)
+ << "The LinkageAttributes Decoration (Linkage name: "
+ << linkage_name << ") cannot be applied to function id "
+ << entry_point
+ << " because it is targeted by an OpEntryPoint instruction.";
+ }
+ }
}
+ // TODO: Refactor this function into smaller pieces.
+
return SPV_SUCCESS;
}
EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
}
+TEST_F(ValidateDecorations, EntryPointFunctionHasLinkageAttributeBad) {
+ string spirv = R"(
+ OpCapability Shader
+ OpCapability Linkage
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpDecorate %main LinkageAttributes "import_main" Import
+%1 = OpTypeVoid
+%2 = OpTypeFunction %1
+%main = OpFunction %1 None %2
+%4 = OpLabel
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(spirv.c_str());
+ EXPECT_EQ(SPV_ERROR_INVALID_BINARY, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("The LinkageAttributes Decoration (Linkage name: import_main) "
+ "cannot be applied to function id 1 because it is targeted by "
+ "an OpEntryPoint instruction."));
+}
+
} // anonymous namespace