Merge llvm, clang, compiler-rt, libc++, lld and lldb release_40 branch
r292951, and update build glue.
This commit is contained in:
commit
f8496407cb
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/projects/clang400-import/; revision=312719
@ -115,7 +115,7 @@
|
||||
#endif
|
||||
|
||||
#ifndef _LIBCPP_CLANG_VER
|
||||
#define _LIBCPP_CLANG_VER 0
|
||||
# define _LIBCPP_CLANG_VER 0
|
||||
#endif
|
||||
|
||||
// FIXME: ABI detection should be done via compiler builtin macros. This
|
||||
@ -845,7 +845,7 @@ template <unsigned> struct __static_assert_check {};
|
||||
#if defined(__APPLE__)
|
||||
# if !defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && \
|
||||
defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__)
|
||||
# define __MAC_OS_X_VERSION_MIN_REQUIRED __ENVIROMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
|
||||
# define __MAC_OS_X_VERSION_MIN_REQUIRED __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
|
||||
# endif
|
||||
# if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
|
||||
# if __MAC_OS_X_VERSION_MIN_REQUIRED < 1060
|
||||
|
@ -512,7 +512,7 @@ class BitcodeReader : public BitcodeReaderBase, public GVMaterializer {
|
||||
}
|
||||
|
||||
Metadata *getFnMetadataByID(unsigned ID) {
|
||||
return MDLoader->getMetadataFwdRef(ID);
|
||||
return MDLoader->getMetadataFwdRefOrLoad(ID);
|
||||
}
|
||||
|
||||
BasicBlock *getBasicBlock(unsigned ID) const {
|
||||
|
@ -485,8 +485,21 @@ class MetadataLoader::MetadataLoaderImpl {
|
||||
Error parseMetadata(bool ModuleLevel);
|
||||
|
||||
bool hasFwdRefs() const { return MetadataList.hasFwdRefs(); }
|
||||
Metadata *getMetadataFwdRef(unsigned Idx) {
|
||||
return MetadataList.getMetadataFwdRef(Idx);
|
||||
|
||||
Metadata *getMetadataFwdRefOrLoad(unsigned ID) {
|
||||
if (ID < MDStringRef.size())
|
||||
return lazyLoadOneMDString(ID);
|
||||
if (auto *MD = MetadataList.lookup(ID))
|
||||
return MD;
|
||||
// If lazy-loading is enabled, we try recursively to load the operand
|
||||
// instead of creating a temporary.
|
||||
if (ID < (MDStringRef.size() + GlobalMetadataBitPosIndex.size())) {
|
||||
PlaceholderQueue Placeholders;
|
||||
lazyLoadOneMetadata(ID, Placeholders);
|
||||
resolveForwardRefsAndPlaceholders(Placeholders);
|
||||
return MetadataList.lookup(ID);
|
||||
}
|
||||
return MetadataList.getMetadataFwdRef(ID);
|
||||
}
|
||||
|
||||
MDNode *getMDNodeFwdRefOrNull(unsigned Idx) {
|
||||
@ -1727,8 +1740,8 @@ bool MetadataLoader::hasFwdRefs() const { return Pimpl->hasFwdRefs(); }
|
||||
|
||||
/// Return the given metadata, creating a replaceable forward reference if
|
||||
/// necessary.
|
||||
Metadata *MetadataLoader::getMetadataFwdRef(unsigned Idx) {
|
||||
return Pimpl->getMetadataFwdRef(Idx);
|
||||
Metadata *MetadataLoader::getMetadataFwdRefOrLoad(unsigned Idx) {
|
||||
return Pimpl->getMetadataFwdRefOrLoad(Idx);
|
||||
}
|
||||
|
||||
MDNode *MetadataLoader::getMDNodeFwdRefOrNull(unsigned Idx) {
|
||||
|
@ -63,7 +63,7 @@ class MetadataLoader {
|
||||
|
||||
/// Return the given metadata, creating a replaceable forward reference if
|
||||
/// necessary.
|
||||
Metadata *getMetadataFwdRef(unsigned Idx);
|
||||
Metadata *getMetadataFwdRefOrLoad(unsigned Idx);
|
||||
|
||||
MDNode *getMDNodeFwdRefOrNull(unsigned Idx);
|
||||
|
||||
|
@ -687,9 +687,30 @@ AArch64LoadStoreOpt::mergePairedInsns(MachineBasicBlock::iterator I,
|
||||
MachineInstrBuilder MIB;
|
||||
DebugLoc DL = I->getDebugLoc();
|
||||
MachineBasicBlock *MBB = I->getParent();
|
||||
MachineOperand RegOp0 = getLdStRegOp(*RtMI);
|
||||
MachineOperand RegOp1 = getLdStRegOp(*Rt2MI);
|
||||
// Kill flags may become invalid when moving stores for pairing.
|
||||
if (RegOp0.isUse()) {
|
||||
if (!MergeForward) {
|
||||
// Clear kill flags on store if moving upwards. Example:
|
||||
// STRWui %w0, ...
|
||||
// USE %w1
|
||||
// STRWui kill %w1 ; need to clear kill flag when moving STRWui upwards
|
||||
RegOp0.setIsKill(false);
|
||||
RegOp1.setIsKill(false);
|
||||
} else {
|
||||
// Clear kill flags of the first stores register. Example:
|
||||
// STRWui %w1, ...
|
||||
// USE kill %w1 ; need to clear kill flag when moving STRWui downwards
|
||||
// STRW %w0
|
||||
unsigned Reg = getLdStRegOp(*I).getReg();
|
||||
for (MachineInstr &MI : make_range(std::next(I), Paired))
|
||||
MI.clearRegisterKills(Reg, TRI);
|
||||
}
|
||||
}
|
||||
MIB = BuildMI(*MBB, InsertionPoint, DL, TII->get(getMatchingPairOpcode(Opc)))
|
||||
.addOperand(getLdStRegOp(*RtMI))
|
||||
.addOperand(getLdStRegOp(*Rt2MI))
|
||||
.addOperand(RegOp0)
|
||||
.addOperand(RegOp1)
|
||||
.addOperand(BaseRegOp)
|
||||
.addImm(OffsetImm)
|
||||
.setMemRefs(I->mergeMemRefsWith(*Paired));
|
||||
|
@ -97,171 +97,6 @@ namespace {
|
||||
};
|
||||
}
|
||||
|
||||
void ARMTargetLowering::InitLibcallCallingConvs() {
|
||||
// The builtins on ARM always use AAPCS, irrespective of wheter C is AAPCS or
|
||||
// AAPCS_VFP.
|
||||
for (const auto LC : {
|
||||
RTLIB::SHL_I16,
|
||||
RTLIB::SHL_I32,
|
||||
RTLIB::SHL_I64,
|
||||
RTLIB::SHL_I128,
|
||||
RTLIB::SRL_I16,
|
||||
RTLIB::SRL_I32,
|
||||
RTLIB::SRL_I64,
|
||||
RTLIB::SRL_I128,
|
||||
RTLIB::SRA_I16,
|
||||
RTLIB::SRA_I32,
|
||||
RTLIB::SRA_I64,
|
||||
RTLIB::SRA_I128,
|
||||
RTLIB::MUL_I8,
|
||||
RTLIB::MUL_I16,
|
||||
RTLIB::MUL_I32,
|
||||
RTLIB::MUL_I64,
|
||||
RTLIB::MUL_I128,
|
||||
RTLIB::MULO_I32,
|
||||
RTLIB::MULO_I64,
|
||||
RTLIB::MULO_I128,
|
||||
RTLIB::SDIV_I8,
|
||||
RTLIB::SDIV_I16,
|
||||
RTLIB::SDIV_I32,
|
||||
RTLIB::SDIV_I64,
|
||||
RTLIB::SDIV_I128,
|
||||
RTLIB::UDIV_I8,
|
||||
RTLIB::UDIV_I16,
|
||||
RTLIB::UDIV_I32,
|
||||
RTLIB::UDIV_I64,
|
||||
RTLIB::UDIV_I128,
|
||||
RTLIB::SREM_I8,
|
||||
RTLIB::SREM_I16,
|
||||
RTLIB::SREM_I32,
|
||||
RTLIB::SREM_I64,
|
||||
RTLIB::SREM_I128,
|
||||
RTLIB::UREM_I8,
|
||||
RTLIB::UREM_I16,
|
||||
RTLIB::UREM_I32,
|
||||
RTLIB::UREM_I64,
|
||||
RTLIB::UREM_I128,
|
||||
RTLIB::SDIVREM_I8,
|
||||
RTLIB::SDIVREM_I16,
|
||||
RTLIB::SDIVREM_I32,
|
||||
RTLIB::SDIVREM_I64,
|
||||
RTLIB::SDIVREM_I128,
|
||||
RTLIB::UDIVREM_I8,
|
||||
RTLIB::UDIVREM_I16,
|
||||
RTLIB::UDIVREM_I32,
|
||||
RTLIB::UDIVREM_I64,
|
||||
RTLIB::UDIVREM_I128,
|
||||
RTLIB::NEG_I32,
|
||||
RTLIB::NEG_I64,
|
||||
RTLIB::ADD_F32,
|
||||
RTLIB::ADD_F64,
|
||||
RTLIB::ADD_F80,
|
||||
RTLIB::ADD_F128,
|
||||
RTLIB::SUB_F32,
|
||||
RTLIB::SUB_F64,
|
||||
RTLIB::SUB_F80,
|
||||
RTLIB::SUB_F128,
|
||||
RTLIB::MUL_F32,
|
||||
RTLIB::MUL_F64,
|
||||
RTLIB::MUL_F80,
|
||||
RTLIB::MUL_F128,
|
||||
RTLIB::DIV_F32,
|
||||
RTLIB::DIV_F64,
|
||||
RTLIB::DIV_F80,
|
||||
RTLIB::DIV_F128,
|
||||
RTLIB::POWI_F32,
|
||||
RTLIB::POWI_F64,
|
||||
RTLIB::POWI_F80,
|
||||
RTLIB::POWI_F128,
|
||||
RTLIB::FPEXT_F64_F128,
|
||||
RTLIB::FPEXT_F32_F128,
|
||||
RTLIB::FPEXT_F32_F64,
|
||||
RTLIB::FPEXT_F16_F32,
|
||||
RTLIB::FPROUND_F32_F16,
|
||||
RTLIB::FPROUND_F64_F16,
|
||||
RTLIB::FPROUND_F80_F16,
|
||||
RTLIB::FPROUND_F128_F16,
|
||||
RTLIB::FPROUND_F64_F32,
|
||||
RTLIB::FPROUND_F80_F32,
|
||||
RTLIB::FPROUND_F128_F32,
|
||||
RTLIB::FPROUND_F80_F64,
|
||||
RTLIB::FPROUND_F128_F64,
|
||||
RTLIB::FPTOSINT_F32_I32,
|
||||
RTLIB::FPTOSINT_F32_I64,
|
||||
RTLIB::FPTOSINT_F32_I128,
|
||||
RTLIB::FPTOSINT_F64_I32,
|
||||
RTLIB::FPTOSINT_F64_I64,
|
||||
RTLIB::FPTOSINT_F64_I128,
|
||||
RTLIB::FPTOSINT_F80_I32,
|
||||
RTLIB::FPTOSINT_F80_I64,
|
||||
RTLIB::FPTOSINT_F80_I128,
|
||||
RTLIB::FPTOSINT_F128_I32,
|
||||
RTLIB::FPTOSINT_F128_I64,
|
||||
RTLIB::FPTOSINT_F128_I128,
|
||||
RTLIB::FPTOUINT_F32_I32,
|
||||
RTLIB::FPTOUINT_F32_I64,
|
||||
RTLIB::FPTOUINT_F32_I128,
|
||||
RTLIB::FPTOUINT_F64_I32,
|
||||
RTLIB::FPTOUINT_F64_I64,
|
||||
RTLIB::FPTOUINT_F64_I128,
|
||||
RTLIB::FPTOUINT_F80_I32,
|
||||
RTLIB::FPTOUINT_F80_I64,
|
||||
RTLIB::FPTOUINT_F80_I128,
|
||||
RTLIB::FPTOUINT_F128_I32,
|
||||
RTLIB::FPTOUINT_F128_I64,
|
||||
RTLIB::FPTOUINT_F128_I128,
|
||||
RTLIB::SINTTOFP_I32_F32,
|
||||
RTLIB::SINTTOFP_I32_F64,
|
||||
RTLIB::SINTTOFP_I32_F80,
|
||||
RTLIB::SINTTOFP_I32_F128,
|
||||
RTLIB::SINTTOFP_I64_F32,
|
||||
RTLIB::SINTTOFP_I64_F64,
|
||||
RTLIB::SINTTOFP_I64_F80,
|
||||
RTLIB::SINTTOFP_I64_F128,
|
||||
RTLIB::SINTTOFP_I128_F32,
|
||||
RTLIB::SINTTOFP_I128_F64,
|
||||
RTLIB::SINTTOFP_I128_F80,
|
||||
RTLIB::SINTTOFP_I128_F128,
|
||||
RTLIB::UINTTOFP_I32_F32,
|
||||
RTLIB::UINTTOFP_I32_F64,
|
||||
RTLIB::UINTTOFP_I32_F80,
|
||||
RTLIB::UINTTOFP_I32_F128,
|
||||
RTLIB::UINTTOFP_I64_F32,
|
||||
RTLIB::UINTTOFP_I64_F64,
|
||||
RTLIB::UINTTOFP_I64_F80,
|
||||
RTLIB::UINTTOFP_I64_F128,
|
||||
RTLIB::UINTTOFP_I128_F32,
|
||||
RTLIB::UINTTOFP_I128_F64,
|
||||
RTLIB::UINTTOFP_I128_F80,
|
||||
RTLIB::UINTTOFP_I128_F128,
|
||||
RTLIB::OEQ_F32,
|
||||
RTLIB::OEQ_F64,
|
||||
RTLIB::OEQ_F128,
|
||||
RTLIB::UNE_F32,
|
||||
RTLIB::UNE_F64,
|
||||
RTLIB::UNE_F128,
|
||||
RTLIB::OGE_F32,
|
||||
RTLIB::OGE_F64,
|
||||
RTLIB::OGE_F128,
|
||||
RTLIB::OLT_F32,
|
||||
RTLIB::OLT_F64,
|
||||
RTLIB::OLT_F128,
|
||||
RTLIB::OLE_F32,
|
||||
RTLIB::OLE_F64,
|
||||
RTLIB::OLE_F128,
|
||||
RTLIB::OGT_F32,
|
||||
RTLIB::OGT_F64,
|
||||
RTLIB::OGT_F128,
|
||||
RTLIB::UO_F32,
|
||||
RTLIB::UO_F64,
|
||||
RTLIB::UO_F128,
|
||||
RTLIB::O_F32,
|
||||
RTLIB::O_F64,
|
||||
RTLIB::O_F128,
|
||||
})
|
||||
setLibcallCallingConv(LC, CallingConv::ARM_AAPCS);
|
||||
}
|
||||
|
||||
// The APCS parameter registers.
|
||||
static const MCPhysReg GPRArgRegs[] = {
|
||||
ARM::R0, ARM::R1, ARM::R2, ARM::R3
|
||||
@ -349,7 +184,22 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM,
|
||||
|
||||
setBooleanVectorContents(ZeroOrNegativeOneBooleanContent);
|
||||
|
||||
InitLibcallCallingConvs();
|
||||
if (!Subtarget->isTargetDarwin() && !Subtarget->isTargetIOS() &&
|
||||
!Subtarget->isTargetWatchOS()) {
|
||||
const auto &E = Subtarget->getTargetTriple().getEnvironment();
|
||||
|
||||
bool IsHFTarget = E == Triple::EABIHF || E == Triple::GNUEABIHF ||
|
||||
E == Triple::MuslEABIHF;
|
||||
// Windows is a special case. Technically, we will replace all of the "GNU"
|
||||
// calls with calls to MSVCRT if appropriate and adjust the calling
|
||||
// convention then.
|
||||
IsHFTarget = IsHFTarget || Subtarget->isTargetWindows();
|
||||
|
||||
for (int LCID = 0; LCID < RTLIB::UNKNOWN_LIBCALL; ++LCID)
|
||||
setLibcallCallingConv(static_cast<RTLIB::Libcall>(LCID),
|
||||
IsHFTarget ? CallingConv::ARM_AAPCS_VFP
|
||||
: CallingConv::ARM_AAPCS);
|
||||
}
|
||||
|
||||
if (Subtarget->isTargetMachO()) {
|
||||
// Uses VFP for Thumb libfuncs if available.
|
||||
|
@ -538,8 +538,6 @@ class InstrItineraryData;
|
||||
|
||||
bool HasStandaloneRem = true;
|
||||
|
||||
void InitLibcallCallingConvs();
|
||||
|
||||
void addTypeForNEON(MVT VT, MVT PromotedLdStVT, MVT PromotedBitwiseVT);
|
||||
void addDRTypeForNEON(MVT VT);
|
||||
void addQRTypeForNEON(MVT VT);
|
||||
|
@ -600,6 +600,22 @@ class AddressSanitizerModule : public ModulePass {
|
||||
void initializeCallbacks(Module &M);
|
||||
|
||||
bool InstrumentGlobals(IRBuilder<> &IRB, Module &M);
|
||||
void InstrumentGlobalsCOFF(IRBuilder<> &IRB, Module &M,
|
||||
ArrayRef<GlobalVariable *> ExtendedGlobals,
|
||||
ArrayRef<Constant *> MetadataInitializers);
|
||||
void InstrumentGlobalsMachO(IRBuilder<> &IRB, Module &M,
|
||||
ArrayRef<GlobalVariable *> ExtendedGlobals,
|
||||
ArrayRef<Constant *> MetadataInitializers);
|
||||
void
|
||||
InstrumentGlobalsWithMetadataArray(IRBuilder<> &IRB, Module &M,
|
||||
ArrayRef<GlobalVariable *> ExtendedGlobals,
|
||||
ArrayRef<Constant *> MetadataInitializers);
|
||||
|
||||
GlobalVariable *CreateMetadataGlobal(Module &M, Constant *Initializer,
|
||||
StringRef OriginalName);
|
||||
void SetComdatForGlobalMetadata(GlobalVariable *G, GlobalVariable *Metadata);
|
||||
IRBuilder<> CreateAsanModuleDtor(Module &M);
|
||||
|
||||
bool ShouldInstrumentGlobal(GlobalVariable *G);
|
||||
bool ShouldUseMachOGlobalsSection() const;
|
||||
StringRef getGlobalMetadataSection() const;
|
||||
@ -1553,17 +1569,173 @@ void AddressSanitizerModule::initializeCallbacks(Module &M) {
|
||||
|
||||
// Declare the functions that find globals in a shared object and then invoke
|
||||
// the (un)register function on them.
|
||||
AsanRegisterImageGlobals = checkSanitizerInterfaceFunction(
|
||||
M.getOrInsertFunction(kAsanRegisterImageGlobalsName,
|
||||
IRB.getVoidTy(), IntptrTy, nullptr));
|
||||
AsanRegisterImageGlobals =
|
||||
checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
kAsanRegisterImageGlobalsName, IRB.getVoidTy(), IntptrTy, nullptr));
|
||||
AsanRegisterImageGlobals->setLinkage(Function::ExternalLinkage);
|
||||
|
||||
AsanUnregisterImageGlobals = checkSanitizerInterfaceFunction(
|
||||
M.getOrInsertFunction(kAsanUnregisterImageGlobalsName,
|
||||
IRB.getVoidTy(), IntptrTy, nullptr));
|
||||
AsanUnregisterImageGlobals =
|
||||
checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
kAsanUnregisterImageGlobalsName, IRB.getVoidTy(), IntptrTy, nullptr));
|
||||
AsanUnregisterImageGlobals->setLinkage(Function::ExternalLinkage);
|
||||
}
|
||||
|
||||
// Put the metadata and the instrumented global in the same group. This ensures
|
||||
// that the metadata is discarded if the instrumented global is discarded.
|
||||
void AddressSanitizerModule::SetComdatForGlobalMetadata(
|
||||
GlobalVariable *G, GlobalVariable *Metadata) {
|
||||
Module &M = *G->getParent();
|
||||
Comdat *C = G->getComdat();
|
||||
if (!C) {
|
||||
if (!G->hasName()) {
|
||||
// If G is unnamed, it must be internal. Give it an artificial name
|
||||
// so we can put it in a comdat.
|
||||
assert(G->hasLocalLinkage());
|
||||
G->setName(Twine(kAsanGenPrefix) + "_anon_global");
|
||||
}
|
||||
C = M.getOrInsertComdat(G->getName());
|
||||
// Make this IMAGE_COMDAT_SELECT_NODUPLICATES on COFF.
|
||||
if (TargetTriple.isOSBinFormatCOFF())
|
||||
C->setSelectionKind(Comdat::NoDuplicates);
|
||||
G->setComdat(C);
|
||||
}
|
||||
|
||||
assert(G->hasComdat());
|
||||
Metadata->setComdat(G->getComdat());
|
||||
}
|
||||
|
||||
// Create a separate metadata global and put it in the appropriate ASan
|
||||
// global registration section.
|
||||
GlobalVariable *
|
||||
AddressSanitizerModule::CreateMetadataGlobal(Module &M, Constant *Initializer,
|
||||
StringRef OriginalName) {
|
||||
GlobalVariable *Metadata =
|
||||
new GlobalVariable(M, Initializer->getType(), false,
|
||||
GlobalVariable::InternalLinkage, Initializer,
|
||||
Twine("__asan_global_") +
|
||||
GlobalValue::getRealLinkageName(OriginalName));
|
||||
Metadata->setSection(getGlobalMetadataSection());
|
||||
return Metadata;
|
||||
}
|
||||
|
||||
IRBuilder<> AddressSanitizerModule::CreateAsanModuleDtor(Module &M) {
|
||||
Function *AsanDtorFunction =
|
||||
Function::Create(FunctionType::get(Type::getVoidTy(*C), false),
|
||||
GlobalValue::InternalLinkage, kAsanModuleDtorName, &M);
|
||||
BasicBlock *AsanDtorBB = BasicBlock::Create(*C, "", AsanDtorFunction);
|
||||
appendToGlobalDtors(M, AsanDtorFunction, kAsanCtorAndDtorPriority);
|
||||
|
||||
return IRBuilder<>(ReturnInst::Create(*C, AsanDtorBB));
|
||||
}
|
||||
|
||||
void AddressSanitizerModule::InstrumentGlobalsCOFF(
|
||||
IRBuilder<> &IRB, Module &M, ArrayRef<GlobalVariable *> ExtendedGlobals,
|
||||
ArrayRef<Constant *> MetadataInitializers) {
|
||||
assert(ExtendedGlobals.size() == MetadataInitializers.size());
|
||||
auto &DL = M.getDataLayout();
|
||||
|
||||
for (size_t i = 0; i < ExtendedGlobals.size(); i++) {
|
||||
Constant *Initializer = MetadataInitializers[i];
|
||||
GlobalVariable *G = ExtendedGlobals[i];
|
||||
GlobalVariable *Metadata =
|
||||
CreateMetadataGlobal(M, Initializer, G->getName());
|
||||
|
||||
// The MSVC linker always inserts padding when linking incrementally. We
|
||||
// cope with that by aligning each struct to its size, which must be a power
|
||||
// of two.
|
||||
unsigned SizeOfGlobalStruct = DL.getTypeAllocSize(Initializer->getType());
|
||||
assert(isPowerOf2_32(SizeOfGlobalStruct) &&
|
||||
"global metadata will not be padded appropriately");
|
||||
Metadata->setAlignment(SizeOfGlobalStruct);
|
||||
|
||||
SetComdatForGlobalMetadata(G, Metadata);
|
||||
}
|
||||
}
|
||||
|
||||
void AddressSanitizerModule::InstrumentGlobalsMachO(
|
||||
IRBuilder<> &IRB, Module &M, ArrayRef<GlobalVariable *> ExtendedGlobals,
|
||||
ArrayRef<Constant *> MetadataInitializers) {
|
||||
assert(ExtendedGlobals.size() == MetadataInitializers.size());
|
||||
|
||||
// On recent Mach-O platforms, use a structure which binds the liveness of
|
||||
// the global variable to the metadata struct. Keep the list of "Liveness" GV
|
||||
// created to be added to llvm.compiler.used
|
||||
StructType *LivenessTy = StructType::get(IntptrTy, IntptrTy, nullptr);
|
||||
SmallVector<GlobalValue *, 16> LivenessGlobals(ExtendedGlobals.size());
|
||||
|
||||
for (size_t i = 0; i < ExtendedGlobals.size(); i++) {
|
||||
Constant *Initializer = MetadataInitializers[i];
|
||||
GlobalVariable *G = ExtendedGlobals[i];
|
||||
GlobalVariable *Metadata =
|
||||
CreateMetadataGlobal(M, Initializer, G->getName());
|
||||
|
||||
// On recent Mach-O platforms, we emit the global metadata in a way that
|
||||
// allows the linker to properly strip dead globals.
|
||||
auto LivenessBinder = ConstantStruct::get(
|
||||
LivenessTy, Initializer->getAggregateElement(0u),
|
||||
ConstantExpr::getPointerCast(Metadata, IntptrTy), nullptr);
|
||||
GlobalVariable *Liveness = new GlobalVariable(
|
||||
M, LivenessTy, false, GlobalVariable::InternalLinkage, LivenessBinder,
|
||||
Twine("__asan_binder_") + G->getName());
|
||||
Liveness->setSection("__DATA,__asan_liveness,regular,live_support");
|
||||
LivenessGlobals[i] = Liveness;
|
||||
}
|
||||
|
||||
// Update llvm.compiler.used, adding the new liveness globals. This is
|
||||
// needed so that during LTO these variables stay alive. The alternative
|
||||
// would be to have the linker handling the LTO symbols, but libLTO
|
||||
// current API does not expose access to the section for each symbol.
|
||||
if (!LivenessGlobals.empty())
|
||||
appendToCompilerUsed(M, LivenessGlobals);
|
||||
|
||||
// RegisteredFlag serves two purposes. First, we can pass it to dladdr()
|
||||
// to look up the loaded image that contains it. Second, we can store in it
|
||||
// whether registration has already occurred, to prevent duplicate
|
||||
// registration.
|
||||
//
|
||||
// common linkage ensures that there is only one global per shared library.
|
||||
GlobalVariable *RegisteredFlag = new GlobalVariable(
|
||||
M, IntptrTy, false, GlobalVariable::CommonLinkage,
|
||||
ConstantInt::get(IntptrTy, 0), kAsanGlobalsRegisteredFlagName);
|
||||
RegisteredFlag->setVisibility(GlobalVariable::HiddenVisibility);
|
||||
|
||||
IRB.CreateCall(AsanRegisterImageGlobals,
|
||||
{IRB.CreatePointerCast(RegisteredFlag, IntptrTy)});
|
||||
|
||||
// We also need to unregister globals at the end, e.g., when a shared library
|
||||
// gets closed.
|
||||
IRBuilder<> IRB_Dtor = CreateAsanModuleDtor(M);
|
||||
IRB_Dtor.CreateCall(AsanUnregisterImageGlobals,
|
||||
{IRB.CreatePointerCast(RegisteredFlag, IntptrTy)});
|
||||
}
|
||||
|
||||
void AddressSanitizerModule::InstrumentGlobalsWithMetadataArray(
|
||||
IRBuilder<> &IRB, Module &M, ArrayRef<GlobalVariable *> ExtendedGlobals,
|
||||
ArrayRef<Constant *> MetadataInitializers) {
|
||||
assert(ExtendedGlobals.size() == MetadataInitializers.size());
|
||||
unsigned N = ExtendedGlobals.size();
|
||||
assert(N > 0);
|
||||
|
||||
// On platforms that don't have a custom metadata section, we emit an array
|
||||
// of global metadata structures.
|
||||
ArrayType *ArrayOfGlobalStructTy =
|
||||
ArrayType::get(MetadataInitializers[0]->getType(), N);
|
||||
auto AllGlobals = new GlobalVariable(
|
||||
M, ArrayOfGlobalStructTy, false, GlobalVariable::InternalLinkage,
|
||||
ConstantArray::get(ArrayOfGlobalStructTy, MetadataInitializers), "");
|
||||
|
||||
IRB.CreateCall(AsanRegisterGlobals,
|
||||
{IRB.CreatePointerCast(AllGlobals, IntptrTy),
|
||||
ConstantInt::get(IntptrTy, N)});
|
||||
|
||||
// We also need to unregister globals at the end, e.g., when a shared library
|
||||
// gets closed.
|
||||
IRBuilder<> IRB_Dtor = CreateAsanModuleDtor(M);
|
||||
IRB_Dtor.CreateCall(AsanUnregisterGlobals,
|
||||
{IRB.CreatePointerCast(AllGlobals, IntptrTy),
|
||||
ConstantInt::get(IntptrTy, N)});
|
||||
}
|
||||
|
||||
// This function replaces all global variables with new variables that have
|
||||
// trailing redzones. It also creates a function that poisons
|
||||
// redzones and inserts this function into llvm.global_ctors.
|
||||
@ -1580,9 +1752,6 @@ bool AddressSanitizerModule::InstrumentGlobals(IRBuilder<> &IRB, Module &M) {
|
||||
if (n == 0) return false;
|
||||
|
||||
auto &DL = M.getDataLayout();
|
||||
bool UseComdatMetadata = TargetTriple.isOSBinFormatCOFF();
|
||||
bool UseMachOGlobalsSection = ShouldUseMachOGlobalsSection();
|
||||
bool UseMetadataArray = !(UseComdatMetadata || UseMachOGlobalsSection);
|
||||
|
||||
// A global is described by a structure
|
||||
// size_t beg;
|
||||
@ -1597,19 +1766,8 @@ bool AddressSanitizerModule::InstrumentGlobals(IRBuilder<> &IRB, Module &M) {
|
||||
StructType *GlobalStructTy =
|
||||
StructType::get(IntptrTy, IntptrTy, IntptrTy, IntptrTy, IntptrTy,
|
||||
IntptrTy, IntptrTy, IntptrTy, nullptr);
|
||||
unsigned SizeOfGlobalStruct = DL.getTypeAllocSize(GlobalStructTy);
|
||||
assert(isPowerOf2_32(SizeOfGlobalStruct) &&
|
||||
"global metadata will not be padded appropriately");
|
||||
SmallVector<Constant *, 16> Initializers(UseMetadataArray ? n : 0);
|
||||
|
||||
// On recent Mach-O platforms, use a structure which binds the liveness of
|
||||
// the global variable to the metadata struct. Keep the list of "Liveness" GV
|
||||
// created to be added to llvm.compiler.used
|
||||
StructType *LivenessTy = nullptr;
|
||||
if (UseMachOGlobalsSection)
|
||||
LivenessTy = StructType::get(IntptrTy, IntptrTy, nullptr);
|
||||
SmallVector<GlobalValue *, 16> LivenessGlobals(
|
||||
UseMachOGlobalsSection ? n : 0);
|
||||
SmallVector<GlobalVariable *, 16> NewGlobals(n);
|
||||
SmallVector<Constant *, 16> Initializers(n);
|
||||
|
||||
bool HasDynamicallyInitializedGlobals = false;
|
||||
|
||||
@ -1681,25 +1839,7 @@ bool AddressSanitizerModule::InstrumentGlobals(IRBuilder<> &IRB, Module &M) {
|
||||
ConstantExpr::getGetElementPtr(NewTy, NewGlobal, Indices2, true));
|
||||
NewGlobal->takeName(G);
|
||||
G->eraseFromParent();
|
||||
G = NewGlobal;
|
||||
|
||||
if (UseComdatMetadata) {
|
||||
// Get or create a COMDAT for G so that we can use it with our metadata.
|
||||
Comdat *C = G->getComdat();
|
||||
if (!C) {
|
||||
if (!G->hasName()) {
|
||||
// If G is unnamed, it must be internal. Give it an artificial name
|
||||
// so we can put it in a comdat.
|
||||
assert(G->hasLocalLinkage());
|
||||
G->setName(Twine(kAsanGenPrefix) + "_anon_global");
|
||||
}
|
||||
C = M.getOrInsertComdat(G->getName());
|
||||
// Make this IMAGE_COMDAT_SELECT_NODUPLICATES on COFF.
|
||||
if (TargetTriple.isOSBinFormatCOFF())
|
||||
C->setSelectionKind(Comdat::NoDuplicates);
|
||||
G->setComdat(C);
|
||||
}
|
||||
}
|
||||
NewGlobals[i] = NewGlobal;
|
||||
|
||||
Constant *SourceLoc;
|
||||
if (!MD.SourceLoc.empty()) {
|
||||
@ -1750,117 +1890,21 @@ bool AddressSanitizerModule::InstrumentGlobals(IRBuilder<> &IRB, Module &M) {
|
||||
|
||||
DEBUG(dbgs() << "NEW GLOBAL: " << *NewGlobal << "\n");
|
||||
|
||||
// If we aren't using separate metadata globals, add it to the initializer
|
||||
// list and continue.
|
||||
if (UseMetadataArray) {
|
||||
Initializers[i] = Initializer;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Create a separate metadata global and put it in the appropriate ASan
|
||||
// global registration section.
|
||||
GlobalVariable *Metadata = new GlobalVariable(
|
||||
M, GlobalStructTy, false, GlobalVariable::InternalLinkage,
|
||||
Initializer, Twine("__asan_global_") +
|
||||
GlobalValue::getRealLinkageName(G->getName()));
|
||||
Metadata->setSection(getGlobalMetadataSection());
|
||||
|
||||
// We don't want any padding, but we also need a reasonable alignment.
|
||||
// The MSVC linker always inserts padding when linking incrementally. We
|
||||
// cope with that by aligning each struct to its size, which must be a power
|
||||
// of two.
|
||||
Metadata->setAlignment(SizeOfGlobalStruct);
|
||||
|
||||
// On platforms that support comdats, put the metadata and the
|
||||
// instrumented global in the same group. This ensures that the metadata
|
||||
// is discarded if the instrumented global is discarded.
|
||||
if (UseComdatMetadata) {
|
||||
assert(G->hasComdat());
|
||||
Metadata->setComdat(G->getComdat());
|
||||
continue;
|
||||
}
|
||||
assert(UseMachOGlobalsSection);
|
||||
|
||||
// On recent Mach-O platforms, we emit the global metadata in a way that
|
||||
// allows the linker to properly strip dead globals.
|
||||
auto LivenessBinder = ConstantStruct::get(
|
||||
LivenessTy, Initializer->getAggregateElement(0u),
|
||||
ConstantExpr::getPointerCast(Metadata, IntptrTy), nullptr);
|
||||
GlobalVariable *Liveness = new GlobalVariable(
|
||||
M, LivenessTy, false, GlobalVariable::InternalLinkage, LivenessBinder,
|
||||
Twine("__asan_binder_") + G->getName());
|
||||
Liveness->setSection("__DATA,__asan_liveness,regular,live_support");
|
||||
LivenessGlobals[i] = Liveness;
|
||||
if (TargetTriple.isOSBinFormatCOFF()) {
|
||||
InstrumentGlobalsCOFF(IRB, M, NewGlobals, Initializers);
|
||||
} else if (ShouldUseMachOGlobalsSection()) {
|
||||
InstrumentGlobalsMachO(IRB, M, NewGlobals, Initializers);
|
||||
} else {
|
||||
InstrumentGlobalsWithMetadataArray(IRB, M, NewGlobals, Initializers);
|
||||
}
|
||||
|
||||
// Create calls for poisoning before initializers run and unpoisoning after.
|
||||
if (HasDynamicallyInitializedGlobals)
|
||||
createInitializerPoisonCalls(M, ModuleName);
|
||||
|
||||
// Platforms with a dedicated metadata section don't need to emit any more
|
||||
// code.
|
||||
if (UseComdatMetadata)
|
||||
return true;
|
||||
|
||||
GlobalVariable *AllGlobals = nullptr;
|
||||
GlobalVariable *RegisteredFlag = nullptr;
|
||||
|
||||
if (UseMachOGlobalsSection) {
|
||||
// RegisteredFlag serves two purposes. First, we can pass it to dladdr()
|
||||
// to look up the loaded image that contains it. Second, we can store in it
|
||||
// whether registration has already occurred, to prevent duplicate
|
||||
// registration.
|
||||
//
|
||||
// common linkage ensures that there is only one global per shared library.
|
||||
RegisteredFlag = new GlobalVariable(
|
||||
M, IntptrTy, false, GlobalVariable::CommonLinkage,
|
||||
ConstantInt::get(IntptrTy, 0), kAsanGlobalsRegisteredFlagName);
|
||||
RegisteredFlag->setVisibility(GlobalVariable::HiddenVisibility);
|
||||
|
||||
// Update llvm.compiler.used, adding the new liveness globals. This is
|
||||
// needed so that during LTO these variables stay alive. The alternative
|
||||
// would be to have the linker handling the LTO symbols, but libLTO
|
||||
// current API does not expose access to the section for each symbol.
|
||||
if (!LivenessGlobals.empty())
|
||||
appendToCompilerUsed(M, LivenessGlobals);
|
||||
} else if (UseMetadataArray) {
|
||||
// On platforms that don't have a custom metadata section, we emit an array
|
||||
// of global metadata structures.
|
||||
ArrayType *ArrayOfGlobalStructTy = ArrayType::get(GlobalStructTy, n);
|
||||
AllGlobals = new GlobalVariable(
|
||||
M, ArrayOfGlobalStructTy, false, GlobalVariable::InternalLinkage,
|
||||
ConstantArray::get(ArrayOfGlobalStructTy, Initializers), "");
|
||||
}
|
||||
|
||||
// Create a call to register the globals with the runtime.
|
||||
if (UseMachOGlobalsSection) {
|
||||
IRB.CreateCall(AsanRegisterImageGlobals,
|
||||
{IRB.CreatePointerCast(RegisteredFlag, IntptrTy)});
|
||||
} else {
|
||||
IRB.CreateCall(AsanRegisterGlobals,
|
||||
{IRB.CreatePointerCast(AllGlobals, IntptrTy),
|
||||
ConstantInt::get(IntptrTy, n)});
|
||||
}
|
||||
|
||||
// We also need to unregister globals at the end, e.g., when a shared library
|
||||
// gets closed.
|
||||
Function *AsanDtorFunction =
|
||||
Function::Create(FunctionType::get(Type::getVoidTy(*C), false),
|
||||
GlobalValue::InternalLinkage, kAsanModuleDtorName, &M);
|
||||
BasicBlock *AsanDtorBB = BasicBlock::Create(*C, "", AsanDtorFunction);
|
||||
IRBuilder<> IRB_Dtor(ReturnInst::Create(*C, AsanDtorBB));
|
||||
|
||||
if (UseMachOGlobalsSection) {
|
||||
IRB_Dtor.CreateCall(AsanUnregisterImageGlobals,
|
||||
{IRB.CreatePointerCast(RegisteredFlag, IntptrTy)});
|
||||
} else {
|
||||
IRB_Dtor.CreateCall(AsanUnregisterGlobals,
|
||||
{IRB.CreatePointerCast(AllGlobals, IntptrTy),
|
||||
ConstantInt::get(IntptrTy, n)});
|
||||
}
|
||||
|
||||
appendToGlobalDtors(M, AsanDtorFunction, kAsanCtorAndDtorPriority);
|
||||
|
||||
DEBUG(dbgs() << M);
|
||||
return true;
|
||||
}
|
||||
|
@ -85,6 +85,8 @@ STATISTIC(NumGVNLeaderChanges, "Number of leader changes");
|
||||
STATISTIC(NumGVNSortedLeaderChanges, "Number of sorted leader changes");
|
||||
STATISTIC(NumGVNAvoidedSortedLeaderChanges,
|
||||
"Number of avoided sorted leader changes");
|
||||
STATISTIC(NumGVNNotMostDominatingLeader,
|
||||
"Number of times a member dominated it's new classes' leader");
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// GVN Pass
|
||||
@ -1073,17 +1075,20 @@ void NewGVN::moveValueToNewCongruenceClass(Instruction *I,
|
||||
if (I == OldClass->NextLeader.first)
|
||||
OldClass->NextLeader = {nullptr, ~0U};
|
||||
|
||||
// The new instruction and new class leader may either be siblings in the
|
||||
// dominator tree, or the new class leader should dominate the new member
|
||||
// instruction. We simply check that the member instruction does not properly
|
||||
// dominate the new class leader.
|
||||
assert(
|
||||
!isa<Instruction>(NewClass->RepLeader) || !NewClass->RepLeader ||
|
||||
I == NewClass->RepLeader ||
|
||||
!DT->properlyDominates(
|
||||
// It's possible, though unlikely, for us to discover equivalences such
|
||||
// that the current leader does not dominate the old one.
|
||||
// This statistic tracks how often this happens.
|
||||
// We assert on phi nodes when this happens, currently, for debugging, because
|
||||
// we want to make sure we name phi node cycles properly.
|
||||
if (isa<Instruction>(NewClass->RepLeader) && NewClass->RepLeader &&
|
||||
I != NewClass->RepLeader &&
|
||||
DT->properlyDominates(
|
||||
I->getParent(),
|
||||
cast<Instruction>(NewClass->RepLeader)->getParent()) &&
|
||||
cast<Instruction>(NewClass->RepLeader)->getParent())) {
|
||||
++NumGVNNotMostDominatingLeader;
|
||||
assert(!isa<PHINode>(I) &&
|
||||
"New class for instruction should not be dominated by instruction");
|
||||
}
|
||||
|
||||
if (NewClass->RepLeader != I) {
|
||||
auto DFSNum = InstrDFS.lookup(I);
|
||||
|
@ -1339,6 +1339,7 @@ BUILTIN(__builtin_smulll_overflow, "bSLLiCSLLiCSLLi*", "n")
|
||||
BUILTIN(__builtin_addressof, "v*v&", "nct")
|
||||
BUILTIN(__builtin_operator_new, "v*z", "c")
|
||||
BUILTIN(__builtin_operator_delete, "vv*", "n")
|
||||
BUILTIN(__builtin_char_memchr, "c*cC*iz", "n")
|
||||
|
||||
// Safestack builtins
|
||||
BUILTIN(__builtin___get_unsafe_stack_start, "v*", "Fn")
|
||||
|
@ -5683,6 +5683,7 @@ bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
|
||||
case Builtin::BI__builtin_strchr:
|
||||
case Builtin::BI__builtin_wcschr:
|
||||
case Builtin::BI__builtin_memchr:
|
||||
case Builtin::BI__builtin_char_memchr:
|
||||
case Builtin::BI__builtin_wmemchr: {
|
||||
if (!Visit(E->getArg(0)))
|
||||
return false;
|
||||
@ -5720,6 +5721,7 @@ bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
|
||||
// Fall through.
|
||||
case Builtin::BImemchr:
|
||||
case Builtin::BI__builtin_memchr:
|
||||
case Builtin::BI__builtin_char_memchr:
|
||||
// memchr compares by converting both sides to unsigned char. That's also
|
||||
// correct for strchr if we get this far (to cope with plain char being
|
||||
// unsigned in the strchr case).
|
||||
|
@ -1189,6 +1189,10 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
|
||||
return RValue::get(Dest.getPointer());
|
||||
}
|
||||
|
||||
case Builtin::BI__builtin_char_memchr:
|
||||
BuiltinID = Builtin::BI__builtin_memchr;
|
||||
break;
|
||||
|
||||
case Builtin::BI__builtin___memcpy_chk: {
|
||||
// fold __builtin_memcpy_chk(x, y, cst1, cst2) to memcpy iff cst1<=cst2.
|
||||
llvm::APSInt Size, DstSize;
|
||||
|
@ -1183,6 +1183,7 @@ static bool HasFeature(const Preprocessor &PP, StringRef Feature) {
|
||||
.Case("cxx_attributes", LangOpts.CPlusPlus11)
|
||||
.Case("cxx_auto_type", LangOpts.CPlusPlus11)
|
||||
.Case("cxx_constexpr", LangOpts.CPlusPlus11)
|
||||
.Case("cxx_constexpr_string_builtins", LangOpts.CPlusPlus11)
|
||||
.Case("cxx_decltype", LangOpts.CPlusPlus11)
|
||||
.Case("cxx_decltype_incomplete_return_types", LangOpts.CPlusPlus11)
|
||||
.Case("cxx_default_function_template_args", LangOpts.CPlusPlus11)
|
||||
|
@ -12383,8 +12383,8 @@ ExprResult Sema::BuildCXXDefaultInitExpr(SourceLocation Loc, FieldDecl *Field) {
|
||||
Diag(Loc, diag::err_in_class_initializer_not_yet_parsed)
|
||||
<< OutermostClass << Field;
|
||||
Diag(Field->getLocEnd(), diag::note_in_class_initializer_not_yet_parsed);
|
||||
|
||||
// Don't diagnose this again.
|
||||
// Recover by marking the field invalid, unless we're in a SFINAE context.
|
||||
if (!isSFINAEContext())
|
||||
Field->setInvalidDecl();
|
||||
return ExprError();
|
||||
}
|
||||
|
@ -11496,7 +11496,7 @@ ExprResult Sema::BuildBinOp(Scope *S, SourceLocation OpLoc,
|
||||
return checkPseudoObjectAssignment(S, OpLoc, Opc, LHSExpr, RHSExpr);
|
||||
|
||||
// Don't resolve overloads if the other type is overloadable.
|
||||
if (pty->getKind() == BuiltinType::Overload) {
|
||||
if (getLangOpts().CPlusPlus && pty->getKind() == BuiltinType::Overload) {
|
||||
// We can't actually test that if we still have a placeholder,
|
||||
// though. Fortunately, none of the exceptions we see in that
|
||||
// code below are valid when the LHS is an overload set. Note
|
||||
@ -11521,17 +11521,16 @@ ExprResult Sema::BuildBinOp(Scope *S, SourceLocation OpLoc,
|
||||
// An overload in the RHS can potentially be resolved by the type
|
||||
// being assigned to.
|
||||
if (Opc == BO_Assign && pty->getKind() == BuiltinType::Overload) {
|
||||
if (LHSExpr->isTypeDependent() || RHSExpr->isTypeDependent())
|
||||
return BuildOverloadedBinOp(*this, S, OpLoc, Opc, LHSExpr, RHSExpr);
|
||||
|
||||
if (LHSExpr->getType()->isOverloadableType())
|
||||
if (getLangOpts().CPlusPlus &&
|
||||
(LHSExpr->isTypeDependent() || RHSExpr->isTypeDependent() ||
|
||||
LHSExpr->getType()->isOverloadableType()))
|
||||
return BuildOverloadedBinOp(*this, S, OpLoc, Opc, LHSExpr, RHSExpr);
|
||||
|
||||
return CreateBuiltinBinOp(OpLoc, Opc, LHSExpr, RHSExpr);
|
||||
}
|
||||
|
||||
// Don't resolve overloads if the other type is overloadable.
|
||||
if (pty->getKind() == BuiltinType::Overload &&
|
||||
if (getLangOpts().CPlusPlus && pty->getKind() == BuiltinType::Overload &&
|
||||
LHSExpr->getType()->isOverloadableType())
|
||||
return BuildOverloadedBinOp(*this, S, OpLoc, Opc, LHSExpr, RHSExpr);
|
||||
|
||||
|
@ -14,9 +14,12 @@
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
static void demangle(llvm::raw_ostream &OS, const char *Mangled) {
|
||||
static void demangle(llvm::raw_ostream &OS, const std::string &Mangled) {
|
||||
int Status;
|
||||
char *Demangled = itaniumDemangle(Mangled, nullptr, nullptr, &Status);
|
||||
char *Demangled = nullptr;
|
||||
if ((Mangled.size() >= 2 && Mangled.compare(0, 2, "_Z")) ||
|
||||
(Mangled.size() >= 4 && Mangled.compare(0, 4, "___Z")))
|
||||
Demangled = itaniumDemangle(Mangled.c_str(), nullptr, nullptr, &Status);
|
||||
OS << (Demangled ? Demangled : Mangled) << '\n';
|
||||
free(Demangled);
|
||||
}
|
||||
@ -24,7 +27,7 @@ static void demangle(llvm::raw_ostream &OS, const char *Mangled) {
|
||||
int main(int argc, char **argv) {
|
||||
if (argc == 1)
|
||||
for (std::string Mangled; std::getline(std::cin, Mangled);)
|
||||
demangle(llvm::outs(), Mangled.c_str());
|
||||
demangle(llvm::outs(), Mangled);
|
||||
else
|
||||
for (int I = 1; I < argc; ++I)
|
||||
demangle(llvm::outs(), argv[I]);
|
||||
|
@ -8,4 +8,4 @@
|
||||
|
||||
#define CLANG_VENDOR "FreeBSD "
|
||||
|
||||
#define SVN_REVISION "292732"
|
||||
#define SVN_REVISION "292951"
|
||||
|
@ -4,5 +4,5 @@
|
||||
#define LLD_VERSION_STRING "4.0.0"
|
||||
#define LLD_VERSION_MAJOR 4
|
||||
#define LLD_VERSION_MINOR 0
|
||||
#define LLD_REVISION_STRING "292732"
|
||||
#define LLD_REVISION_STRING "292951"
|
||||
#define LLD_REPOSITORY_STRING "FreeBSD"
|
||||
|
Loading…
Reference in New Issue
Block a user