Author: hans Date: Wed Jun 22 11:21:14 2016 New Revision: 273434 URL: http://llvm.org/viewvc/llvm-project?rev=273434&view=rev Log: Widen EHScope::ClenupBitFields::FixupDepth to avoid overflowing it (PR23490)
It currently only takes 2048 gotos to overflow the FixupDepth bitfield, causing silent miscompilation. Apparently some parser generators run into this (see PR). I don't know that that data structure is terribly size sensitive anyway, and since there's no room to widen the bitfield, let's just use a separate word in EHCatchScope for it. Differential Revision: http://reviews.llvm.org/D21566 Added: cfe/trunk/test/CodeGen/fixup-depth-overflow.c Modified: cfe/trunk/lib/CodeGen/CGCleanup.h Modified: cfe/trunk/lib/CodeGen/CGCleanup.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCleanup.h?rev=273434&r1=273433&r2=273434&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGCleanup.h (original) +++ cfe/trunk/lib/CodeGen/CGCleanup.h Wed Jun 22 11:21:14 2016 @@ -86,11 +86,6 @@ protected: /// The amount of extra storage needed by the Cleanup. /// Always a multiple of the scope-stack alignment. unsigned CleanupSize : 12; - - /// The number of fixups required by enclosing scopes (not including - /// this one). If this is the top cleanup scope, all the fixups - /// from this index onwards belong to this scope. - unsigned FixupDepth : 32 - 18 - NumCommonBits; // currently 12 }; class FilterBitFields { @@ -188,6 +183,7 @@ public: EHScopeStack::stable_iterator enclosingEHScope) : EHScope(Catch, enclosingEHScope) { CatchBits.NumHandlers = numHandlers; + assert(CatchBits.NumHandlers == numHandlers && "NumHandlers overflow?"); } unsigned getNumHandlers() const { @@ -263,6 +259,11 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ }; mutable struct ExtInfo *ExtInfo; + /// The number of fixups required by enclosing scopes (not including + /// this one). If this is the top cleanup scope, all the fixups + /// from this index onwards belong to this scope. + unsigned FixupDepth; + struct ExtInfo &getExtInfo() { if (!ExtInfo) ExtInfo = new struct ExtInfo(); return *ExtInfo; @@ -288,8 +289,9 @@ public: unsigned cleanupSize, unsigned fixupDepth, EHScopeStack::stable_iterator enclosingNormal, EHScopeStack::stable_iterator enclosingEH) - : EHScope(EHScope::Cleanup, enclosingEH), EnclosingNormal(enclosingNormal), - NormalBlock(nullptr), ActiveFlag(nullptr), ExtInfo(nullptr) { + : EHScope(EHScope::Cleanup, enclosingEH), + EnclosingNormal(enclosingNormal), NormalBlock(nullptr), + ActiveFlag(nullptr), ExtInfo(nullptr), FixupDepth(fixupDepth) { CleanupBits.IsNormalCleanup = isNormal; CleanupBits.IsEHCleanup = isEH; CleanupBits.IsActive = isActive; @@ -297,7 +299,6 @@ public: CleanupBits.TestFlagInNormalCleanup = false; CleanupBits.TestFlagInEHCleanup = false; CleanupBits.CleanupSize = cleanupSize; - CleanupBits.FixupDepth = fixupDepth; assert(CleanupBits.CleanupSize == cleanupSize && "cleanup size overflow"); } @@ -343,7 +344,7 @@ public: return CleanupBits.TestFlagInEHCleanup; } - unsigned getFixupDepth() const { return CleanupBits.FixupDepth; } + unsigned getFixupDepth() const { return FixupDepth; } EHScopeStack::stable_iterator getEnclosingNormalCleanup() const { return EnclosingNormal; } @@ -451,6 +452,7 @@ public: EHFilterScope(unsigned numFilters) : EHScope(Filter, EHScopeStack::stable_end()) { FilterBits.NumFilters = numFilters; + assert(FilterBits.NumFilters == numFilters && "NumFilters overflow"); } static size_t getSizeForNumFilters(unsigned numFilters) { Added: cfe/trunk/test/CodeGen/fixup-depth-overflow.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/fixup-depth-overflow.c?rev=273434&view=auto ============================================================================== --- cfe/trunk/test/CodeGen/fixup-depth-overflow.c (added) +++ cfe/trunk/test/CodeGen/fixup-depth-overflow.c Wed Jun 22 11:21:14 2016 @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -O1 -disable-llvm-optzns -emit-llvm -o - %s | FileCheck %s + +#define M if (x) goto L1; +#define M10 M M M M M M M M M M +#define M100 M10 M10 M10 M10 M10 M10 M10 M10 M10 M10 +#define M1000 M100 M100 M100 M100 M100 M100 M100 M100 M100 M100 + +void f(int x) { + int h; + + // Many gotos to not-yet-emitted labels would cause EHScope's FixupDepth + // to overflow (PR23490). + M1000 M1000 M1000 + + if (x == 5) { + // This will cause us to emit a clean-up of the stack variable. If the + // FixupDepths are broken, fixups will erroneously get threaded through it. + int i; + } + +L1: + return; +} + +// CHECK-LABEL: define void @f +// CHECK-NOT: cleanup _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits