summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2012-08-24 23:29:28 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2012-08-24 23:29:28 +0000
commit1144af3c9b4da48cd581156e05b24261c8de366a (patch)
tree49da576a97bfdab702528643450798baa54c790f
parentcac59d8ae815596f4f6b77d1a5414c0591168ea5 (diff)
downloadllvm-1144af3c9b4da48cd581156e05b24261c8de366a.tar.gz
llvm-1144af3c9b4da48cd581156e05b24261c8de366a.tar.bz2
llvm-1144af3c9b4da48cd581156e05b24261c8de366a.tar.xz
Fix integer undefined behavior due to signed left shift overflow in LLVM.
Reviewed offline by chandlerc. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162623 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/ADT/BitVector.h9
-rw-r--r--include/llvm/ADT/DenseMapInfo.h6
-rw-r--r--include/llvm/ADT/PointerIntPair.h4
-rw-r--r--include/llvm/ADT/SparseBitVector.h2
-rw-r--r--include/llvm/CodeGen/MachineOperand.h2
-rw-r--r--include/llvm/Support/MathExtras.h12
-rw-r--r--lib/Analysis/ValueTracking.cpp2
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinter.cpp7
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAG.cpp5
-rw-r--r--lib/Support/regexec.c2
-rw-r--r--lib/Target/ARM/Disassembler/ARMDisassembler.cpp2
-rw-r--r--lib/Target/CellSPU/SPUAsmPrinter.cpp6
-rw-r--r--lib/Target/CellSPU/SPUISelDAGToDAG.cpp13
-rw-r--r--lib/Target/Mips/MipsAnalyzeImmediate.cpp2
-rw-r--r--lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp2
-rw-r--r--lib/Target/PowerPC/PPCISelLowering.cpp15
-rw-r--r--lib/Target/X86/Disassembler/X86DisassemblerDecoder.c2
-rw-r--r--lib/Target/X86/X86ISelDAGToDAG.cpp5
-rw-r--r--utils/TableGen/CodeGenDAGPatterns.cpp17
19 files changed, 59 insertions, 56 deletions
diff --git a/include/llvm/ADT/BitVector.h b/include/llvm/ADT/BitVector.h
index 3e2e5f230a..df896b98f4 100644
--- a/include/llvm/ADT/BitVector.h
+++ b/include/llvm/ADT/BitVector.h
@@ -172,7 +172,7 @@ public:
unsigned BitPos = Prev % BITWORD_SIZE;
BitWord Copy = Bits[WordPos];
// Mask off previous bits.
- Copy &= ~0L << BitPos;
+ Copy &= ~0UL << BitPos;
if (Copy != 0) {
if (sizeof(BitWord) == 4)
@@ -451,8 +451,11 @@ private:
// Then set any stray high bits of the last used word.
unsigned ExtraBits = Size % BITWORD_SIZE;
if (ExtraBits) {
- Bits[UsedWords-1] &= ~(~0L << ExtraBits);
- Bits[UsedWords-1] |= (0 - (BitWord)t) << ExtraBits;
+ BitWord ExtraBitMask = ~0UL << ExtraBits;
+ if (t)
+ Bits[UsedWords-1] |= ExtraBitMask;
+ else
+ Bits[UsedWords-1] &= ~ExtraBitMask;
}
}
diff --git a/include/llvm/ADT/DenseMapInfo.h b/include/llvm/ADT/DenseMapInfo.h
index 1559a35c39..6f17a647b6 100644
--- a/include/llvm/ADT/DenseMapInfo.h
+++ b/include/llvm/ADT/DenseMapInfo.h
@@ -31,12 +31,12 @@ struct DenseMapInfo {
template<typename T>
struct DenseMapInfo<T*> {
static inline T* getEmptyKey() {
- intptr_t Val = -1;
+ uintptr_t Val = static_cast<uintptr_t>(-1);
Val <<= PointerLikeTypeTraits<T*>::NumLowBitsAvailable;
return reinterpret_cast<T*>(Val);
}
static inline T* getTombstoneKey() {
- intptr_t Val = -2;
+ uintptr_t Val = static_cast<uintptr_t>(-2);
Val <<= PointerLikeTypeTraits<T*>::NumLowBitsAvailable;
return reinterpret_cast<T*>(Val);
}
@@ -105,7 +105,7 @@ template<> struct DenseMapInfo<int> {
// Provide DenseMapInfo for longs.
template<> struct DenseMapInfo<long> {
static inline long getEmptyKey() {
- return (1UL << (sizeof(long) * 8 - 1)) - 1L;
+ return (1UL << (sizeof(long) * 8 - 1)) - 1UL;
}
static inline long getTombstoneKey() { return getEmptyKey() - 1L; }
static unsigned getHashValue(const long& Val) {
diff --git a/include/llvm/ADT/PointerIntPair.h b/include/llvm/ADT/PointerIntPair.h
index fcc758b43a..71c379bad5 100644
--- a/include/llvm/ADT/PointerIntPair.h
+++ b/include/llvm/ADT/PointerIntPair.h
@@ -135,12 +135,12 @@ template<typename PointerTy, unsigned IntBits, typename IntType>
struct DenseMapInfo<PointerIntPair<PointerTy, IntBits, IntType> > {
typedef PointerIntPair<PointerTy, IntBits, IntType> Ty;
static Ty getEmptyKey() {
- intptr_t Val = -1;
+ uintptr_t Val = static_cast<uintptr_t>(-1);
Val <<= PointerLikeTypeTraits<PointerTy>::NumLowBitsAvailable;
return Ty(reinterpret_cast<PointerTy>(Val), IntType((1 << IntBits)-1));
}
static Ty getTombstoneKey() {
- intptr_t Val = -2;
+ uintptr_t Val = static_cast<uintptr_t>(-2);
Val <<= PointerLikeTypeTraits<PointerTy>::NumLowBitsAvailable;
return Ty(reinterpret_cast<PointerTy>(Val), IntType(0));
}
diff --git a/include/llvm/ADT/SparseBitVector.h b/include/llvm/ADT/SparseBitVector.h
index 89774c3f56..791f1082c2 100644
--- a/include/llvm/ADT/SparseBitVector.h
+++ b/include/llvm/ADT/SparseBitVector.h
@@ -158,7 +158,7 @@ public:
&& "Word Position outside of element");
// Mask off previous bits.
- Copy &= ~0L << BitPos;
+ Copy &= ~0UL << BitPos;
if (Copy != 0) {
if (sizeof(BitWord) == 4)
diff --git a/include/llvm/CodeGen/MachineOperand.h b/include/llvm/CodeGen/MachineOperand.h
index 37d42b3583..c09d9f1251 100644
--- a/include/llvm/CodeGen/MachineOperand.h
+++ b/include/llvm/CodeGen/MachineOperand.h
@@ -421,7 +421,7 @@ public:
int64_t getOffset() const {
assert((isGlobal() || isSymbol() || isCPI() || isTargetIndex() ||
isBlockAddress()) && "Wrong MachineOperand accessor");
- return (int64_t(Contents.OffsetedInfo.OffsetHi) << 32) |
+ return int64_t(uint64_t(Contents.OffsetedInfo.OffsetHi) << 32) |
SmallContents.OffsetLo;
}
diff --git a/include/llvm/Support/MathExtras.h b/include/llvm/Support/MathExtras.h
index 4005161320..35c2694cff 100644
--- a/include/llvm/Support/MathExtras.h
+++ b/include/llvm/Support/MathExtras.h
@@ -463,12 +463,24 @@ template <unsigned B> inline int32_t SignExtend32(uint32_t x) {
return int32_t(x << (32 - B)) >> (32 - B);
}
+/// \brief Sign extend number in the bottom B bits of X to a 32-bit int.
+/// Requires 0 < B <= 32.
+inline int32_t SignExtend32(uint32_t X, unsigned B) {
+ return int32_t(X << (32 - B)) >> (32 - B);
+}
+
/// SignExtend64 - Sign extend B-bit number x to 64-bit int.
/// Usage int64_t r = SignExtend64<5>(x);
template <unsigned B> inline int64_t SignExtend64(uint64_t x) {
return int64_t(x << (64 - B)) >> (64 - B);
}
+/// \brief Sign extend number in the bottom B bits of X to a 64-bit int.
+/// Requires 0 < B <= 64.
+inline int64_t SignExtend64(uint64_t X, unsigned B) {
+ return int64_t(X << (64 - B)) >> (64 - B);
+}
+
} // End llvm namespace
#endif
diff --git a/lib/Analysis/ValueTracking.cpp b/lib/Analysis/ValueTracking.cpp
index cea34e16e7..491224a4b6 100644
--- a/lib/Analysis/ValueTracking.cpp
+++ b/lib/Analysis/ValueTracking.cpp
@@ -1614,7 +1614,7 @@ Value *llvm::GetPointerBaseWithConstantOffset(Value *Ptr, int64_t &Offset,
// right.
unsigned PtrSize = TD.getPointerSizeInBits();
if (PtrSize < 64)
- Offset = (Offset << (64-PtrSize)) >> (64-PtrSize);
+ Offset = SignExtend64(Offset, PtrSize);
return GetPointerBaseWithConstantOffset(GEP->getPointerOperand(), Offset, TD);
}
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 375bd7eb88..aa5d140e9f 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -1475,10 +1475,9 @@ static const MCExpr *LowerConstant(const Constant *CV, AsmPrinter &AP) {
return Base;
// Truncate/sext the offset to the pointer size.
- if (TD.getPointerSizeInBits() != 64) {
- int SExtAmount = 64-TD.getPointerSizeInBits();
- Offset = (Offset << SExtAmount) >> SExtAmount;
- }
+ unsigned Width = TD.getPointerSizeInBits();
+ if (Width < 64)
+ Offset = SignExtend64(Offset, Width);
return MCBinaryExpr::CreateAdd(Base, MCConstantExpr::Create(Offset, Ctx),
Ctx);
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index f4fe8927f6..3ab0b46def 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -1097,10 +1097,9 @@ SDValue SelectionDAG::getGlobalAddress(const GlobalValue *GV, DebugLoc DL,
"Cannot set target flags on target-independent globals");
// Truncate (with sign-extension) the offset value to the pointer size.
- EVT PTy = TLI.getPointerTy();
- unsigned BitWidth = PTy.getSizeInBits();
+ unsigned BitWidth = TLI.getPointerTy().getSizeInBits();
if (BitWidth < 64)
- Offset = (Offset << (64 - BitWidth) >> (64 - BitWidth));
+ Offset = SignExtend64(Offset, BitWidth);
const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV);
if (!GVar) {
diff --git a/lib/Support/regexec.c b/lib/Support/regexec.c
index 007861675b..bd5e72d4c5 100644
--- a/lib/Support/regexec.c
+++ b/lib/Support/regexec.c
@@ -69,7 +69,7 @@
#define SETUP(v) ((v) = 0)
#define onestate long
#define INIT(o, n) ((o) = (unsigned long)1 << (n))
-#define INC(o) ((o) <<= 1)
+#define INC(o) ((o) = (unsigned long)(o) << 1)
#define ISSTATEIN(v, o) (((v) & (o)) != 0)
/* some abbreviations; note that some of these know variable names! */
/* do "if I'm here, I can also be there" etc without branches */
diff --git a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
index c90751d0b9..c394ed1579 100644
--- a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
+++ b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
@@ -3170,7 +3170,7 @@ static DecodeStatus DecodeT2Imm8S4(MCInst &Inst, unsigned Val,
int imm = Val & 0xFF;
if (!(Val & 0x100)) imm *= -1;
- Inst.addOperand(MCOperand::CreateImm(imm << 2));
+ Inst.addOperand(MCOperand::CreateImm(imm * 4));
}
return MCDisassembler::Success;
diff --git a/lib/Target/CellSPU/SPUAsmPrinter.cpp b/lib/Target/CellSPU/SPUAsmPrinter.cpp
index 03d5a9ae0c..3396e8b1ef 100644
--- a/lib/Target/CellSPU/SPUAsmPrinter.cpp
+++ b/lib/Target/CellSPU/SPUAsmPrinter.cpp
@@ -130,8 +130,7 @@ namespace {
void
printS10ImmOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O)
{
- short value = (short) (((int) MI->getOperand(OpNo).getImm() << 16)
- >> 16);
+ short value = MI->getOperand(OpNo).getImm();
assert((value >= -(1 << 9) && value <= (1 << 9) - 1)
&& "Invalid s10 argument");
O << value;
@@ -140,8 +139,7 @@ namespace {
void
printU10ImmOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O)
{
- short value = (short) (((int) MI->getOperand(OpNo).getImm() << 16)
- >> 16);
+ short value = MI->getOperand(OpNo).getImm();
assert((value <= (1 << 10) - 1) && "Invalid u10 argument");
O << value;
}
diff --git a/lib/Target/CellSPU/SPUISelDAGToDAG.cpp b/lib/Target/CellSPU/SPUISelDAGToDAG.cpp
index c27caeae7d..425371d3e1 100644
--- a/lib/Target/CellSPU/SPUISelDAGToDAG.cpp
+++ b/lib/Target/CellSPU/SPUISelDAGToDAG.cpp
@@ -83,12 +83,10 @@ namespace {
return true;
} else if (vt == MVT::i32) {
int32_t i_val = (int32_t) CN->getZExtValue();
- short s_val = (short) i_val;
- return i_val == s_val;
+ return i_val == SignExtend32<16>(i_val);
} else {
int64_t i_val = (int64_t) CN->getZExtValue();
- short s_val = (short) i_val;
- return i_val == s_val;
+ return i_val == SignExtend64<16>(i_val);
}
}
@@ -99,9 +97,10 @@ namespace {
EVT vt = FPN->getValueType(0);
if (vt == MVT::f32) {
int val = FloatToBits(FPN->getValueAPF().convertToFloat());
- int sval = (int) ((val << 16) >> 16);
- Imm = (short) val;
- return val == sval;
+ if (val == SignExtend32<16>(val)) {
+ Imm = (short) val;
+ return true;
+ }
}
return false;
diff --git a/lib/Target/Mips/MipsAnalyzeImmediate.cpp b/lib/Target/Mips/MipsAnalyzeImmediate.cpp
index dc8fbd0d03..99b163ec33 100644
--- a/lib/Target/Mips/MipsAnalyzeImmediate.cpp
+++ b/lib/Target/Mips/MipsAnalyzeImmediate.cpp
@@ -91,7 +91,7 @@ void MipsAnalyzeImmediate::ReplaceADDiuSLLWithLUi(InstSeq &Seq) {
// Sign-extend and shift operand of ADDiu and see if it still fits in 16-bit.
int64_t Imm = SignExtend64<16>(Seq[0].ImmOpnd);
- int64_t ShiftedImm = Imm << (Seq[1].ImmOpnd - 16);
+ int64_t ShiftedImm = (uint64_t)Imm << (Seq[1].ImmOpnd - 16);
if (!isInt<16>(ShiftedImm))
return;
diff --git a/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp b/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp
index d175e3e79e..413142eb2b 100644
--- a/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp
+++ b/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp
@@ -137,7 +137,7 @@ void PPCInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNo,
void PPCInstPrinter::printS5ImmOperand(const MCInst *MI, unsigned OpNo,
raw_ostream &O) {
char Value = MI->getOperand(OpNo).getImm();
- Value = (Value << (32-5)) >> (32-5);
+ Value = SignExtend32<5>(Value);
O << (int)Value;
}
diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp
index c18ba69e71..88078246c1 100644
--- a/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -811,14 +811,13 @@ SDValue PPC::get_VSPLTI_elt(SDNode *N, unsigned ByteSize, SelectionDAG &DAG) {
}
// Properly sign extend the value.
- int ShAmt = (4-ByteSize)*8;
- int MaskVal = ((int)Value << ShAmt) >> ShAmt;
+ int MaskVal = SignExtend32(Value, ByteSize * 8);
// If this is zero, don't match, zero matches ISD::isBuildVectorAllZeros.
if (MaskVal == 0) return SDValue();
// Finally, if this value fits in a 5 bit sext field, return it
- if (((MaskVal << (32-5)) >> (32-5)) == MaskVal)
+ if (SignExtend32<5>(MaskVal) == MaskVal)
return DAG.getTargetConstant(MaskVal, MVT::i32);
return SDValue();
}
@@ -2424,7 +2423,7 @@ static SDNode *isBLACompatibleAddress(SDValue Op, SelectionDAG &DAG) {
int Addr = C->getZExtValue();
if ((Addr & 3) != 0 || // Low 2 bits are implicitly zero.
- (Addr << 6 >> 6) != Addr)
+ SignExtend32<26>(Addr) != Addr)
return 0; // Top 6 bits have to be sext of immediate.
return DAG.getConstant((int)C->getZExtValue() >> 2,
@@ -4142,7 +4141,7 @@ SDValue PPCTargetLowering::LowerBUILD_VECTOR(SDValue Op,
unsigned TypeShiftAmt = i & (SplatBitSize-1);
// vsplti + shl self.
- if (SextVal == (i << (int)TypeShiftAmt)) {
+ if (SextVal == (int)((unsigned)i << TypeShiftAmt)) {
SDValue Res = BuildSplatI(i, SplatSize, MVT::Other, DAG, dl);
static const unsigned IIDs[] = { // Intrinsic to use for each size.
Intrinsic::ppc_altivec_vslb, Intrinsic::ppc_altivec_vslh, 0,
@@ -4187,17 +4186,17 @@ SDValue PPCTargetLowering::LowerBUILD_VECTOR(SDValue Op,
}
// t = vsplti c, result = vsldoi t, t, 1
- if (SextVal == ((i << 8) | (i < 0 ? 0xFF : 0))) {
+ if (SextVal == (int)(((unsigned)i << 8) | (i < 0 ? 0xFF : 0))) {
SDValue T = BuildSplatI(i, SplatSize, MVT::v16i8, DAG, dl);
return BuildVSLDOI(T, T, 1, Op.getValueType(), DAG, dl);
}
// t = vsplti c, result = vsldoi t, t, 2
- if (SextVal == ((i << 16) | (i < 0 ? 0xFFFF : 0))) {
+ if (SextVal == (int)(((unsigned)i << 16) | (i < 0 ? 0xFFFF : 0))) {
SDValue T = BuildSplatI(i, SplatSize, MVT::v16i8, DAG, dl);
return BuildVSLDOI(T, T, 2, Op.getValueType(), DAG, dl);
}
// t = vsplti c, result = vsldoi t, t, 3
- if (SextVal == ((i << 24) | (i < 0 ? 0xFFFFFF : 0))) {
+ if (SextVal == (int)(((unsigned)i << 24) | (i < 0 ? 0xFFFFFF : 0))) {
SDValue T = BuildSplatI(i, SplatSize, MVT::v16i8, DAG, dl);
return BuildVSLDOI(T, T, 3, Op.getValueType(), DAG, dl);
}
diff --git a/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c b/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c
index 0c929122ae..c8d45ff938 100644
--- a/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c
+++ b/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c
@@ -200,7 +200,7 @@ static void unconsumeByte(struct InternalInstruction* insn) {
insn->readerCursor + offset); \
if (ret) \
return ret; \
- combined = combined | ((type)byte << ((type)offset * 8)); \
+ combined = combined | ((uint64_t)byte << (offset * 8)); \
} \
*ptr = combined; \
insn->readerCursor += sizeof(type); \
diff --git a/lib/Target/X86/X86ISelDAGToDAG.cpp b/lib/Target/X86/X86ISelDAGToDAG.cpp
index 27195b4522..b7b400236e 100644
--- a/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ b/lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -1011,7 +1011,7 @@ bool X86DAGToDAGISel::MatchAddressRecursively(SDValue N, X86ISelAddressMode &AM,
AM.IndexReg = ShVal.getNode()->getOperand(0);
ConstantSDNode *AddVal =
cast<ConstantSDNode>(ShVal.getNode()->getOperand(1));
- uint64_t Disp = AddVal->getSExtValue() << Val;
+ uint64_t Disp = (uint64_t)AddVal->getSExtValue() << Val;
if (!FoldOffsetIntoAddress(Disp, AM))
return false;
}
@@ -2116,7 +2116,8 @@ SDNode *X86DAGToDAGISel::Select(SDNode *Node) {
// Make sure that we don't change the operation by removing bits.
// This only matters for OR and XOR, AND is unaffected.
- if (Opcode != ISD::AND && ((Val >> ShlVal) << ShlVal) != Val)
+ uint64_t RemovedBitsMask = (1ULL << ShlVal) - 1;
+ if (Opcode != ISD::AND && (Val & RemovedBitsMask) != 0)
break;
unsigned ShlOp, Op;
diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp
index 52254187d4..0842c0016d 100644
--- a/utils/TableGen/CodeGenDAGPatterns.cpp
+++ b/utils/TableGen/CodeGenDAGPatterns.cpp
@@ -1410,19 +1410,13 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
// Make sure that the value is representable for this type.
if (Size >= 32) return MadeChange;
- int Val = (II->getValue() << (32-Size)) >> (32-Size);
- if (Val == II->getValue()) return MadeChange;
-
- // If sign-extended doesn't fit, does it fit as unsigned?
- unsigned ValueMask;
- unsigned UnsignedVal;
- ValueMask = unsigned(~uint32_t(0UL) >> (32-Size));
- UnsignedVal = unsigned(II->getValue());
-
- if ((ValueMask & UnsignedVal) == UnsignedVal)
+ // Check that the value doesn't use more bits than we have. It must either
+ // be a sign- or zero-extended equivalent of the original.
+ int64_t SignBitAndAbove = II->getValue() >> (Size - 1);
+ if (SignBitAndAbove == -1 || SignBitAndAbove == 0 || SignBitAndAbove == 1)
return MadeChange;
- TP.error("Integer value '" + itostr(II->getValue())+
+ TP.error("Integer value '" + itostr(II->getValue()) +
"' is out of range for type '" + getEnumName(getType(0)) + "'!");
return MadeChange;
}
@@ -3400,4 +3394,3 @@ void CodeGenDAGPatterns::GenerateVariants() {
DEBUG(errs() << "\n");
}
}
-