[spirv-remap] Fix undefined behavior in hashing

There's a statement that intends to generate a 32-bit hashcode, but due
to integer promotion, the intermediate values can trigger signed integer
overflow, which is undefined behavior.

To avoid this, cast at least one operand to unsigned int before
multiplying, which will cause the result to be promoted to unsigned int
instead of signed int.

With this patch, I'm able to build core for qemu-x64 with host_asan-ubsan.

Fixed: 60128
Change-Id: Idd644e534116bf29dca8013936ac39901bbe68fc
Reviewed-on: https://fuchsia-review.googlesource.com/c/third_party/glslang/+/428254
Reviewed-by: John Bauman <jbauman@google.com>
diff --git a/SPIRV/SPVRemapper.cpp b/SPIRV/SPVRemapper.cpp
index fd0bb89..943b9b6 100644
--- a/SPIRV/SPVRemapper.cpp
+++ b/SPIRV/SPVRemapper.cpp
@@ -827,7 +827,15 @@
             [&](spv::Id& id) {
                 if (thisOpCode != spv::OpNop) {
                     ++idCounter;
-                    const std::uint32_t hashval = opCounter[thisOpCode] * thisOpCode * 50047 + idCounter + fnId * 117;
+                    const std::uint32_t hashval =
+                        // Explicitly cast operands to unsigned int to avoid integer
+                        // promotion to signed int followed by integer overflow,
+                        // which would result in undefined behavior.
+                        static_cast<unsigned int>(opCounter[thisOpCode])
+                        * thisOpCode
+                        * 50047
+                        + idCounter
+                        + static_cast<unsigned int>(fnId) * 117;
 
                     if (isOldIdUnmapped(id))
                         localId(id, nextUnusedId(hashval % softTypeIdLimit + firstMappedID));