Skip to content

Commit e4f573f

Browse files
committed
Merging r155466:
------------------------------------------------------------------------ r155466 | chandlerc | 2012-04-24 11:42:47 -0700 (Tue, 24 Apr 2012) | 17 lines Fix a crash on valid (if UB) bitcode that is produced for some global constants in C++11 mode. I have no idea why it required such particular circumstances to get here, the code seems clearly to rely upon unchecked assumptions. Specifically, when we decide to form an index into a struct type, we may have gone through (at least one) zero-length array indexing round, which would have left the offset un-adjusted, and thus not necessarily valid for use when indexing the struct type. This is just an canonicalization step, so the correct thing is to refuse to canonicalize nonsensical GEPs of this form. Implemented, and test case added. Fixes PR12642. Pair debugged and coded with Richard Smith. =] I credit him with most of the debugging, and preventing me from writing the wrong code. ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_31@155506 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent ad41289 commit e4f573f

File tree

2 files changed

+16
-3
lines changed

2 files changed

+16
-3
lines changed

lib/Analysis/ConstantFolding.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,7 @@ static Constant *SymbolicallyEvaluateGEP(ArrayRef<Constant *> Ops,
681681
// This makes it easy to determine if the getelementptr is "inbounds".
682682
// Also, this helps GlobalOpt do SROA on GlobalVariables.
683683
Type *Ty = Ptr->getType();
684+
assert(Ty->isPointerTy() && "Forming regular GEP of non-pointer type");
684685
SmallVector<Constant*, 32> NewIdxs;
685686
do {
686687
if (SequentialType *ATy = dyn_cast<SequentialType>(Ty)) {
@@ -711,10 +712,17 @@ static Constant *SymbolicallyEvaluateGEP(ArrayRef<Constant *> Ops,
711712
}
712713
Ty = ATy->getElementType();
713714
} else if (StructType *STy = dyn_cast<StructType>(Ty)) {
714-
// Determine which field of the struct the offset points into. The
715-
// getZExtValue is at least as safe as the StructLayout API because we
716-
// know the offset is within the struct at this point.
715+
// If we end up with an offset that isn't valid for this struct type, we
716+
// can't re-form this GEP in a regular form, so bail out. The pointer
717+
// operand likely went through casts that are necessary to make the GEP
718+
// sensible.
717719
const StructLayout &SL = *TD->getStructLayout(STy);
720+
if (Offset.uge(SL.getSizeInBytes()))
721+
break;
722+
723+
// Determine which field of the struct the offset points into. The
724+
// getZExtValue is fine as we've already ensured that the offset is
725+
// within the range representable by the StructLayout API.
718726
unsigned ElIdx = SL.getElementContainingOffset(Offset.getZExtValue());
719727
NewIdxs.push_back(ConstantInt::get(Type::getInt32Ty(Ty->getContext()),
720728
ElIdx));

test/Transforms/GlobalOpt/constantfold-initializers.ll

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3
1212
@xs = global [2 x i32] zeroinitializer, align 4
1313
; CHECK: @xs = global [2 x i32] [i32 1, i32 1]
1414

15+
; PR12642
16+
%PR12642.struct = type { i8 }
17+
@PR12642.s = global <{}> zeroinitializer, align 1
18+
@PR12642.p = constant %PR12642.struct* bitcast (i8* getelementptr (i8* bitcast (<{}>* @PR12642.s to i8*), i64 1) to %PR12642.struct*), align 8
19+
1520
define internal void @test1() {
1621
entry:
1722
store i32 1, i32* getelementptr inbounds ([2 x i32]* @xs, i64 0, i64 0)

0 commit comments

Comments
 (0)