Index: clang/lib/CodeGen/CGExpr.cpp =================================================================== --- clang/lib/CodeGen/CGExpr.cpp +++ clang/lib/CodeGen/CGExpr.cpp @@ -3613,7 +3613,15 @@ if (!E->getType()->isVariableArrayType()) { assert(isa(Addr.getElementType()) && "Expected pointer to array"); - Addr = Builder.CreateConstArrayGEP(Addr, 0, "arraydecay"); + + if (getLangOpts().isSignedOverflowDefined()) { + llvm::setSignedWrap(true); + Addr = Builder.CreateConstGEP(Addr, 0, "arraydecay"); + } + else { + Addr = Builder.CreateConstArrayGEP(Addr, 0, "arraydecay"); + } + } // The result of this decay conversion points to an array element within the Index: clang/test/CodeGen/inbounds.c =================================================================== --- /dev/null +++ clang/test/CodeGen/inbounds.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fwrapv -emit-llvm -o - %s | FileCheck %s + +extern char base[]; + +char *test() { + return base + 1; +} + +// CHECK: ret ptr getelementptr (i8, ptr @base, i64 1) Index: llvm/include/llvm/IR/ConstantFold.h =================================================================== --- llvm/include/llvm/IR/ConstantFold.h +++ llvm/include/llvm/IR/ConstantFold.h @@ -26,10 +26,15 @@ namespace llvm { template class ArrayRef; + inline bool SignedWrap = false; + class Value; class Constant; class Type; + bool getSignedWrap(void); + void setSignedWrap(bool Wrap); + // Constant fold various types of instruction... Constant *ConstantFoldCastInstruction( unsigned opcode, ///< The opcode of the cast Index: llvm/lib/IR/ConstantFold.cpp =================================================================== --- llvm/lib/IR/ConstantFold.cpp +++ llvm/lib/IR/ConstantFold.cpp @@ -347,6 +347,14 @@ } } +bool llvm::getSignedWrap() { + return llvm::SignedWrap; +} + +void llvm::setSignedWrap(bool sWrap) { + llvm::SignedWrap=sWrap; +} + Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V, Type *DestTy) { if (isa(V))