1 // Copyright (c) 2019 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "source/fuzz/transformation_add_global_undef.h"
16 
17 #include "gtest/gtest.h"
18 #include "source/fuzz/fuzzer_util.h"
19 #include "test/fuzz/fuzz_test_util.h"
20 
21 namespace spvtools {
22 namespace fuzz {
23 namespace {
24 
TEST(TransformationAddGlobalUndefTest,BasicTest)25 TEST(TransformationAddGlobalUndefTest, BasicTest) {
26   std::string shader = R"(
27                OpCapability Shader
28           %1 = OpExtInstImport "GLSL.std.450"
29                OpMemoryModel Logical GLSL450
30                OpEntryPoint Fragment %4 "main"
31                OpExecutionMode %4 OriginUpperLeft
32                OpSource ESSL 310
33           %2 = OpTypeVoid
34           %3 = OpTypeFunction %2
35           %6 = OpTypeFloat 32
36           %7 = OpTypeInt 32 1
37           %8 = OpTypeVector %6 2
38           %9 = OpTypeVector %6 3
39          %10 = OpTypeVector %6 4
40          %11 = OpTypeVector %7 2
41           %4 = OpFunction %2 None %3
42           %5 = OpLabel
43                OpReturn
44                OpFunctionEnd
45   )";
46 
47   const auto env = SPV_ENV_UNIVERSAL_1_4;
48   const auto consumer = nullptr;
49   const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
50   spvtools::ValidatorOptions validator_options;
51   ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
52                                                kConsoleMessageConsumer));
53   TransformationContext transformation_context(
54       MakeUnique<FactManager>(context.get()), validator_options);
55   // Id already in use
56   ASSERT_FALSE(TransformationAddGlobalUndef(4, 11).IsApplicable(
57       context.get(), transformation_context));
58   // %1 is not a type
59   ASSERT_FALSE(TransformationAddGlobalUndef(100, 1).IsApplicable(
60       context.get(), transformation_context));
61 
62   // %3 is a function type
63   ASSERT_FALSE(TransformationAddGlobalUndef(100, 3).IsApplicable(
64       context.get(), transformation_context));
65 
66   TransformationAddGlobalUndef transformations[] = {
67       // %100 = OpUndef %6
68       TransformationAddGlobalUndef(100, 6),
69 
70       // %101 = OpUndef %7
71       TransformationAddGlobalUndef(101, 7),
72 
73       // %102 = OpUndef %8
74       TransformationAddGlobalUndef(102, 8),
75 
76       // %103 = OpUndef %9
77       TransformationAddGlobalUndef(103, 9),
78 
79       // %104 = OpUndef %10
80       TransformationAddGlobalUndef(104, 10),
81 
82       // %105 = OpUndef %11
83       TransformationAddGlobalUndef(105, 11)};
84 
85   for (auto& transformation : transformations) {
86     ASSERT_TRUE(
87         transformation.IsApplicable(context.get(), transformation_context));
88     ApplyAndCheckFreshIds(transformation, context.get(),
89                           &transformation_context);
90   }
91   ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
92                                                kConsoleMessageConsumer));
93 
94   std::string after_transformation = R"(
95                OpCapability Shader
96           %1 = OpExtInstImport "GLSL.std.450"
97                OpMemoryModel Logical GLSL450
98                OpEntryPoint Fragment %4 "main"
99                OpExecutionMode %4 OriginUpperLeft
100                OpSource ESSL 310
101           %2 = OpTypeVoid
102           %3 = OpTypeFunction %2
103           %6 = OpTypeFloat 32
104           %7 = OpTypeInt 32 1
105           %8 = OpTypeVector %6 2
106           %9 = OpTypeVector %6 3
107          %10 = OpTypeVector %6 4
108          %11 = OpTypeVector %7 2
109         %100 = OpUndef %6
110         %101 = OpUndef %7
111         %102 = OpUndef %8
112         %103 = OpUndef %9
113         %104 = OpUndef %10
114         %105 = OpUndef %11
115           %4 = OpFunction %2 None %3
116           %5 = OpLabel
117                OpReturn
118                OpFunctionEnd
119   )";
120   ASSERT_TRUE(IsEqual(env, after_transformation, context.get()));
121 }
122 
123 }  // namespace
124 }  // namespace fuzz
125 }  // namespace spvtools
126