Browse Source

Add validation to check unknown function attributes (#963)

Young Kim 7 years ago
parent
commit
1d48a06455
2 changed files with 37 additions and 8 deletions
  1. 24 7
      lib/HLSL/DxilValidation.cpp
  2. 13 1
      tools/clang/unittests/HLSL/ValidationTest.cpp

+ 24 - 7
lib/HLSL/DxilValidation.cpp

@@ -2371,16 +2371,33 @@ static void ValidateInstructionMetadata(Instruction *I,
 }
 
 static void ValidateFunctionAttribute(Function *F, ValidationContext &ValCtx) {
-  AttributeSet attrSet = F->getAttributes();
+  AttributeSet attrSet = F->getAttributes().getFnAttributes();
   // fp32-denorm-mode
-  if (attrSet.hasAttribute(AttributeSet::FunctionIndex, DXIL::kFP32DenormKindString)) {
-    Attribute attr = attrSet.getAttribute(AttributeSet::FunctionIndex, DXIL::kFP32DenormKindString);
+  if (attrSet.hasAttribute(AttributeSet::FunctionIndex,
+                           DXIL::kFP32DenormKindString)) {
+    Attribute attr = attrSet.getAttribute(AttributeSet::FunctionIndex,
+                                          DXIL::kFP32DenormKindString);
     StringRef value = attr.getValueAsString();
     if (!value.equals(DXIL::kFP32DenormValueAnyString) &&
-      !value.equals(DXIL::kFP32DenormValueFtzString) &&
-      !value.equals(DXIL::kFP32DenormValuePreserveString))
-    {
-      ValCtx.EmitFnAttributeError(F, attr.getKindAsString(), attr.getValueAsString());
+        !value.equals(DXIL::kFP32DenormValueFtzString) &&
+        !value.equals(DXIL::kFP32DenormValuePreserveString)) {
+      ValCtx.EmitFnAttributeError(F, attr.getKindAsString(),
+                                  attr.getValueAsString());
+    }
+  }
+  // TODO: If validating libraries, we should remove all unknown function attributes.
+  // For each attribute, check if it is a known attribute
+  for (unsigned I = 0, E = attrSet.getNumSlots(); I != E; ++I) {
+    for (auto AttrIter = attrSet.begin(I), AttrEnd = attrSet.end(I);
+         AttrIter != AttrEnd; ++AttrIter) {
+      if (!AttrIter->isStringAttribute()) {
+        continue;
+      }
+      StringRef kind = AttrIter->getKindAsString();
+      if (!kind.equals(DXIL::kFP32DenormKindString)) {
+        ValCtx.EmitFnAttributeError(F, AttrIter->getKindAsString(),
+                                    AttrIter->getValueAsString());
+      }
     }
   }
 }

+ 13 - 1
tools/clang/unittests/HLSL/ValidationTest.cpp

@@ -226,6 +226,7 @@ public:
   TEST_METHOD(ClipCullMaxComponents)
   TEST_METHOD(ClipCullMaxRows)
   TEST_METHOD(DuplicateSysValue)
+  TEST_METHOD(FunctionAttributes)
   TEST_METHOD(GSMainMissingAttributeFail)
   TEST_METHOD(GSOtherMissingAttributeFail)
   TEST_METHOD(GSMissingMaxVertexCountFail)
@@ -3150,4 +3151,15 @@ TEST_F(ValidationTest, Float32DenormModeAttribute) {
     "contains invalid attribute 'fp32-denorm-mode' with value 'invalid_mode'",
     true);
 }
-// TODO: reject non-zero padding
+
+TEST_F(ValidationTest, FunctionAttributes) {
+  if (m_ver.SkipDxilVersion(1, 2)) return;
+  std::vector<LPCWSTR> pArguments = { L"-denorm", L"ftz" };
+  RewriteAssemblyCheckMsg(
+    "float4 main(float4 col: COL) : SV_Target { return col; }", "ps_6_2",
+    pArguments.data(), 2, nullptr, 0,
+    { "\"fp32-denorm-mode\"=\"ftz\"" },
+    { "\"dummy_attribute\"=\"invalid_mode\"" },
+    "contains invalid attribute 'dummy_attribute' with value 'invalid_mode'",
+    true);
+}// TODO: reject non-zero padding