]> granicus.if.org Git - llvm/commitdiff
[TextAPI] Fix off-by-one error in the bit index extraction loop
authorPetar Jovanovic <petar.jovanovic@mips.com>
Fri, 5 Apr 2019 12:58:15 +0000 (12:58 +0000)
committerPetar Jovanovic <petar.jovanovic@mips.com>
Fri, 5 Apr 2019 12:58:15 +0000 (12:58 +0000)
The loop in findNextSetBit() runs one pass more than it should.

On 64-bit architectures this does not cause a problem, but 32-bit
architectures mask the shift count to 5 bits which limits the number of
shifts inside a range of 0 to 31. Shifting by 32 has the same effect as
shifting by 0, so if the first bit in the set is 1, the function will return
with Index different from EndIndexVal. Because of that, range-based for
loops iterating thorough architectures will continue until hitting a 0 in
the set, resulting in n additional iterations, where n is equal to the
number of consecutive 1 bits at the start the set.

Ultimately TBDv1.WriteFile and TBDv2.WriteFile will output additional
architectures causing a failure in the unit tests.

Patch by Milos Stojanovic.

Differential Revision: https://reviews.llvm.org/D60198

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@357759 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/TextAPI/MachO/ArchitectureSet.h

index aae1f1d4e0990935cc008378b9de3b931f01904b..d8dfc7f1af214aa98787a91118915d2d7128be07 100644 (file)
@@ -69,11 +69,10 @@ public:
     void findNextSetBit() {
       if (Index == EndIndexVal)
         return;
-
-      do {
-        if (*ArchSet & (1UL << ++Index))
+      while (++Index < sizeof(Ty) * 8) {
+        if (*ArchSet & (1UL << Index))
           return;
-      } while (Index < sizeof(Ty) * 8);
+      }
 
       Index = EndIndexVal;
     }