Index: lib/CodeGen/CGCleanup.h =================================================================== --- lib/CodeGen/CGCleanup.h +++ lib/CodeGen/CGCleanup.h @@ -58,7 +58,7 @@ friend class EHCatchScope; unsigned : NumCommonBits; - unsigned NumHandlers : 32 - NumCommonBits; + unsigned NumHandlers; }; class CleanupBitFields { @@ -90,14 +90,14 @@ /// 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 + unsigned FixupDepth; }; class FilterBitFields { friend class EHFilterScope; unsigned : NumCommonBits; - unsigned NumFilters : 32 - NumCommonBits; + unsigned NumFilters; }; union { @@ -188,6 +188,7 @@ EHScopeStack::stable_iterator enclosingEHScope) : EHScope(Catch, enclosingEHScope) { CatchBits.NumHandlers = numHandlers; + assert(CatchBits.NumHandlers == numHandlers && "NumHandlers overflow?"); } unsigned getNumHandlers() const { @@ -300,6 +301,7 @@ CleanupBits.FixupDepth = fixupDepth; assert(CleanupBits.CleanupSize == cleanupSize && "cleanup size overflow"); + assert(CleanupBits.FixupDepth == fixupDepth && "fixup depth overflow"); } void Destroy() { @@ -451,6 +453,7 @@ EHFilterScope(unsigned numFilters) : EHScope(Filter, EHScopeStack::stable_end()) { FilterBits.NumFilters = numFilters; + assert(FilterBits.NumFilters == numFilters && "NumFilters overflow"); } static size_t getSizeForNumFilters(unsigned numFilters) { Index: test/CodeGen/fixup-depth-overflow.c =================================================================== --- /dev/null +++ test/CodeGen/fixup-depth-overflow.c @@ -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