diff options
42 files changed, 2344 insertions, 6642 deletions
diff --git a/gnu/llvm/lib/CodeGen/AsmPrinter/AsmPrinterHandler.h b/gnu/llvm/lib/CodeGen/AsmPrinter/AsmPrinterHandler.h index f5ac95a20b1..e59961f8576 100644 --- a/gnu/llvm/lib/CodeGen/AsmPrinter/AsmPrinterHandler.h +++ b/gnu/llvm/lib/CodeGen/AsmPrinter/AsmPrinterHandler.h @@ -19,54 +19,47 @@ namespace llvm { -class AsmPrinter; class MachineBasicBlock; class MachineFunction; class MachineInstr; class MCSymbol; -typedef MCSymbol *ExceptionSymbolProvider(AsmPrinter *Asm); - -/// Collects and handles AsmPrinter objects required to build debug +/// \brief Collects and handles AsmPrinter objects required to build debug /// or EH information. class AsmPrinterHandler { public: virtual ~AsmPrinterHandler(); - /// For symbols that have a size designated (e.g. common symbols), + /// \brief For symbols that have a size designated (e.g. common symbols), /// this tracks that size. virtual void setSymbolSize(const MCSymbol *Sym, uint64_t Size) = 0; - /// Emit all sections that should come after the content. + /// \brief Emit all sections that should come after the content. virtual void endModule() = 0; - /// Gather pre-function debug information. + /// \brief Gather pre-function debug information. /// Every beginFunction(MF) call should be followed by an endFunction(MF) /// call. virtual void beginFunction(const MachineFunction *MF) = 0; - // Emit any of function marker (like .cfi_endproc). This is called + // \brief Emit any of function marker (like .cfi_endproc). This is called // before endFunction and cannot switch sections. virtual void markFunctionEnd(); - /// Gather post-function debug information. + /// \brief Gather post-function debug information. /// Please note that some AsmPrinter implementations may not call /// beginFunction at all. virtual void endFunction(const MachineFunction *MF) = 0; - virtual void beginFragment(const MachineBasicBlock *MBB, - ExceptionSymbolProvider ESP) {} - virtual void endFragment() {} - - /// Emit target-specific EH funclet machinery. + /// \brief Emit target-specific EH funclet machinery. virtual void beginFunclet(const MachineBasicBlock &MBB, MCSymbol *Sym = nullptr) {} virtual void endFunclet() {} - /// Process beginning of an instruction. + /// \brief Process beginning of an instruction. virtual void beginInstruction(const MachineInstr *MI) = 0; - /// Process end of an instruction. + /// \brief Process end of an instruction. virtual void endInstruction() = 0; }; } // End of namespace llvm diff --git a/gnu/llvm/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp b/gnu/llvm/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp index 25518a339c6..3c46a99d084 100644 --- a/gnu/llvm/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp +++ b/gnu/llvm/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp @@ -1,4 +1,4 @@ -//===- llvm/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp --------------===// +//===-- llvm/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp -------------===// // // The LLVM Compiler Infrastructure // @@ -9,36 +9,27 @@ #include "DbgValueHistoryCalculator.h" #include "llvm/ADT/BitVector.h" -#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineInstr.h" -#include "llvm/CodeGen/MachineOperand.h" -#include "llvm/CodeGen/TargetLowering.h" -#include "llvm/CodeGen/TargetRegisterInfo.h" -#include "llvm/CodeGen/TargetSubtargetInfo.h" -#include "llvm/IR/DebugInfoMetadata.h" -#include "llvm/IR/DebugLoc.h" -#include "llvm/MC/MCRegisterInfo.h" +#include "llvm/IR/DebugInfo.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" -#include <cassert> +#include "llvm/Target/TargetRegisterInfo.h" +#include <algorithm> #include <map> -#include <utility> - using namespace llvm; #define DEBUG_TYPE "dwarfdebug" -// If @MI is a DBG_VALUE with debug value described by a +// \brief If @MI is a DBG_VALUE with debug value described by a // defined register, returns the number of this register. // In the other case, returns 0. static unsigned isDescribedByReg(const MachineInstr &MI) { assert(MI.isDebugValue()); assert(MI.getNumOperands() == 4); // If location of variable is described using a register (directly or - // indirectly), this register is always a first operand. + // indirecltly), this register is always a first operand. return MI.getOperand(0).isReg() ? MI.getOperand(0).getReg() : 0; } @@ -49,9 +40,9 @@ void DbgValueHistoryMap::startInstrRange(InlinedVariable Var, assert(MI.isDebugValue() && "not a DBG_VALUE"); auto &Ranges = VarInstrRanges[Var]; if (!Ranges.empty() && Ranges.back().second == nullptr && - Ranges.back().first->isIdenticalTo(MI)) { - LLVM_DEBUG(dbgs() << "Coalescing identical DBG_VALUE entries:\n" - << "\t" << Ranges.back().first << "\t" << MI << "\n"); + Ranges.back().first->isIdenticalTo(&MI)) { + DEBUG(dbgs() << "Coalescing identical DBG_VALUE entries:\n" + << "\t" << Ranges.back().first << "\t" << MI << "\n"); return; } Ranges.push_back(std::make_pair(&MI, nullptr)); @@ -79,20 +70,18 @@ unsigned DbgValueHistoryMap::getRegisterForVar(InlinedVariable Var) const { } namespace { - // Maps physreg numbers to the variables they describe. -using InlinedVariable = DbgValueHistoryMap::InlinedVariable; -using RegDescribedVarsMap = std::map<unsigned, SmallVector<InlinedVariable, 1>>; - -} // end anonymous namespace +typedef DbgValueHistoryMap::InlinedVariable InlinedVariable; +typedef std::map<unsigned, SmallVector<InlinedVariable, 1>> RegDescribedVarsMap; +} -// Claim that @Var is not described by @RegNo anymore. +// \brief Claim that @Var is not described by @RegNo anymore. static void dropRegDescribedVar(RegDescribedVarsMap &RegVars, unsigned RegNo, InlinedVariable Var) { const auto &I = RegVars.find(RegNo); assert(RegNo != 0U && I != RegVars.end()); auto &VarSet = I->second; - const auto &VarPos = llvm::find(VarSet, Var); + const auto &VarPos = std::find(VarSet.begin(), VarSet.end(), Var); assert(VarPos != VarSet.end()); VarSet.erase(VarPos); // Don't keep empty sets in a map to keep it as small as possible. @@ -100,16 +89,16 @@ static void dropRegDescribedVar(RegDescribedVarsMap &RegVars, unsigned RegNo, RegVars.erase(I); } -// Claim that @Var is now described by @RegNo. +// \brief Claim that @Var is now described by @RegNo. static void addRegDescribedVar(RegDescribedVarsMap &RegVars, unsigned RegNo, InlinedVariable Var) { assert(RegNo != 0U); auto &VarSet = RegVars[RegNo]; - assert(!is_contained(VarSet, Var)); + assert(std::find(VarSet.begin(), VarSet.end(), Var) == VarSet.end()); VarSet.push_back(Var); } -// Terminate the location range for variables described by register at +// \brief Terminate the location range for variables described by register at // @I by inserting @ClobberingInstr to their history. static void clobberRegisterUses(RegDescribedVarsMap &RegVars, RegDescribedVarsMap::iterator I, @@ -122,7 +111,7 @@ static void clobberRegisterUses(RegDescribedVarsMap &RegVars, RegVars.erase(I); } -// Terminate the location range for variables described by register +// \brief Terminate the location range for variables described by register // @RegNo by inserting @ClobberingInstr to their history. static void clobberRegisterUses(RegDescribedVarsMap &RegVars, unsigned RegNo, DbgValueHistoryMap &HistMap, @@ -133,7 +122,27 @@ static void clobberRegisterUses(RegDescribedVarsMap &RegVars, unsigned RegNo, clobberRegisterUses(RegVars, I, HistMap, ClobberingInstr); } -// Returns the first instruction in @MBB which corresponds to +// \brief Collect all registers clobbered by @MI and apply the functor +// @Func to their RegNo. +// @Func should be a functor with a void(unsigned) signature. We're +// not using std::function here for performance reasons. It has a +// small but measurable impact. By using a functor instead of a +// std::set& here, we can avoid the overhead of constructing +// temporaries in calculateDbgValueHistory, which has a significant +// performance impact. +template<typename Callable> +static void applyToClobberedRegisters(const MachineInstr &MI, + const TargetRegisterInfo *TRI, + Callable Func) { + for (const MachineOperand &MO : MI.operands()) { + if (!MO.isReg() || !MO.isDef() || !MO.getReg()) + continue; + for (MCRegAliasIterator AI(MO.getReg(), TRI, true); AI.isValid(); ++AI) + Func(*AI); + } +} + +// \brief Returns the first instruction in @MBB which corresponds to // the function epilogue, or nullptr if @MBB doesn't contain an epilogue. static const MachineInstr *getFirstEpilogueInst(const MachineBasicBlock &MBB) { auto LastMI = MBB.getLastNonDebugInstr(); @@ -143,19 +152,19 @@ static const MachineInstr *getFirstEpilogueInst(const MachineBasicBlock &MBB) { // as the return instruction. DebugLoc LastLoc = LastMI->getDebugLoc(); auto Res = LastMI; - for (MachineBasicBlock::const_reverse_iterator I = LastMI.getReverse(), - E = MBB.rend(); + for (MachineBasicBlock::const_reverse_iterator I(std::next(LastMI)), + E = MBB.rend(); I != E; ++I) { if (I->getDebugLoc() != LastLoc) - return &*Res; + return Res; Res = &*I; } // If all instructions have the same debug location, assume whole MBB is // an epilogue. - return &*MBB.begin(); + return MBB.begin(); } -// Collect registers that are modified in the function body (their +// \brief Collect registers that are modified in the function body (their // contents is changed outside of the prologue and epilogue). static void collectChangingRegs(const MachineFunction *MF, const TargetRegisterInfo *TRI, @@ -164,25 +173,10 @@ static void collectChangingRegs(const MachineFunction *MF, auto FirstEpilogueInst = getFirstEpilogueInst(MBB); for (const auto &MI : MBB) { - // Avoid looking at prologue or epilogue instructions. if (&MI == FirstEpilogueInst) break; - if (MI.getFlag(MachineInstr::FrameSetup)) - continue; - - // Look for register defs and register masks. Register masks are - // typically on calls and they clobber everything not in the mask. - for (const MachineOperand &MO : MI.operands()) { - // Skip virtual registers since they are handled by the parent. - if (MO.isReg() && MO.isDef() && MO.getReg() && - !TRI->isVirtualRegister(MO.getReg())) { - for (MCRegAliasIterator AI(MO.getReg(), TRI, true); AI.isValid(); - ++AI) - Regs.set(*AI); - } else if (MO.isRegMask()) { - Regs.setBitsNotInMask(MO.getRegMask()); - } - } + if (!MI.getFlag(MachineInstr::FrameSetup)) + applyToClobberedRegisters(MI, TRI, [&](unsigned r) { Regs.set(r); }); } } } @@ -193,51 +187,19 @@ void llvm::calculateDbgValueHistory(const MachineFunction *MF, BitVector ChangingRegs(TRI->getNumRegs()); collectChangingRegs(MF, TRI, ChangingRegs); - const TargetLowering *TLI = MF->getSubtarget().getTargetLowering(); - unsigned SP = TLI->getStackPointerRegisterToSaveRestore(); RegDescribedVarsMap RegVars; for (const auto &MBB : *MF) { for (const auto &MI : MBB) { - if (!MI.isDebugInstr()) { + if (!MI.isDebugValue()) { // Not a DBG_VALUE instruction. It may clobber registers which describe // some variables. - for (const MachineOperand &MO : MI.operands()) { - if (MO.isReg() && MO.isDef() && MO.getReg()) { - // Ignore call instructions that claim to clobber SP. The AArch64 - // backend does this for aggregate function arguments. - if (MI.isCall() && MO.getReg() == SP) - continue; - // If this is a virtual register, only clobber it since it doesn't - // have aliases. - if (TRI->isVirtualRegister(MO.getReg())) - clobberRegisterUses(RegVars, MO.getReg(), Result, MI); - // If this is a register def operand, it may end a debug value - // range. - else { - for (MCRegAliasIterator AI(MO.getReg(), TRI, true); AI.isValid(); - ++AI) - if (ChangingRegs.test(*AI)) - clobberRegisterUses(RegVars, *AI, Result, MI); - } - } else if (MO.isRegMask()) { - // If this is a register mask operand, clobber all debug values in - // non-CSRs. - for (unsigned I : ChangingRegs.set_bits()) { - // Don't consider SP to be clobbered by register masks. - if (unsigned(I) != SP && TRI->isPhysicalRegister(I) && - MO.clobbersPhysReg(I)) { - clobberRegisterUses(RegVars, I, Result, MI); - } - } - } - } + applyToClobberedRegisters(MI, TRI, [&](unsigned RegNo) { + if (ChangingRegs.test(RegNo)) + clobberRegisterUses(RegVars, RegNo, Result, MI); + }); continue; } - // Skip DBG_LABEL instructions. - if (MI.isDebugLabel()) - continue; - assert(MI.getNumOperands() > 1 && "Invalid DBG_VALUE instruction!"); // Use the base variable (without any DW_OP_piece expressions) // as index into History. The full variables including the @@ -262,40 +224,9 @@ void llvm::calculateDbgValueHistory(const MachineFunction *MF, if (!MBB.empty() && &MBB != &MF->back()) { for (auto I = RegVars.begin(), E = RegVars.end(); I != E;) { auto CurElem = I++; // CurElem can be erased below. - if (TRI->isVirtualRegister(CurElem->first) || - ChangingRegs.test(CurElem->first)) + if (ChangingRegs.test(CurElem->first)) clobberRegisterUses(RegVars, CurElem, Result, MBB.back()); } } } } - -#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) -LLVM_DUMP_METHOD void DbgValueHistoryMap::dump() const { - dbgs() << "DbgValueHistoryMap:\n"; - for (const auto &VarRangePair : *this) { - const InlinedVariable &Var = VarRangePair.first; - const InstrRanges &Ranges = VarRangePair.second; - - const DILocalVariable *LocalVar = Var.first; - const DILocation *Location = Var.second; - - dbgs() << " - " << LocalVar->getName() << " at "; - - if (Location) - dbgs() << Location->getFilename() << ":" << Location->getLine() << ":" - << Location->getColumn(); - else - dbgs() << "<unknown location>"; - - dbgs() << " --\n"; - - for (const InstrRange &Range : Ranges) { - dbgs() << " Begin: " << *Range.first; - if (Range.second) - dbgs() << " End : " << *Range.second; - dbgs() << "\n"; - } - } -} -#endif diff --git a/gnu/llvm/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h b/gnu/llvm/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h index a262cb38b17..546d1b44378 100644 --- a/gnu/llvm/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h +++ b/gnu/llvm/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h @@ -1,4 +1,4 @@ -//===- llvm/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h ------*- C++ -*-===// +//===-- llvm/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h ----*- C++ -*--===// // // The LLVM Compiler Infrastructure // @@ -12,14 +12,13 @@ #include "llvm/ADT/MapVector.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/IR/DebugInfoMetadata.h" -#include <utility> namespace llvm { -class DILocalVariable; class MachineFunction; class MachineInstr; +class DILocalVariable; +class DILocation; class TargetRegisterInfo; // For each user variable, keep a list of instruction ranges where this variable @@ -31,11 +30,11 @@ class DbgValueHistoryMap { // instruction of the next instruction range, or until the end of the // function. public: - using InstrRange = std::pair<const MachineInstr *, const MachineInstr *>; - using InstrRanges = SmallVector<InstrRange, 4>; - using InlinedVariable = - std::pair<const DILocalVariable *, const DILocation *>; - using InstrRangesMap = MapVector<InlinedVariable, InstrRanges>; + typedef std::pair<const MachineInstr *, const MachineInstr *> InstrRange; + typedef SmallVector<InstrRange, 4> InstrRanges; + typedef std::pair<const DILocalVariable *, const DILocation *> + InlinedVariable; + typedef MapVector<InlinedVariable, InstrRanges> InstrRangesMap; private: InstrRangesMap VarInstrRanges; @@ -43,7 +42,6 @@ private: public: void startInstrRange(InlinedVariable Var, const MachineInstr &MI); void endInstrRange(InlinedVariable Var, const MachineInstr &MI); - // Returns register currently describing @Var. If @Var is currently // unaccessible or is not described by a register, returns 0. unsigned getRegisterForVar(InlinedVariable Var) const; @@ -52,16 +50,11 @@ public: void clear() { VarInstrRanges.clear(); } InstrRangesMap::const_iterator begin() const { return VarInstrRanges.begin(); } InstrRangesMap::const_iterator end() const { return VarInstrRanges.end(); } - -#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) - LLVM_DUMP_METHOD void dump() const; -#endif }; void calculateDbgValueHistory(const MachineFunction *MF, const TargetRegisterInfo *TRI, DbgValueHistoryMap &Result); +} -} // end namespace llvm - -#endif // LLVM_LIB_CODEGEN_ASMPRINTER_DBGVALUEHISTORYCALCULATOR_H +#endif diff --git a/gnu/llvm/lib/Target/AArch64/CMakeLists.txt b/gnu/llvm/lib/Target/AArch64/CMakeLists.txt index d9a00512f71..f26327ff84a 100644 --- a/gnu/llvm/lib/Target/AArch64/CMakeLists.txt +++ b/gnu/llvm/lib/Target/AArch64/CMakeLists.txt @@ -1,51 +1,41 @@ set(LLVM_TARGET_DEFINITIONS AArch64.td) -tablegen(LLVM AArch64GenAsmMatcher.inc -gen-asm-matcher) +tablegen(LLVM AArch64GenRegisterInfo.inc -gen-register-info) +tablegen(LLVM AArch64GenInstrInfo.inc -gen-instr-info) +tablegen(LLVM AArch64GenMCCodeEmitter.inc -gen-emitter) +tablegen(LLVM AArch64GenMCPseudoLowering.inc -gen-pseudo-lowering) tablegen(LLVM AArch64GenAsmWriter.inc -gen-asm-writer) tablegen(LLVM AArch64GenAsmWriter1.inc -gen-asm-writer -asmwriternum=1) -tablegen(LLVM AArch64GenCallingConv.inc -gen-callingconv) +tablegen(LLVM AArch64GenAsmMatcher.inc -gen-asm-matcher) tablegen(LLVM AArch64GenDAGISel.inc -gen-dag-isel) -tablegen(LLVM AArch64GenDisassemblerTables.inc -gen-disassembler) tablegen(LLVM AArch64GenFastISel.inc -gen-fast-isel) -tablegen(LLVM AArch64GenGlobalISel.inc -gen-global-isel) -tablegen(LLVM AArch64GenInstrInfo.inc -gen-instr-info) -tablegen(LLVM AArch64GenMCCodeEmitter.inc -gen-emitter) -tablegen(LLVM AArch64GenMCPseudoLowering.inc -gen-pseudo-lowering) -tablegen(LLVM AArch64GenRegisterBank.inc -gen-register-bank) -tablegen(LLVM AArch64GenRegisterInfo.inc -gen-register-info) +tablegen(LLVM AArch64GenCallingConv.inc -gen-callingconv) tablegen(LLVM AArch64GenSubtargetInfo.inc -gen-subtarget) -tablegen(LLVM AArch64GenSystemOperands.inc -gen-searchable-tables) - +tablegen(LLVM AArch64GenDisassemblerTables.inc -gen-disassembler) add_public_tablegen_target(AArch64CommonTableGen) add_llvm_target(AArch64CodeGen AArch64A57FPLoadBalancing.cpp + AArch64AddressTypePromotion.cpp AArch64AdvSIMDScalarPass.cpp AArch64AsmPrinter.cpp - AArch64CallLowering.cpp + AArch64BranchRelaxation.cpp AArch64CleanupLocalDynamicTLSPass.cpp AArch64CollectLOH.cpp - AArch64CondBrTuning.cpp AArch64ConditionalCompares.cpp AArch64DeadRegisterDefinitionsPass.cpp AArch64ExpandPseudoInsts.cpp - AArch64FalkorHWPFFix.cpp AArch64FastISel.cpp AArch64A53Fix835769.cpp AArch64FrameLowering.cpp AArch64ConditionOptimizer.cpp - AArch64RedundantCopyElimination.cpp AArch64ISelDAGToDAG.cpp AArch64ISelLowering.cpp AArch64InstrInfo.cpp - AArch64InstructionSelector.cpp - AArch64LegalizerInfo.cpp AArch64LoadStoreOptimizer.cpp - AArch64MacroFusion.cpp AArch64MCInstLower.cpp AArch64PromoteConstant.cpp AArch64PBQPRegAlloc.cpp - AArch64RegisterBankInfo.cpp AArch64RegisterInfo.cpp AArch64SelectionDAGInfo.cpp AArch64StorePairSuppress.cpp @@ -53,15 +43,13 @@ add_llvm_target(AArch64CodeGen AArch64TargetMachine.cpp AArch64TargetObjectFile.cpp AArch64TargetTransformInfo.cpp - AArch64SIMDInstrOpt.cpp - - DEPENDS - intrinsics_gen ) +add_dependencies(LLVMAArch64CodeGen intrinsics_gen) + +add_subdirectory(TargetInfo) add_subdirectory(AsmParser) add_subdirectory(Disassembler) add_subdirectory(InstPrinter) add_subdirectory(MCTargetDesc) -add_subdirectory(TargetInfo) add_subdirectory(Utils) diff --git a/gnu/llvm/lib/Target/AMDGPU/AMDGPUIntrinsics.td b/gnu/llvm/lib/Target/AMDGPU/AMDGPUIntrinsics.td index 230a0462850..1de3546485b 100644 --- a/gnu/llvm/lib/Target/AMDGPU/AMDGPUIntrinsics.td +++ b/gnu/llvm/lib/Target/AMDGPU/AMDGPUIntrinsics.td @@ -12,5 +12,79 @@ //===----------------------------------------------------------------------===// let TargetPrefix = "AMDGPU", isTarget = 1 in { + + def int_AMDGPU_store_output : Intrinsic<[], [llvm_float_ty, llvm_i32_ty], []>; + def int_AMDGPU_swizzle : Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_i32_ty], [IntrNoMem]>; + def int_AMDGPU_abs : Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem]>; + def int_AMDGPU_arl : Intrinsic<[llvm_i32_ty], [llvm_float_ty], [IntrNoMem]>; + def int_AMDGPU_cndlt : Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty, llvm_float_ty], [IntrNoMem]>; + def int_AMDGPU_div : Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty], [IntrNoMem]>; + def int_AMDGPU_fract : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>; + def int_AMDGPU_clamp : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>; + + // This is named backwards (instead of rsq_legacy) so we don't have + // to define it with the public builtins intrinsics. This is a + // workaround for how intrinsic names are parsed. If the name is + // llvm.AMDGPU.rsq.legacy, the parser assumes that you meant + // llvm.AMDGPU.rsq.{f32 | f64} and incorrectly mangled the name. + def int_AMDGPU_legacy_rsq : Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>; + + def int_AMDGPU_dp4 : Intrinsic<[llvm_float_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; def int_AMDGPU_kill : Intrinsic<[], [llvm_float_ty], []>; + def int_AMDGPU_kilp : Intrinsic<[], [], []>; + def int_AMDGPU_lrp : Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty, llvm_float_ty], [IntrNoMem]>; + def int_AMDGPU_mul : Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty], [IntrNoMem]>; + def int_AMDGPU_pow : Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty], [IntrNoMem]>; + def int_AMDGPU_seq : Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty], [IntrNoMem]>; + def int_AMDGPU_sgt : Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty], [IntrNoMem]>; + def int_AMDGPU_sge : Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty], [IntrNoMem]>; + def int_AMDGPU_sle : Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty], [IntrNoMem]>; + def int_AMDGPU_sne : Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty], [IntrNoMem]>; + def int_AMDGPU_mullit : Intrinsic<[llvm_v4f32_ty], [llvm_float_ty, llvm_float_ty, llvm_float_ty], [IntrNoMem]>; + def int_AMDGPU_tex : Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + def int_AMDGPU_txb : Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + def int_AMDGPU_txf : Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + def int_AMDGPU_txq : Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + def int_AMDGPU_txd : Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + def int_AMDGPU_txl : Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + def int_AMDGPU_trunc : Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>; + def int_AMDGPU_ddx : Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + def int_AMDGPU_ddy : Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + def int_AMDGPU_imax : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + def int_AMDGPU_imin : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + def int_AMDGPU_umax : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + def int_AMDGPU_umin : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + def int_AMDGPU_umul24 : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + def int_AMDGPU_imul24 : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + def int_AMDGPU_imad24 : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + def int_AMDGPU_umad24 : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + def int_AMDGPU_cvt_f32_ubyte0 : Intrinsic<[llvm_float_ty], [llvm_i32_ty], [IntrNoMem]>; + def int_AMDGPU_cvt_f32_ubyte1 : Intrinsic<[llvm_float_ty], [llvm_i32_ty], [IntrNoMem]>; + def int_AMDGPU_cvt_f32_ubyte2 : Intrinsic<[llvm_float_ty], [llvm_i32_ty], [IntrNoMem]>; + def int_AMDGPU_cvt_f32_ubyte3 : Intrinsic<[llvm_float_ty], [llvm_i32_ty], [IntrNoMem]>; + def int_AMDGPU_cube : Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>; + def int_AMDGPU_bfi : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + def int_AMDGPU_bfe_i32 : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + def int_AMDGPU_bfe_u32 : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + def int_AMDGPU_bfm : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + def int_AMDGPU_brev : Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem]>; + def int_AMDGPU_flbit_i32 : Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem]>; + def int_AMDGPU_barrier_local : Intrinsic<[], [], [IntrConvergent]>; + def int_AMDGPU_barrier_global : Intrinsic<[], [], [IntrConvergent]>; +} + +// Legacy names for compatibility. +let TargetPrefix = "AMDIL", isTarget = 1 in { + def int_AMDIL_abs : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>], [IntrNoMem]>; + def int_AMDIL_fraction : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>; + def int_AMDIL_clamp : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>; + def int_AMDIL_exp : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>; + def int_AMDIL_round_nearest : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>; } + +let TargetPrefix = "TGSI", isTarget = 1 in { + + def int_TGSI_lit_z : Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty, llvm_float_ty],[IntrNoMem]>; +} + +include "SIIntrinsics.td" diff --git a/gnu/llvm/lib/Target/Hexagon/HexagonInstrFormatsV4.td b/gnu/llvm/lib/Target/Hexagon/HexagonInstrFormatsV4.td index c5fa2599521..2d1dea526ee 100644 --- a/gnu/llvm/lib/Target/Hexagon/HexagonInstrFormatsV4.td +++ b/gnu/llvm/lib/Target/Hexagon/HexagonInstrFormatsV4.td @@ -1,4 +1,4 @@ -//==- HexagonInstrFormatsV4.td - Hexagon Instruction Formats --*- tablegen -==// +//==- HexagonInstrFormats.td - Hexagon Instruction Formats --*- tablegen -*-==// // // The LLVM Compiler Infrastructure // @@ -11,6 +11,18 @@ // //===----------------------------------------------------------------------===// +//----------------------------------------------------------------------------// +// Hexagon Instruction Flags +// +// *** Must match BaseInfo.h *** +//----------------------------------------------------------------------------// + +def TypeMEMOP : IType<9>; +def TypeNV : IType<10>; +def TypeDUPLEX : IType<11>; +def TypeCOMPOUND : IType<12>; +def TypePREFIX : IType<30>; + // Duplex Instruction Class Declaration //===----------------------------------------------------------------------===// @@ -49,7 +61,7 @@ class InstDuplex<bits<4> iClass, list<dag> pattern = [], // *** Must match MCTargetDesc/HexagonBaseInfo.h *** - let TSFlags{5-0} = Type.Value; + let TSFlags{4-0} = Type.Value; // Predicated instructions. bits<1> isPredicated = 0; @@ -85,3 +97,59 @@ class InstDuplex<bits<4> iClass, list<dag> pattern = [], bits<2> opExtentAlign = 0; let TSFlags{28-27} = opExtentAlign; // Alignment exponent before extending. } + +//----------------------------------------------------------------------------// +// Instruction Classes Definitions +//----------------------------------------------------------------------------// + +// +// NV type instructions. +// +class NVInst<dag outs, dag ins, string asmstr, list<dag> pattern = [], + string cstr = "", InstrItinClass itin = NCJ_tc_3or4stall_SLOT0> + : InstHexagon<outs, ins, asmstr, pattern, cstr, itin, TypeNV>, OpcodeHexagon; + +class NVInst_V4<dag outs, dag ins, string asmstr, list<dag> pattern = [], + string cstr = "", InstrItinClass itin = NCJ_tc_3or4stall_SLOT0> + : NVInst<outs, ins, asmstr, pattern, cstr, itin>; + +// Definition of Post increment new value store. +class NVInstPost_V4<dag outs, dag ins, string asmstr, list<dag> pattern = [], + string cstr = "", InstrItinClass itin = ST_tc_st_SLOT0> + : NVInst<outs, ins, asmstr, pattern, cstr, itin>; + +// Post increment ST Instruction. +let mayStore = 1 in +class NVInstPI_V4<dag outs, dag ins, string asmstr, list<dag> pattern = [], + string cstr = "", InstrItinClass itin = ST_tc_st_SLOT0> + : NVInst<outs, ins, asmstr, pattern, cstr, itin>; + +// New-value conditional branch. +class NCJInst<dag outs, dag ins, string asmstr, list<dag> pattern = [], + string cstr = ""> + : NVInst<outs, ins, asmstr, pattern, cstr>; + +let mayLoad = 1, mayStore = 1 in +class MEMInst<dag outs, dag ins, string asmstr, list<dag> pattern = [], + string cstr = "", InstrItinClass itin = V4LDST_tc_st_SLOT0> + : InstHexagon<outs, ins, asmstr, pattern, cstr, itin, TypeMEMOP>, + OpcodeHexagon; + +class MEMInst_V4<dag outs, dag ins, string asmstr, list<dag> pattern = [], + string cstr = "", InstrItinClass itin = V4LDST_tc_st_SLOT0> + : MEMInst<outs, ins, asmstr, pattern, cstr, itin>; + +let isCodeGenOnly = 1 in +class EXTENDERInst<dag outs, dag ins, string asmstr, list<dag> pattern = []> + : InstHexagon<outs, ins, asmstr, pattern, "", EXTENDER_tc_1_SLOT0123, + TypePREFIX>, OpcodeHexagon; + +class SUBInst<dag outs, dag ins, string asmstr, list<dag> pattern = [], + string cstr = ""> + : InstHexagon<outs, ins, asmstr, pattern, "", PREFIX, TypeDUPLEX>, + OpcodeHexagon; + +class CJInst<dag outs, dag ins, string asmstr, list<dag> pattern = [], + string cstr = ""> + : InstHexagon<outs, ins, asmstr, pattern, cstr, COMPOUND, TypeCOMPOUND>, + OpcodeHexagon; diff --git a/gnu/llvm/lib/Target/Hexagon/HexagonIntrinsicsV4.td b/gnu/llvm/lib/Target/Hexagon/HexagonIntrinsicsV4.td index 2affe531515..c80a188d82e 100644 --- a/gnu/llvm/lib/Target/Hexagon/HexagonIntrinsicsV4.td +++ b/gnu/llvm/lib/Target/Hexagon/HexagonIntrinsicsV4.td @@ -60,60 +60,71 @@ def : T_PPR_pat <S2_lsr_r_p_xor, int_hexagon_S2_lsr_r_p_xor>; def : T_PPR_pat <S2_lsl_r_p_xor, int_hexagon_S2_lsl_r_p_xor>; // Multiply and use upper result -def : T_RR_pat <M2_mpysu_up, int_hexagon_M2_mpysu_up>; -def : T_RR_pat <M2_mpy_up_s1, int_hexagon_M2_mpy_up_s1>; -def : T_RR_pat <M2_hmmpyh_s1, int_hexagon_M2_hmmpyh_s1>; -def : T_RR_pat <M2_hmmpyl_s1, int_hexagon_M2_hmmpyl_s1>; -def : T_RR_pat <M2_mpy_up_s1_sat, int_hexagon_M2_mpy_up_s1_sat>; - -def : T_PP_pat <A2_vaddub, int_hexagon_A2_vaddb_map>; -def : T_PP_pat <A2_vsubub, int_hexagon_A2_vsubb_map>; +def : MType_R32_pat <int_hexagon_M2_mpysu_up, M2_mpysu_up>; +def : MType_R32_pat <int_hexagon_M2_mpy_up_s1, M2_mpy_up_s1>; +def : MType_R32_pat <int_hexagon_M2_hmmpyh_s1, M2_hmmpyh_s1>; +def : MType_R32_pat <int_hexagon_M2_hmmpyl_s1, M2_hmmpyl_s1>; +def : MType_R32_pat <int_hexagon_M2_mpy_up_s1_sat, M2_mpy_up_s1_sat>; // Vector reduce add unsigned halfwords -def : T_PP_pat <M2_vraddh, int_hexagon_M2_vraddh>; - -def: T_P_pat<S2_brevp, int_hexagon_S2_brevp>; -def: T_P_pat<S2_ct0p, int_hexagon_S2_ct0p>; -def: T_P_pat<S2_ct1p, int_hexagon_S2_ct1p>; - -def: T_Q_RR_pat<C4_nbitsset, int_hexagon_C4_nbitsset>; -def: T_Q_RR_pat<C4_nbitsclr, int_hexagon_C4_nbitsclr>; -def: T_Q_RI_pat<C4_nbitsclri, int_hexagon_C4_nbitsclri>; - -def : T_Q_PI_pat<A4_vcmpbeqi, int_hexagon_A4_vcmpbeqi>; -def : T_Q_PI_pat<A4_vcmpbgti, int_hexagon_A4_vcmpbgti>; -def : T_Q_PI_pat<A4_vcmpbgtui, int_hexagon_A4_vcmpbgtui>; -def : T_Q_PI_pat<A4_vcmpheqi, int_hexagon_A4_vcmpheqi>; -def : T_Q_PI_pat<A4_vcmphgti, int_hexagon_A4_vcmphgti>; -def : T_Q_PI_pat<A4_vcmphgtui, int_hexagon_A4_vcmphgtui>; -def : T_Q_PI_pat<A4_vcmpweqi, int_hexagon_A4_vcmpweqi>; -def : T_Q_PI_pat<A4_vcmpwgti, int_hexagon_A4_vcmpwgti>; -def : T_Q_PI_pat<A4_vcmpwgtui, int_hexagon_A4_vcmpwgtui>; -def : T_Q_PP_pat<A4_vcmpbeq_any, int_hexagon_A4_vcmpbeq_any>; - -def : T_Q_RR_pat<A4_cmpbeq, int_hexagon_A4_cmpbeq>; -def : T_Q_RR_pat<A4_cmpbgt, int_hexagon_A4_cmpbgt>; -def : T_Q_RR_pat<A4_cmpbgtu, int_hexagon_A4_cmpbgtu>; -def : T_Q_RR_pat<A4_cmpheq, int_hexagon_A4_cmpheq>; -def : T_Q_RR_pat<A4_cmphgt, int_hexagon_A4_cmphgt>; -def : T_Q_RR_pat<A4_cmphgtu, int_hexagon_A4_cmphgtu>; - -def : T_Q_RI_pat<A4_cmpbeqi, int_hexagon_A4_cmpbeqi>; -def : T_Q_RI_pat<A4_cmpbgti, int_hexagon_A4_cmpbgti>; -def : T_Q_RI_pat<A4_cmpbgtui, int_hexagon_A4_cmpbgtui>; - -def : T_Q_RI_pat<A4_cmpheqi, int_hexagon_A4_cmpheqi>; -def : T_Q_RI_pat<A4_cmphgti, int_hexagon_A4_cmphgti>; -def : T_Q_RI_pat<A4_cmphgtui, int_hexagon_A4_cmphgtui>; - -def : T_Q_RP_pat<A4_boundscheck, int_hexagon_A4_boundscheck>; -def : T_Q_PR_pat<A4_tlbmatch, int_hexagon_A4_tlbmatch>; - -def : T_RRR_pat <M4_mpyrr_addr, int_hexagon_M4_mpyrr_addr>; -def : T_IRR_pat <M4_mpyrr_addi, int_hexagon_M4_mpyrr_addi>; -def : T_IRI_pat <M4_mpyri_addi, int_hexagon_M4_mpyri_addi>; +def : Pat <(int_hexagon_M2_vraddh DoubleRegs:$src1, DoubleRegs:$src2), + (M2_vraddh DoubleRegs:$src1, DoubleRegs:$src2)>; + +def : T_P_pat <S2_brevp, int_hexagon_S2_brevp>; + +def: T_P_pat <S2_ct0p, int_hexagon_S2_ct0p>; +def: T_P_pat <S2_ct1p, int_hexagon_S2_ct1p>; +def: T_RR_pat<C4_nbitsset, int_hexagon_C4_nbitsset>; +def: T_RR_pat<C4_nbitsclr, int_hexagon_C4_nbitsclr>; +def: T_RI_pat<C4_nbitsclri, int_hexagon_C4_nbitsclri>; + + +class vcmpImm_pat <InstHexagon MI, Intrinsic IntID, PatLeaf immPred> : + Pat <(IntID (i64 DoubleRegs:$src1), immPred:$src2), + (MI (i64 DoubleRegs:$src1), immPred:$src2)>; + +def : vcmpImm_pat <A4_vcmpbeqi, int_hexagon_A4_vcmpbeqi, u8ImmPred>; +def : vcmpImm_pat <A4_vcmpbgti, int_hexagon_A4_vcmpbgti, s8ImmPred>; +def : vcmpImm_pat <A4_vcmpbgtui, int_hexagon_A4_vcmpbgtui, u7ImmPred>; + +def : vcmpImm_pat <A4_vcmpheqi, int_hexagon_A4_vcmpheqi, s8ImmPred>; +def : vcmpImm_pat <A4_vcmphgti, int_hexagon_A4_vcmphgti, s8ImmPred>; +def : vcmpImm_pat <A4_vcmphgtui, int_hexagon_A4_vcmphgtui, u7ImmPred>; + +def : vcmpImm_pat <A4_vcmpweqi, int_hexagon_A4_vcmpweqi, s8ImmPred>; +def : vcmpImm_pat <A4_vcmpwgti, int_hexagon_A4_vcmpwgti, s8ImmPred>; +def : vcmpImm_pat <A4_vcmpwgtui, int_hexagon_A4_vcmpwgtui, u7ImmPred>; + +def : T_PP_pat<A4_vcmpbeq_any, int_hexagon_A4_vcmpbeq_any>; + +def : T_RR_pat<A4_cmpbeq, int_hexagon_A4_cmpbeq>; +def : T_RR_pat<A4_cmpbgt, int_hexagon_A4_cmpbgt>; +def : T_RR_pat<A4_cmpbgtu, int_hexagon_A4_cmpbgtu>; +def : T_RR_pat<A4_cmpheq, int_hexagon_A4_cmpheq>; +def : T_RR_pat<A4_cmphgt, int_hexagon_A4_cmphgt>; +def : T_RR_pat<A4_cmphgtu, int_hexagon_A4_cmphgtu>; + +def : T_RI_pat<A4_cmpbeqi, int_hexagon_A4_cmpbeqi>; +def : T_RI_pat<A4_cmpbgti, int_hexagon_A4_cmpbgti>; +def : T_RI_pat<A4_cmpbgtui, int_hexagon_A4_cmpbgtui>; + +def : T_RI_pat<A4_cmpheqi, int_hexagon_A4_cmpheqi>; +def : T_RI_pat<A4_cmphgti, int_hexagon_A4_cmphgti>; +def : T_RI_pat<A4_cmphgtui, int_hexagon_A4_cmphgtui>; + +def : T_RP_pat <A4_boundscheck, int_hexagon_A4_boundscheck>; + +def : T_PR_pat<A4_tlbmatch, int_hexagon_A4_tlbmatch>; + +def : Pat <(int_hexagon_M4_mpyrr_addr IntRegs:$src1, IntRegs:$src2, + IntRegs:$src3), + (M4_mpyrr_addr IntRegs:$src1, IntRegs:$src2, IntRegs:$src3)>; + +def : T_IRR_pat <M4_mpyrr_addi, int_hexagon_M4_mpyrr_addi>; +def : T_IRI_pat <M4_mpyri_addi, int_hexagon_M4_mpyri_addi>; def : T_RIR_pat <M4_mpyri_addr_u2, int_hexagon_M4_mpyri_addr_u2>; -def : T_RRI_pat <M4_mpyri_addr, int_hexagon_M4_mpyri_addr>; +def : T_RRI_pat <M4_mpyri_addr, int_hexagon_M4_mpyri_addr>; +// Multiply 32x32 and use upper result def : T_RRR_pat <M4_mac_up_s1_sat, int_hexagon_M4_mac_up_s1_sat>; def : T_RRR_pat <M4_nac_up_s1_sat, int_hexagon_M4_nac_up_s1_sat>; @@ -167,15 +178,15 @@ def : T_PPR_pat <A4_vrminuw, int_hexagon_A4_vrminuw>; // Rotate and reduce bytes def : Pat <(int_hexagon_S4_vrcrotate DoubleRegs:$src1, IntRegs:$src2, - u2_0ImmPred:$src3), - (S4_vrcrotate DoubleRegs:$src1, IntRegs:$src2, u2_0ImmPred:$src3)>; + u2ImmPred:$src3), + (S4_vrcrotate DoubleRegs:$src1, IntRegs:$src2, u2ImmPred:$src3)>; // Rotate and reduce bytes with accumulation // Rxx+=vrcrotate(Rss,Rt,#u2) def : Pat <(int_hexagon_S4_vrcrotate_acc DoubleRegs:$src1, DoubleRegs:$src2, - IntRegs:$src3, u2_0ImmPred:$src4), + IntRegs:$src3, u2ImmPred:$src4), (S4_vrcrotate_acc DoubleRegs:$src1, DoubleRegs:$src2, - IntRegs:$src3, u2_0ImmPred:$src4)>; + IntRegs:$src3, u2ImmPred:$src4)>; // Vector conditional negate def : T_PPR_pat<S2_vrcnegh, int_hexagon_S2_vrcnegh>; @@ -199,46 +210,41 @@ def : T_IRI_pat <S4_subi_lsr_ri, int_hexagon_S4_subi_lsr_ri>; // Split bitfield def : T_RI_pat <A4_bitspliti, int_hexagon_A4_bitspliti>; -def : T_RR_pat <A4_bitsplit, int_hexagon_A4_bitsplit>; +def : T_RR_pat <A4_bitsplit, int_hexagon_A4_bitsplit>; -def: T_RR_pat<S4_parity, int_hexagon_S4_parity>; +def: T_RR_pat<S4_parity, int_hexagon_S4_parity>; -def: T_Q_RI_pat<S4_ntstbit_i, int_hexagon_S4_ntstbit_i>; -def: T_Q_RR_pat<S4_ntstbit_r, int_hexagon_S4_ntstbit_r>; +def: T_RI_pat<S4_ntstbit_i, int_hexagon_S4_ntstbit_i>; +def: T_RR_pat<S4_ntstbit_r, int_hexagon_S4_ntstbit_r>; -def: T_RI_pat<S4_clbaddi, int_hexagon_S4_clbaddi>; -def: T_PI_pat<S4_clbpaddi, int_hexagon_S4_clbpaddi>; -def: T_P_pat <S4_clbpnorm, int_hexagon_S4_clbpnorm>; +def: T_RI_pat<S4_clbaddi, int_hexagon_S4_clbaddi>; +def: T_PI_pat<S4_clbpaddi, int_hexagon_S4_clbpaddi>; +def: T_P_pat <S4_clbpnorm, int_hexagon_S4_clbpnorm>; -//******************************************************************* -// ALU32/ALU -//******************************************************************* +/******************************************************************** +* ALU32/ALU * +*********************************************************************/ // ALU32 / ALU / Logical Operations. def: T_RR_pat<A4_andn, int_hexagon_A4_andn>; def: T_RR_pat<A4_orn, int_hexagon_A4_orn>; -//******************************************************************* -// ALU32/PERM -//******************************************************************* +/******************************************************************** +* ALU32/PERM * +*********************************************************************/ // Combine Words Into Doublewords. -def: T_RI_pat<A4_combineri, int_hexagon_A4_combineri, s32_0ImmPred>; -def: T_IR_pat<A4_combineir, int_hexagon_A4_combineir, s32_0ImmPred>; +def: T_RI_pat<A4_combineri, int_hexagon_A4_combineri, s32ImmPred>; +def: T_IR_pat<A4_combineir, int_hexagon_A4_combineir, s32ImmPred>; -//******************************************************************* -// ALU32/PRED -//******************************************************************* +/******************************************************************** +* ALU32/PRED * +*********************************************************************/ // Compare -def : T_Q_RI_pat<C4_cmpneqi, int_hexagon_C4_cmpneqi, s32_0ImmPred>; -def : T_Q_RI_pat<C4_cmpltei, int_hexagon_C4_cmpltei, s32_0ImmPred>; -def : T_Q_RI_pat<C4_cmplteui, int_hexagon_C4_cmplteui, u32_0ImmPred>; - -// Compare To General Register. -def: T_Q_RR_pat<C4_cmpneq, int_hexagon_C4_cmpneq>; -def: T_Q_RR_pat<C4_cmplte, int_hexagon_C4_cmplte>; -def: T_Q_RR_pat<C4_cmplteu, int_hexagon_C4_cmplteu>; +def : T_RI_pat<C4_cmpneqi, int_hexagon_C4_cmpneqi, s32ImmPred>; +def : T_RI_pat<C4_cmpltei, int_hexagon_C4_cmpltei, s32ImmPred>; +def : T_RI_pat<C4_cmplteui, int_hexagon_C4_cmplteui, u32ImmPred>; def: T_RR_pat<A4_rcmpeq, int_hexagon_A4_rcmpeq>; def: T_RR_pat<A4_rcmpneq, int_hexagon_A4_rcmpneq>; @@ -246,23 +252,30 @@ def: T_RR_pat<A4_rcmpneq, int_hexagon_A4_rcmpneq>; def: T_RI_pat<A4_rcmpeqi, int_hexagon_A4_rcmpeqi>; def: T_RI_pat<A4_rcmpneqi, int_hexagon_A4_rcmpneqi>; -//******************************************************************* -// CR -//******************************************************************* +/******************************************************************** +* CR * +*********************************************************************/ // CR / Logical Operations On Predicates. -def: T_Q_QQQ_pat<C4_and_and, int_hexagon_C4_and_and>; -def: T_Q_QQQ_pat<C4_and_andn, int_hexagon_C4_and_andn>; -def: T_Q_QQQ_pat<C4_and_or, int_hexagon_C4_and_or>; -def: T_Q_QQQ_pat<C4_and_orn, int_hexagon_C4_and_orn>; -def: T_Q_QQQ_pat<C4_or_and, int_hexagon_C4_or_and>; -def: T_Q_QQQ_pat<C4_or_andn, int_hexagon_C4_or_andn>; -def: T_Q_QQQ_pat<C4_or_or, int_hexagon_C4_or_or>; -def: T_Q_QQQ_pat<C4_or_orn, int_hexagon_C4_or_orn>; - -//******************************************************************* -// XTYPE/ALU -//******************************************************************* + +class qi_CRInst_qiqiqi_pat<Intrinsic IntID, InstHexagon Inst> : + Pat<(i32 (IntID IntRegs:$Rs, IntRegs:$Rt, IntRegs:$Ru)), + (i32 (C2_tfrpr (Inst (C2_tfrrp IntRegs:$Rs), + (C2_tfrrp IntRegs:$Rt), + (C2_tfrrp IntRegs:$Ru))))>; + +def: qi_CRInst_qiqiqi_pat<int_hexagon_C4_and_and, C4_and_and>; +def: qi_CRInst_qiqiqi_pat<int_hexagon_C4_and_andn, C4_and_andn>; +def: qi_CRInst_qiqiqi_pat<int_hexagon_C4_and_or, C4_and_or>; +def: qi_CRInst_qiqiqi_pat<int_hexagon_C4_and_orn, C4_and_orn>; +def: qi_CRInst_qiqiqi_pat<int_hexagon_C4_or_and, C4_or_and>; +def: qi_CRInst_qiqiqi_pat<int_hexagon_C4_or_andn, C4_or_andn>; +def: qi_CRInst_qiqiqi_pat<int_hexagon_C4_or_or, C4_or_or>; +def: qi_CRInst_qiqiqi_pat<int_hexagon_C4_or_orn, C4_or_orn>; + +/******************************************************************** +* XTYPE/ALU * +*********************************************************************/ // Add And Accumulate. diff --git a/gnu/llvm/lib/Target/Hexagon/HexagonScheduleV4.td b/gnu/llvm/lib/Target/Hexagon/HexagonScheduleV4.td index 69b704a805b..67af147b25b 100644 --- a/gnu/llvm/lib/Target/Hexagon/HexagonScheduleV4.td +++ b/gnu/llvm/lib/Target/Hexagon/HexagonScheduleV4.td @@ -7,38 +7,198 @@ // //===----------------------------------------------------------------------===// -def LD_tc_ld_SLOT01 : InstrItinClass; -def ST_tc_st_SLOT01 : InstrItinClass; - -class HexagonV4PseudoItin { - list<InstrItinData> V4PseudoItin_list = [ - InstrItinData<PSEUDO, [InstrStage<1, [SLOT0, SLOT1, SLOT2, SLOT3]>]>, - InstrItinData<PSEUDOM, [InstrStage<1, [SLOT2, SLOT3], 0>, - InstrStage<1, [SLOT2, SLOT3]>]>, - InstrItinData<DUPLEX, [InstrStage<1, [SLOT0]>]>, - InstrItinData<tc_ENDLOOP, [InstrStage<1, [SLOT_ENDLOOP]>]> - ]; -} +// There are four SLOTS (four parallel pipelines) in Hexagon V4 machine. +// This file describes that machine information. + +// +// |===========|==================================================| +// | PIPELINE | Instruction Classes | +// |===========|==================================================| +// | SLOT0 | LD ST ALU32 MEMOP NV SYSTEM | +// |-----------|--------------------------------------------------| +// | SLOT1 | LD ST ALU32 | +// |-----------|--------------------------------------------------| +// | SLOT2 | XTYPE ALU32 J JR | +// |-----------|--------------------------------------------------| +// | SLOT3 | XTYPE ALU32 J CR | +// |===========|==================================================| + +// Functional Units. +def SLOT0 : FuncUnit; +def SLOT1 : FuncUnit; +def SLOT2 : FuncUnit; +def SLOT3 : FuncUnit; +// Endloop is a pseudo instruction that is encoded with 2 bits in a packet +// rather than taking an execution slot. This special unit is needed +// to schedule an ENDLOOP with 4 other instructions. +def SLOT_ENDLOOP: FuncUnit; + +// Itinerary classes. +def PSEUDO : InstrItinClass; +def PSEUDOM : InstrItinClass; +// ALU64/M/S Instruction classes of V2 are collectively knownn as XTYPE in V4. +def DUPLEX : InstrItinClass; +def PREFIX : InstrItinClass; +def COMPOUND_CJ_ARCHDEPSLOT : InstrItinClass; +def COMPOUND : InstrItinClass; + +def ALU32_2op_tc_1_SLOT0123 : InstrItinClass; +def ALU32_2op_tc_2early_SLOT0123 : InstrItinClass; +def ALU32_3op_tc_2early_SLOT0123 : InstrItinClass; +def ALU32_3op_tc_1_SLOT0123 : InstrItinClass; +def ALU32_3op_tc_2_SLOT0123 : InstrItinClass; +def ALU32_ADDI_tc_1_SLOT0123 : InstrItinClass; +def ALU64_tc_1_SLOT23 : InstrItinClass; +def ALU64_tc_1or2_SLOT23 : InstrItinClass; +def ALU64_tc_2_SLOT23 : InstrItinClass; +def ALU64_tc_2early_SLOT23 : InstrItinClass; +def ALU64_tc_3x_SLOT23 : InstrItinClass; +def CR_tc_2_SLOT3 : InstrItinClass; +def CR_tc_2early_SLOT23 : InstrItinClass; +def CR_tc_2early_SLOT3 : InstrItinClass; +def CR_tc_3x_SLOT23 : InstrItinClass; +def CR_tc_3x_SLOT3 : InstrItinClass; +def J_tc_2early_SLOT23 : InstrItinClass; +def J_tc_2early_CJUMP_UCJUMP_ARCHDEPSLOT : InstrItinClass; +def J_tc_2early_SLOT2 : InstrItinClass; +def LD_tc_ld_SLOT01 : InstrItinClass; +def LD_tc_ld_SLOT0 : InstrItinClass; +def LD_tc_3or4stall_SLOT0 : InstrItinClass; +def M_tc_1_SLOT23 : InstrItinClass; +def M_tc_1or2_SLOT23 : InstrItinClass; +def M_tc_2_SLOT23 : InstrItinClass; +def M_tc_3_SLOT23 : InstrItinClass; +def M_tc_3x_SLOT23 : InstrItinClass; +def M_tc_3or4x_SLOT23 : InstrItinClass; +def ST_tc_st_SLOT01 : InstrItinClass; +def ST_tc_st_SLOT0 : InstrItinClass; +def ST_tc_ld_SLOT0 : InstrItinClass; +def ST_tc_3stall_SLOT0 : InstrItinClass; +def S_2op_tc_1_SLOT23 : InstrItinClass; +def S_2op_tc_2_SLOT23 : InstrItinClass; +def S_2op_tc_2early_SLOT23 : InstrItinClass; +def S_2op_tc_3or4x_SLOT23 : InstrItinClass; +def S_3op_tc_1_SLOT23 : InstrItinClass; +def S_3op_tc_1or2_SLOT23 : InstrItinClass; +def S_3op_tc_2_SLOT23 : InstrItinClass; +def S_3op_tc_2early_SLOT23 : InstrItinClass; +def S_3op_tc_3_SLOT23 : InstrItinClass; +def S_3op_tc_3x_SLOT23 : InstrItinClass; +def NCJ_tc_3or4stall_SLOT0 : InstrItinClass; +def V2LDST_tc_ld_SLOT01 : InstrItinClass; +def V2LDST_tc_st_SLOT0 : InstrItinClass; +def V2LDST_tc_st_SLOT01 : InstrItinClass; +def V4LDST_tc_ld_SLOT01 : InstrItinClass; +def V4LDST_tc_st_SLOT0 : InstrItinClass; +def V4LDST_tc_st_SLOT01 : InstrItinClass; +def J_tc_2early_SLOT0123 : InstrItinClass; +def EXTENDER_tc_1_SLOT0123 : InstrItinClass; +def S_3op_tc_3stall_SLOT23 : InstrItinClass; -def HexagonV4ItinList : DepScalarItinV4, HexagonV4PseudoItin { - list<InstrItinData> V4Itin_list = [ - InstrItinData<LD_tc_ld_SLOT01, [InstrStage<1, [SLOT0, SLOT1]>]>, - InstrItinData<ST_tc_st_SLOT01, [InstrStage<1, [SLOT0, SLOT1]>]> - ]; - list<InstrItinData> ItinList = - !listconcat(V4Itin_list, DepScalarItinV4_list, V4PseudoItin_list); -} def HexagonItinerariesV4 : - ProcessorItineraries<[SLOT0, SLOT1, SLOT2, SLOT3, SLOT_ENDLOOP], - [Hex_FWD], HexagonV4ItinList.ItinList>; + ProcessorItineraries<[SLOT0, SLOT1, SLOT2, SLOT3, SLOT_ENDLOOP], [], [ + // ALU32 + InstrItinData<ALU32_2op_tc_1_SLOT0123 , + [InstrStage<1, [SLOT0, SLOT1, SLOT2, SLOT3]>]>, + InstrItinData<ALU32_2op_tc_2early_SLOT0123, + [InstrStage<1, [SLOT0, SLOT1, SLOT2, SLOT3]>]>, + InstrItinData<ALU32_3op_tc_1_SLOT0123 , + [InstrStage<1, [SLOT0, SLOT1, SLOT2, SLOT3]>]>, + InstrItinData<ALU32_3op_tc_2early_SLOT0123, + [InstrStage<1, [SLOT0, SLOT1, SLOT2, SLOT3]>]>, + InstrItinData<ALU32_3op_tc_2_SLOT0123 , + [InstrStage<1, [SLOT0, SLOT1, SLOT2, SLOT3]>]>, + InstrItinData<ALU32_ADDI_tc_1_SLOT0123 , + [InstrStage<1, [SLOT0, SLOT1, SLOT2, SLOT3]>]>, + + // ALU64 + InstrItinData<ALU64_tc_1_SLOT23 , [InstrStage<1, [SLOT2, SLOT3]>]>, + InstrItinData<ALU64_tc_1or2_SLOT23 , [InstrStage<1, [SLOT2, SLOT3]>]>, + InstrItinData<ALU64_tc_2_SLOT23 , [InstrStage<1, [SLOT2, SLOT3]>]>, + InstrItinData<ALU64_tc_2early_SLOT23 , [InstrStage<1, [SLOT2, SLOT3]>]>, + InstrItinData<ALU64_tc_3x_SLOT23 , [InstrStage<1, [SLOT2, SLOT3]>]>, + + // CR -> System + InstrItinData<CR_tc_2_SLOT3 , [InstrStage<1, [SLOT3]>]>, + InstrItinData<CR_tc_2early_SLOT3 , [InstrStage<1, [SLOT3]>]>, + InstrItinData<CR_tc_3x_SLOT3 , [InstrStage<1, [SLOT3]>]>, + + // Jump (conditional/unconditional/return etc) + // CR + InstrItinData<CR_tc_2early_SLOT23 , [InstrStage<1, [SLOT2, SLOT3]>]>, + InstrItinData<CR_tc_3x_SLOT23 , [InstrStage<1, [SLOT2, SLOT3]>]>, + // J + InstrItinData<J_tc_2early_SLOT23 , [InstrStage<1, [SLOT2, SLOT3]>]>, + // JR + InstrItinData<J_tc_2early_SLOT2 , [InstrStage<1, [SLOT2]>]>, + + //Load + InstrItinData<LD_tc_ld_SLOT01 , [InstrStage<1, [SLOT0, SLOT1]>]>, + InstrItinData<LD_tc_ld_SLOT0 , [InstrStage<1, [SLOT0]>]>, + InstrItinData<LD_tc_3or4stall_SLOT0 , [InstrStage<1, [SLOT0]>]>, + + // M + InstrItinData<M_tc_1_SLOT23 , [InstrStage<1, [SLOT2, SLOT3]>]>, + InstrItinData<M_tc_1or2_SLOT23 , [InstrStage<1, [SLOT2, SLOT3]>]>, + InstrItinData<M_tc_2_SLOT23 , [InstrStage<1, [SLOT2, SLOT3]>]>, + InstrItinData<M_tc_3_SLOT23 , [InstrStage<1, [SLOT2, SLOT3]>]>, + InstrItinData<M_tc_3x_SLOT23 , [InstrStage<1, [SLOT2, SLOT3]>]>, + InstrItinData<M_tc_3or4x_SLOT23 , [InstrStage<1, [SLOT2, SLOT3]>]>, + + // Store + // ST + InstrItinData<ST_tc_st_SLOT01 , [InstrStage<1, [SLOT0, SLOT1]>]>, + // ST0 + InstrItinData<ST_tc_st_SLOT0 , [InstrStage<1, [SLOT0]>]>, + InstrItinData<ST_tc_ld_SLOT0 , [InstrStage<1, [SLOT0]>]>, + + // S + InstrItinData<S_2op_tc_1_SLOT23 , [InstrStage<1, [SLOT2, SLOT3]>]>, + InstrItinData<S_2op_tc_2_SLOT23 , [InstrStage<1, [SLOT2, SLOT3]>]>, + InstrItinData<S_2op_tc_2early_SLOT23 , [InstrStage<1, [SLOT2, SLOT3]>]>, + InstrItinData<S_2op_tc_3or4x_SLOT23 , [InstrStage<1, [SLOT2, SLOT3]>]>, + InstrItinData<S_3op_tc_1_SLOT23 , [InstrStage<1, [SLOT2, SLOT3]>]>, + InstrItinData<S_3op_tc_1or2_SLOT23 , [InstrStage<1, [SLOT2, SLOT3]>]>, + InstrItinData<S_3op_tc_2early_SLOT23 , [InstrStage<1, [SLOT2, SLOT3]>]>, + InstrItinData<S_3op_tc_2_SLOT23 , [InstrStage<1, [SLOT2, SLOT3]>]>, + InstrItinData<S_3op_tc_3_SLOT23 , [InstrStage<1, [SLOT2, SLOT3]>]>, + InstrItinData<S_3op_tc_3x_SLOT23 , [InstrStage<1, [SLOT2, SLOT3]>]>, + + // SYS + InstrItinData<ST_tc_3stall_SLOT0 , [InstrStage<1, [SLOT0]>]>, + + // New Value Compare Jump + InstrItinData<NCJ_tc_3or4stall_SLOT0 , [InstrStage<1, [SLOT0]>]>, + + // Mem ops - MEM_V4 + InstrItinData<V2LDST_tc_st_SLOT0 , [InstrStage<1, [SLOT0]>]>, + InstrItinData<V2LDST_tc_ld_SLOT01 , [InstrStage<1, [SLOT0, SLOT1]>]>, + InstrItinData<V2LDST_tc_st_SLOT01 , [InstrStage<1, [SLOT0, SLOT1]>]>, + InstrItinData<V4LDST_tc_st_SLOT0 , [InstrStage<1, [SLOT0]>]>, + InstrItinData<V4LDST_tc_ld_SLOT01 , [InstrStage<1, [SLOT0, SLOT1]>]>, + InstrItinData<V4LDST_tc_st_SLOT01 , [InstrStage<1, [SLOT0, SLOT1]>]>, + + InstrItinData<DUPLEX , [InstrStage<1, [SLOT0]>]>, + + // ENDLOOP + InstrItinData<J_tc_2early_SLOT0123 , [InstrStage<1, [SLOT_ENDLOOP]>]>, + + // Extender/PREFIX + InstrItinData<EXTENDER_tc_1_SLOT0123, + [InstrStage<1, [SLOT0, SLOT1, SLOT2, SLOT3]>]>, + + InstrItinData<COMPOUND , [InstrStage<1, [SLOT2, SLOT3]>]>, + InstrItinData<PSEUDO , [InstrStage<1, [SLOT0, SLOT1, SLOT2, SLOT3]>]>, + InstrItinData<PSEUDOM, [InstrStage<1, [SLOT2, SLOT3], 0>, + InstrStage<1, [SLOT2, SLOT3]>]> + ]>; def HexagonModelV4 : SchedMachineModel { // Max issue per cycle == bundle width. let IssueWidth = 4; let Itineraries = HexagonItinerariesV4; let LoadLatency = 1; - let CompleteModel = 0; } //===----------------------------------------------------------------------===// diff --git a/gnu/llvm/lib/Target/WebAssembly/WebAssemblyStoreResults.cpp b/gnu/llvm/lib/Target/WebAssembly/WebAssemblyStoreResults.cpp index 893e8484c4c..4e08b2b079e 100644 --- a/gnu/llvm/lib/Target/WebAssembly/WebAssemblyStoreResults.cpp +++ b/gnu/llvm/lib/Target/WebAssembly/WebAssemblyStoreResults.cpp @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// /// /// \file -/// This file implements an optimization pass using store result values. +/// \brief This file implements an optimization pass using store result values. /// /// WebAssembly's store instructions return the stored value. This is to enable /// an optimization wherein uses of the stored value can be replaced by uses of @@ -17,19 +17,12 @@ /// potentially also exposing the store to register stackifying. These both can /// reduce get_local/set_local traffic. /// -/// This pass also performs this optimization for memcpy, memmove, and memset -/// calls, since the LLVM intrinsics for these return void so they can't use the -/// returned attribute and consequently aren't handled by the OptimizeReturned -/// pass. -/// //===----------------------------------------------------------------------===// -#include "MCTargetDesc/WebAssemblyMCTargetDesc.h" #include "WebAssembly.h" +#include "MCTargetDesc/WebAssemblyMCTargetDesc.h" #include "WebAssemblyMachineFunctionInfo.h" #include "WebAssemblySubtarget.h" -#include "llvm/Analysis/TargetLibraryInfo.h" -#include "llvm/CodeGen/LiveIntervals.h" #include "llvm/CodeGen/MachineBlockFrequencyInfo.h" #include "llvm/CodeGen/MachineDominators.h" #include "llvm/CodeGen/MachineRegisterInfo.h" @@ -46,7 +39,9 @@ public: static char ID; // Pass identification, replacement for typeid WebAssemblyStoreResults() : MachineFunctionPass(ID) {} - StringRef getPassName() const override { return "WebAssembly Store Results"; } + const char *getPassName() const override { + return "WebAssembly Store Results"; + } void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesCFG(); @@ -54,10 +49,6 @@ public: AU.addPreserved<MachineBlockFrequencyInfo>(); AU.addRequired<MachineDominatorTree>(); AU.addPreserved<MachineDominatorTree>(); - AU.addRequired<LiveIntervals>(); - AU.addPreserved<SlotIndexes>(); - AU.addPreserved<LiveIntervals>(); - AU.addRequired<TargetLibraryInfoWrapperPass>(); MachineFunctionPass::getAnalysisUsage(AU); } @@ -68,136 +59,64 @@ private: } // end anonymous namespace char WebAssemblyStoreResults::ID = 0; -INITIALIZE_PASS(WebAssemblyStoreResults, DEBUG_TYPE, - "Optimize store result values for WebAssembly", false, false) - FunctionPass *llvm::createWebAssemblyStoreResults() { return new WebAssemblyStoreResults(); } -// Replace uses of FromReg with ToReg if they are dominated by MI. -static bool ReplaceDominatedUses(MachineBasicBlock &MBB, MachineInstr &MI, - unsigned FromReg, unsigned ToReg, - const MachineRegisterInfo &MRI, - MachineDominatorTree &MDT, - LiveIntervals &LIS) { - bool Changed = false; - - LiveInterval *FromLI = &LIS.getInterval(FromReg); - LiveInterval *ToLI = &LIS.getInterval(ToReg); - - SlotIndex FromIdx = LIS.getInstructionIndex(MI).getRegSlot(); - VNInfo *FromVNI = FromLI->getVNInfoAt(FromIdx); - - SmallVector<SlotIndex, 4> Indices; - - for (auto I = MRI.use_nodbg_begin(FromReg), E = MRI.use_nodbg_end(); I != E;) { - MachineOperand &O = *I++; - MachineInstr *Where = O.getParent(); - - // Check that MI dominates the instruction in the normal way. - if (&MI == Where || !MDT.dominates(&MI, Where)) - continue; - - // If this use gets a different value, skip it. - SlotIndex WhereIdx = LIS.getInstructionIndex(*Where); - VNInfo *WhereVNI = FromLI->getVNInfoAt(WhereIdx); - if (WhereVNI && WhereVNI != FromVNI) - continue; - - // Make sure ToReg isn't clobbered before it gets there. - VNInfo *ToVNI = ToLI->getVNInfoAt(WhereIdx); - if (ToVNI && ToVNI != FromVNI) - continue; - - Changed = true; - LLVM_DEBUG(dbgs() << "Setting operand " << O << " in " << *Where << " from " - << MI << "\n"); - O.setReg(ToReg); - - // If the store's def was previously dead, it is no longer. - if (!O.isUndef()) { - MI.getOperand(0).setIsDead(false); - - Indices.push_back(WhereIdx.getRegSlot()); - } - } - - if (Changed) { - // Extend ToReg's liveness. - LIS.extendToIndices(*ToLI, Indices); - - // Shrink FromReg's liveness. - LIS.shrinkToUses(FromLI); - - // If we replaced all dominated uses, FromReg is now killed at MI. - if (!FromLI->liveAt(FromIdx.getDeadSlot())) - MI.addRegisterKilled(FromReg, - MBB.getParent()->getSubtarget<WebAssemblySubtarget>() - .getRegisterInfo()); - } - - return Changed; -} - -static bool optimizeCall(MachineBasicBlock &MBB, MachineInstr &MI, - const MachineRegisterInfo &MRI, - MachineDominatorTree &MDT, - LiveIntervals &LIS, - const WebAssemblyTargetLowering &TLI, - const TargetLibraryInfo &LibInfo) { - MachineOperand &Op1 = MI.getOperand(1); - if (!Op1.isSymbol()) - return false; - - StringRef Name(Op1.getSymbolName()); - bool callReturnsInput = Name == TLI.getLibcallName(RTLIB::MEMCPY) || - Name == TLI.getLibcallName(RTLIB::MEMMOVE) || - Name == TLI.getLibcallName(RTLIB::MEMSET); - if (!callReturnsInput) - return false; - - LibFunc Func; - if (!LibInfo.getLibFunc(Name, Func)) - return false; - - unsigned FromReg = MI.getOperand(2).getReg(); - unsigned ToReg = MI.getOperand(0).getReg(); - if (MRI.getRegClass(FromReg) != MRI.getRegClass(ToReg)) - report_fatal_error("Store results: call to builtin function with wrong " - "signature, from/to mismatch"); - return ReplaceDominatedUses(MBB, MI, FromReg, ToReg, MRI, MDT, LIS); -} - bool WebAssemblyStoreResults::runOnMachineFunction(MachineFunction &MF) { - LLVM_DEBUG({ + DEBUG({ dbgs() << "********** Store Results **********\n" << "********** Function: " << MF.getName() << '\n'; }); - MachineRegisterInfo &MRI = MF.getRegInfo(); + const MachineRegisterInfo &MRI = MF.getRegInfo(); MachineDominatorTree &MDT = getAnalysis<MachineDominatorTree>(); - const WebAssemblyTargetLowering &TLI = - *MF.getSubtarget<WebAssemblySubtarget>().getTargetLowering(); - const auto &LibInfo = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(); - LiveIntervals &LIS = getAnalysis<LiveIntervals>(); bool Changed = false; - // We don't preserve SSA form. - MRI.leaveSSA(); - - assert(MRI.tracksLiveness() && "StoreResults expects liveness tracking"); + assert(MRI.isSSA() && "StoreResults depends on SSA form"); for (auto &MBB : MF) { - LLVM_DEBUG(dbgs() << "Basic Block: " << MBB.getName() << '\n'); + DEBUG(dbgs() << "Basic Block: " << MBB.getName() << '\n'); for (auto &MI : MBB) switch (MI.getOpcode()) { default: break; - case WebAssembly::CALL_I32: - case WebAssembly::CALL_I64: - Changed |= optimizeCall(MBB, MI, MRI, MDT, LIS, TLI, LibInfo); - break; + case WebAssembly::STORE8_I32: + case WebAssembly::STORE16_I32: + case WebAssembly::STORE8_I64: + case WebAssembly::STORE16_I64: + case WebAssembly::STORE32_I64: + case WebAssembly::STORE_F32: + case WebAssembly::STORE_F64: + case WebAssembly::STORE_I32: + case WebAssembly::STORE_I64: + unsigned ToReg = MI.getOperand(0).getReg(); + unsigned FromReg = MI.getOperand(3).getReg(); + for (auto I = MRI.use_begin(FromReg), E = MRI.use_end(); I != E;) { + MachineOperand &O = *I++; + MachineInstr *Where = O.getParent(); + if (Where->getOpcode() == TargetOpcode::PHI) { + // PHIs use their operands on their incoming CFG edges rather than + // in their parent blocks. Get the basic block paired with this use + // of FromReg and check that MI's block dominates it. + MachineBasicBlock *Pred = + Where->getOperand(&O - &Where->getOperand(0) + 1).getMBB(); + if (!MDT.dominates(&MBB, Pred)) + continue; + } else { + // For a non-PHI, check that MI dominates the instruction in the + // normal way. + if (&MI == Where || !MDT.dominates(&MI, Where)) + continue; + } + Changed = true; + DEBUG(dbgs() << "Setting operand " << O << " in " << *Where + << " from " << MI << "\n"); + O.setReg(ToReg); + // If the store's def was previously dead, it is no longer. But the + // dead flag shouldn't be set yet. + assert(!MI.getOperand(0).isDead() && "Dead flag set on store result"); + } } } diff --git a/gnu/llvm/tools/clang/include/clang/Basic/VirtualFileSystem.h b/gnu/llvm/tools/clang/include/clang/Basic/VirtualFileSystem.h index 2480b91123c..bab88c90b0a 100644 --- a/gnu/llvm/tools/clang/include/clang/Basic/VirtualFileSystem.h +++ b/gnu/llvm/tools/clang/include/clang/Basic/VirtualFileSystem.h @@ -6,10 +6,8 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -// /// \file -/// Defines the virtual file system interface vfs::FileSystem. -// +/// \brief Defines the virtual file system interface vfs::FileSystem. //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_BASIC_VIRTUALFILESYSTEM_H @@ -17,53 +15,38 @@ #include "clang/Basic/LLVM.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" -#include "llvm/ADT/None.h" #include "llvm/ADT/Optional.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/ADT/Twine.h" -#include "llvm/Support/Chrono.h" #include "llvm/Support/ErrorOr.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/SourceMgr.h" -#include <cassert> -#include <cstdint> -#include <ctime> -#include <memory> -#include <stack> -#include <string> -#include <system_error> -#include <utility> -#include <vector> +#include "llvm/Support/raw_ostream.h" namespace llvm { - class MemoryBuffer; - -} // namespace llvm +} namespace clang { namespace vfs { -/// The result of a \p status operation. +/// \brief The result of a \p status operation. class Status { std::string Name; llvm::sys::fs::UniqueID UID; - llvm::sys::TimePoint<> MTime; + llvm::sys::TimeValue MTime; uint32_t User; uint32_t Group; uint64_t Size; - llvm::sys::fs::file_type Type = llvm::sys::fs::file_type::status_error; + llvm::sys::fs::file_type Type; llvm::sys::fs::perms Perms; public: - // FIXME: remove when files support multiple names - bool IsVFSMapped = false; + bool IsVFSMapped; // FIXME: remove when files support multiple names - Status() = default; +public: + Status() : Type(llvm::sys::fs::file_type::status_error) {} Status(const llvm::sys::fs::file_status &Status); Status(StringRef Name, llvm::sys::fs::UniqueID UID, - llvm::sys::TimePoint<> MTime, uint32_t User, uint32_t Group, + llvm::sys::TimeValue MTime, uint32_t User, uint32_t Group, uint64_t Size, llvm::sys::fs::file_type Type, llvm::sys::fs::perms Perms); @@ -72,14 +55,14 @@ public: static Status copyWithNewName(const llvm::sys::fs::file_status &In, StringRef NewName); - /// Returns the name that should be used for this file or directory. + /// \brief Returns the name that should be used for this file or directory. StringRef getName() const { return Name; } /// @name Status interface from llvm::sys::fs /// @{ llvm::sys::fs::file_type getType() const { return Type; } llvm::sys::fs::perms getPermissions() const { return Perms; } - llvm::sys::TimePoint<> getLastModificationTime() const { return MTime; } + llvm::sys::TimeValue getLastModificationTime() const { return MTime; } llvm::sys::fs::UniqueID getUniqueID() const { return UID; } uint32_t getUser() const { return User; } uint32_t getGroup() const { return Group; } @@ -98,71 +81,55 @@ public: /// @} }; -/// Represents an open file. +/// \brief Represents an open file. class File { public: - /// Destroy the file after closing it (if open). + /// \brief Destroy the file after closing it (if open). /// Sub-classes should generally call close() inside their destructors. We /// cannot do that from the base class, since close is virtual. virtual ~File(); - - /// Get the status of the file. + /// \brief Get the status of the file. virtual llvm::ErrorOr<Status> status() = 0; - - /// Get the name of the file - virtual llvm::ErrorOr<std::string> getName() { - if (auto Status = status()) - return Status->getName().str(); - else - return Status.getError(); - } - - /// Get the contents of the file as a \p MemoryBuffer. + /// \brief Get the contents of the file as a \p MemoryBuffer. virtual llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> getBuffer(const Twine &Name, int64_t FileSize = -1, bool RequiresNullTerminator = true, bool IsVolatile = false) = 0; - - /// Closes the file. + /// \brief Closes the file. virtual std::error_code close() = 0; }; namespace detail { - -/// An interface for virtual file systems to provide an iterator over the +/// \brief An interface for virtual file systems to provide an iterator over the /// (non-recursive) contents of a directory. struct DirIterImpl { virtual ~DirIterImpl(); - - /// Sets \c CurrentEntry to the next entry in the directory on success, + /// \brief Sets \c CurrentEntry to the next entry in the directory on success, /// or returns a system-defined \c error_code. virtual std::error_code increment() = 0; - Status CurrentEntry; }; +} // end namespace detail -} // namespace detail - -/// An input iterator over the entries in a virtual path, similar to +/// \brief An input iterator over the entries in a virtual path, similar to /// llvm::sys::fs::directory_iterator. class directory_iterator { std::shared_ptr<detail::DirIterImpl> Impl; // Input iterator semantics on copy public: - directory_iterator(std::shared_ptr<detail::DirIterImpl> I) - : Impl(std::move(I)) { + directory_iterator(std::shared_ptr<detail::DirIterImpl> I) : Impl(I) { assert(Impl.get() != nullptr && "requires non-null implementation"); if (!Impl->CurrentEntry.isStatusKnown()) Impl.reset(); // Normalize the end iterator to Impl == nullptr. } - /// Construct an 'end' iterator. - directory_iterator() = default; + /// \brief Construct an 'end' iterator. + directory_iterator() { } - /// Equivalent to operator++, with an error code. + /// \brief Equivalent to operator++, with an error code. directory_iterator &increment(std::error_code &EC) { assert(Impl && "attempting to increment past end"); EC = Impl->increment(); - if (!Impl->CurrentEntry.isStatusKnown()) + if (EC || !Impl->CurrentEntry.isStatusKnown()) Impl.reset(); // Normalize the end iterator to Impl == nullptr. return *this; } @@ -182,11 +149,11 @@ public: class FileSystem; -/// An input iterator over the recursive contents of a virtual path, +/// \brief An input iterator over the recursive contents of a virtual path, /// similar to llvm::sys::fs::recursive_directory_iterator. class recursive_directory_iterator { - using IterState = - std::stack<directory_iterator, std::vector<directory_iterator>>; + typedef std::stack<directory_iterator, std::vector<directory_iterator>> + IterState; FileSystem *FS; std::shared_ptr<IterState> State; // Input iterator semantics on copy. @@ -194,11 +161,10 @@ class recursive_directory_iterator { public: recursive_directory_iterator(FileSystem &FS, const Twine &Path, std::error_code &EC); + /// \brief Construct an 'end' iterator. + recursive_directory_iterator() { } - /// Construct an 'end' iterator. - recursive_directory_iterator() = default; - - /// Equivalent to operator++, with an error code. + /// \brief Equivalent to operator++, with an error code. recursive_directory_iterator &increment(std::error_code &EC); const Status &operator*() const { return *State->top(); } @@ -210,23 +176,16 @@ public: bool operator!=(const recursive_directory_iterator &RHS) const { return !(*this == RHS); } - - /// Gets the current level. Starting path is at level 0. - int level() const { - assert(!State->empty() && "Cannot get level without any iteration state"); - return State->size()-1; - } }; -/// The virtual file system interface. +/// \brief The virtual file system interface. class FileSystem : public llvm::ThreadSafeRefCountedBase<FileSystem> { public: virtual ~FileSystem(); - /// Get the status of the entry at \p Path, if one exists. + /// \brief Get the status of the entry at \p Path, if one exists. virtual llvm::ErrorOr<Status> status(const Twine &Path) = 0; - - /// Get a \p File object for the file at \p Path, if one exists. + /// \brief Get a \p File object for the file at \p Path, if one exists. virtual llvm::ErrorOr<std::unique_ptr<File>> openFileForRead(const Twine &Path) = 0; @@ -236,7 +195,7 @@ public: getBufferForFile(const Twine &Name, int64_t FileSize = -1, bool RequiresNullTerminator = true, bool IsVolatile = false); - /// Get a directory_iterator for \p Dir. + /// \brief Get a directory_iterator for \p Dir. /// \note The 'end' iterator is directory_iterator(). virtual directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) = 0; @@ -244,16 +203,9 @@ public: /// Set the working directory. This will affect all following operations on /// this file system and may propagate down for nested file systems. virtual std::error_code setCurrentWorkingDirectory(const Twine &Path) = 0; - /// Get the working directory of this file system. virtual llvm::ErrorOr<std::string> getCurrentWorkingDirectory() const = 0; - /// Gets real path of \p Path e.g. collapse all . and .. patterns, resolve - /// symlinks. For real file system, this uses `llvm::sys::fs::real_path`. - /// This returns errc::operation_not_permitted if not implemented by subclass. - virtual std::error_code getRealPath(const Twine &Path, - SmallVectorImpl<char> &Output) const; - /// Check whether a file exists. Provided for convenience. bool exists(const Twine &Path); @@ -271,11 +223,11 @@ public: std::error_code makeAbsolute(SmallVectorImpl<char> &Path) const; }; -/// Gets an \p vfs::FileSystem for the 'real' file system, as seen by +/// \brief Gets an \p vfs::FileSystem for the 'real' file system, as seen by /// the operating system. IntrusiveRefCntPtr<FileSystem> getRealFileSystem(); -/// A file system that allows overlaying one \p AbstractFileSystem on top +/// \brief A file system that allows overlaying one \p AbstractFileSystem on top /// of another. /// /// Consists of a stack of >=1 \p FileSystem objects, which are treated as being @@ -286,16 +238,14 @@ IntrusiveRefCntPtr<FileSystem> getRealFileSystem(); /// that exists in more than one file system, the file in the top-most file /// system overrides the other(s). class OverlayFileSystem : public FileSystem { - using FileSystemList = SmallVector<IntrusiveRefCntPtr<FileSystem>, 1>; - - /// The stack of file systems, implemented as a list in order of + typedef SmallVector<IntrusiveRefCntPtr<FileSystem>, 1> FileSystemList; + /// \brief The stack of file systems, implemented as a list in order of /// their addition. FileSystemList FSList; public: OverlayFileSystem(IntrusiveRefCntPtr<FileSystem> Base); - - /// Pushes a file system on top of the stack. + /// \brief Pushes a file system on top of the stack. void pushOverlay(IntrusiveRefCntPtr<FileSystem> FS); llvm::ErrorOr<Status> status(const Twine &Path) override; @@ -304,27 +254,20 @@ public: directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) override; llvm::ErrorOr<std::string> getCurrentWorkingDirectory() const override; std::error_code setCurrentWorkingDirectory(const Twine &Path) override; - std::error_code getRealPath(const Twine &Path, - SmallVectorImpl<char> &Output) const override; - using iterator = FileSystemList::reverse_iterator; - using const_iterator = FileSystemList::const_reverse_iterator; - - /// Get an iterator pointing to the most recently added file system. + typedef FileSystemList::reverse_iterator iterator; + + /// \brief Get an iterator pointing to the most recently added file system. iterator overlays_begin() { return FSList.rbegin(); } - const_iterator overlays_begin() const { return FSList.rbegin(); } - /// Get an iterator pointing one-past the least recently added file + /// \brief Get an iterator pointing one-past the least recently added file /// system. iterator overlays_end() { return FSList.rend(); } - const_iterator overlays_end() const { return FSList.rend(); } }; namespace detail { - class InMemoryDirectory; - -} // namespace detail +} // end namespace detail /// An in-memory file system. class InMemoryFileSystem : public FileSystem { @@ -335,34 +278,17 @@ class InMemoryFileSystem : public FileSystem { public: explicit InMemoryFileSystem(bool UseNormalizedPaths = true); ~InMemoryFileSystem() override; - - /// Add a file containing a buffer or a directory to the VFS with a - /// path. The VFS owns the buffer. If present, User, Group, Type - /// and Perms apply to the newly-created file or directory. - /// \return true if the file or directory was successfully added, - /// false if the file or directory already exists in the file system with - /// different contents. + /// Add a buffer to the VFS with a path. The VFS owns the buffer. + /// \return true if the file was successfully added, false if the file already + /// exists in the file system with different contents. bool addFile(const Twine &Path, time_t ModificationTime, - std::unique_ptr<llvm::MemoryBuffer> Buffer, - Optional<uint32_t> User = None, Optional<uint32_t> Group = None, - Optional<llvm::sys::fs::file_type> Type = None, - Optional<llvm::sys::fs::perms> Perms = None); - + std::unique_ptr<llvm::MemoryBuffer> Buffer); /// Add a buffer to the VFS with a path. The VFS does not own the buffer. - /// If present, User, Group, Type and Perms apply to the newly-created file - /// or directory. - /// \return true if the file or directory was successfully added, - /// false if the file or directory already exists in the file system with - /// different contents. + /// \return true if the file was successfully added, false if the file already + /// exists in the file system with different contents. bool addFileNoOwn(const Twine &Path, time_t ModificationTime, - llvm::MemoryBuffer *Buffer, - Optional<uint32_t> User = None, - Optional<uint32_t> Group = None, - Optional<llvm::sys::fs::file_type> Type = None, - Optional<llvm::sys::fs::perms> Perms = None); - + llvm::MemoryBuffer *Buffer); std::string toString() const; - /// Return true if this file system normalizes . and .. in paths. bool useNormalizedPaths() const { return UseNormalizedPaths; } @@ -370,31 +296,20 @@ public: llvm::ErrorOr<std::unique_ptr<File>> openFileForRead(const Twine &Path) override; directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) override; - llvm::ErrorOr<std::string> getCurrentWorkingDirectory() const override { return WorkingDirectory; } - /// Canonicalizes \p Path by combining with the current working - /// directory and normalizing the path (e.g. remove dots). If the current - /// working directory is not set, this returns errc::operation_not_permitted. - /// - /// This doesn't resolve symlinks as they are not supported in in-memory file - /// system. - std::error_code getRealPath(const Twine &Path, - SmallVectorImpl<char> &Output) const override; - std::error_code setCurrentWorkingDirectory(const Twine &Path) override; }; -/// Get a globally unique ID for a virtual file or directory. +/// \brief Get a globally unique ID for a virtual file or directory. llvm::sys::fs::UniqueID getNextVirtualUniqueID(); -/// Gets a \p FileSystem for a virtual file system described in YAML +/// \brief Gets a \p FileSystem for a virtual file system described in YAML /// format. IntrusiveRefCntPtr<FileSystem> getVFSFromYAML(std::unique_ptr<llvm::MemoryBuffer> Buffer, llvm::SourceMgr::DiagHandlerTy DiagHandler, - StringRef YAMLFilePath, void *DiagContext = nullptr, IntrusiveRefCntPtr<FileSystem> ExternalFS = getRealFileSystem()); @@ -405,50 +320,19 @@ struct YAMLVFSEntry { std::string RPath; }; -/// Collect all pairs of <virtual path, real path> entries from the -/// \p YAMLFilePath. This is used by the module dependency collector to forward -/// the entries into the reproducer output VFS YAML file. -void collectVFSFromYAML( - std::unique_ptr<llvm::MemoryBuffer> Buffer, - llvm::SourceMgr::DiagHandlerTy DiagHandler, StringRef YAMLFilePath, - SmallVectorImpl<YAMLVFSEntry> &CollectedEntries, - void *DiagContext = nullptr, - IntrusiveRefCntPtr<FileSystem> ExternalFS = getRealFileSystem()); - class YAMLVFSWriter { std::vector<YAMLVFSEntry> Mappings; Optional<bool> IsCaseSensitive; - Optional<bool> IsOverlayRelative; - Optional<bool> UseExternalNames; - Optional<bool> IgnoreNonExistentContents; - std::string OverlayDir; public: - YAMLVFSWriter() = default; - + YAMLVFSWriter() {} void addFileMapping(StringRef VirtualPath, StringRef RealPath); - void setCaseSensitivity(bool CaseSensitive) { IsCaseSensitive = CaseSensitive; } - - void setUseExternalNames(bool UseExtNames) { - UseExternalNames = UseExtNames; - } - - void setIgnoreNonExistentContents(bool IgnoreContents) { - IgnoreNonExistentContents = IgnoreContents; - } - - void setOverlayDir(StringRef OverlayDirectory) { - IsOverlayRelative = true; - OverlayDir.assign(OverlayDirectory.str()); - } - void write(llvm::raw_ostream &OS); }; -} // namespace vfs -} // namespace clang - -#endif // LLVM_CLANG_BASIC_VIRTUALFILESYSTEM_H +} // end namespace vfs +} // end namespace clang +#endif diff --git a/gnu/llvm/tools/clang/include/clang/Frontend/CodeGenOptions.h b/gnu/llvm/tools/clang/include/clang/Frontend/CodeGenOptions.h index a6d061acf0f..7550e6f4c74 100644 --- a/gnu/llvm/tools/clang/include/clang/Frontend/CodeGenOptions.h +++ b/gnu/llvm/tools/clang/include/clang/Frontend/CodeGenOptions.h @@ -14,12 +14,8 @@ #ifndef LLVM_CLANG_FRONTEND_CODEGENOPTIONS_H #define LLVM_CLANG_FRONTEND_CODEGENOPTIONS_H -#include "clang/Basic/DebugInfoOptions.h" #include "clang/Basic/Sanitizers.h" -#include "clang/Basic/XRayInstr.h" -#include "llvm/Support/CodeGen.h" #include "llvm/Support/Regex.h" -#include "llvm/Target/TargetOptions.h" #include <map> #include <memory> #include <string> @@ -27,7 +23,7 @@ namespace clang { -/// Bitfields of CodeGenOptions, split out from CodeGenOptions to ensure +/// \brief Bitfields of CodeGenOptions, split out from CodeGenOptions to ensure /// that this large collection of bitfields is a trivial class type. class CodeGenOptionsBase { public: @@ -46,24 +42,53 @@ protected: class CodeGenOptions : public CodeGenOptionsBase { public: enum InliningMethod { + NoInlining, // Perform no inlining whatsoever. NormalInlining, // Use the standard function inlining pass. - OnlyHintInlining, // Inline only (implicitly) hinted functions. OnlyAlwaysInlining // Only run the always inlining pass. }; enum VectorLibrary { - NoLibrary, // Don't use any vector library. - Accelerate, // Use the Accelerate framework. - SVML // Intel short vector math library. + NoLibrary, // Don't use any vector library. + Accelerate // Use the Accelerate framework. }; - enum ObjCDispatchMethodKind { Legacy = 0, NonLegacy = 1, Mixed = 2 }; + enum DebugInfoKind { + NoDebugInfo, /// Don't generate debug info. + + LocTrackingOnly, /// Emit location information but do not generate + /// debug info in the output. This is useful in + /// cases where the backend wants to track source + /// locations for instructions without actually + /// emitting debug info for them (e.g., when -Rpass + /// is used). + + DebugLineTablesOnly, /// Emit only debug info necessary for generating + /// line number tables (-gline-tables-only). + + LimitedDebugInfo, /// Limit generated debug info to reduce size + /// (-fno-standalone-debug). This emits + /// forward decls for types that could be + /// replaced with forward decls in the source + /// code. For dynamic C++ classes type info + /// is only emitted int the module that + /// contains the classe's vtable. + + FullDebugInfo /// Generate complete debug info. + }; + + enum DebuggerKind { + DebuggerKindDefault, + DebuggerKindGDB, + DebuggerKindLLDB, + DebuggerKindSCE + }; + enum TLSModel { GeneralDynamicTLSModel, LocalDynamicTLSModel, @@ -71,21 +96,10 @@ public: LocalExecTLSModel }; - /// Clang versions with different platform ABI conformance. - enum class ClangABI { - /// Attempt to be ABI-compatible with code generated by Clang 3.8.x - /// (SVN r257626). This causes <1 x long long> to be passed in an - /// integer register instead of an SSE register on x64_64. - Ver3_8, - - /// Attempt to be ABI-compatible with code generated by Clang 4.0.x - /// (SVN r291814). This causes move operations to be ignored when - /// determining whether a class type can be passed or returned directly. - Ver4, - - /// Conform to the underlying platform's C and C++ ABIs as closely - /// as we can. - Latest + enum FPContractModeKind { + FPC_Off, // Form fused FP ops only where result will not be affected. + FPC_On, // Form fused FP ops according to FP_CONTRACT rules. + FPC_Fast // Aggressively fuse FP ops (E.g. FMA). }; enum StructReturnConventionKind { @@ -94,30 +108,12 @@ public: SRCK_InRegs // Small structs in registers (-freg-struct-return). }; - enum ProfileInstrKind { - ProfileNone, // Profile instrumentation is turned off. - ProfileClangInstr, // Clang instrumentation to generate execution counts - // to use with PGO. - ProfileIRInstr, // IR level PGO instrumentation in LLVM. - }; - - enum EmbedBitcodeKind { - Embed_Off, // No embedded bitcode. - Embed_All, // Embed both bitcode and commandline in the output. - Embed_Bitcode, // Embed just the bitcode in the output. - Embed_Marker // Embed a marker as a placeholder for bitcode. - }; - /// The code model to use (-mcmodel). std::string CodeModel; - /// The filename with path we use for coverage data files. The runtime - /// allows further manipulation with the GCOV_PREFIX and GCOV_PREFIX_STRIP - /// environment variables. - std::string CoverageDataFile; - - /// The filename with path we use for coverage notes files. - std::string CoverageNotesFile; + /// The filename with path we use for coverage files. The extension will be + /// replaced. + std::string CoverageFile; /// The version string to put into coverage files. char CoverageVersion[4]; @@ -137,27 +133,11 @@ public: /// The ABI to use for passing floating point arguments. std::string FloatABI; - /// The floating-point denormal mode to use. - std::string FPDenormalMode; - /// The float precision limit to use, if non-empty. std::string LimitFloatPrecision; - struct BitcodeFileToLink { - /// The filename of the bitcode file to link in. - std::string Filename; - /// If true, we set attributes functions in the bitcode library according to - /// our CodeGenOptions, much as we set attrs on functions that we generate - /// ourselves. - bool PropagateAttrs = false; - /// If true, we use LLVM module internalizer. - bool Internalize = false; - /// Bitwise combination of llvm::Linker::Flags, passed to the LLVM linker. - unsigned LinkFlags = 0; - }; - - /// The files specified here are linked in to the module before optimizations. - std::vector<BitcodeFileToLink> LinkBitcodeFiles; + /// The name of the bitcode file to link before optzns. + std::vector<std::pair<unsigned, std::string>> LinkBitcodeFiles; /// The user provided name for the "main file", if non-empty. This is useful /// in situations where the input file name does not match the original input @@ -169,7 +149,7 @@ public: std::string SplitDwarfFile; /// The name of the relocation model to use. - llvm::Reloc::Model RelocationModel; + std::string RelocationModel; /// The thread model to use std::string ThreadModel; @@ -178,12 +158,12 @@ public: /// function instead of to trap instructions. std::string TrapFuncName; + /// A list of command-line options to forward to the LLVM backend. + std::vector<std::string> BackendOptions; + /// A list of dependent libraries. std::vector<std::string> DependentLibraries; - /// A list of linker options to embed in the object file. - std::vector<std::string> LinkerOptions; - /// Name of the profile file to use as output for -fprofile-instr-generate /// and -fprofile-generate. std::string InstrProfileOutput; @@ -192,27 +172,19 @@ public: std::string SampleProfileFile; /// Name of the profile file to use as input for -fprofile-instr-use - std::string ProfileInstrumentUsePath; + std::string InstrProfileInput; /// Name of the function summary index file to use for ThinLTO function /// importing. std::string ThinLTOIndexFile; - /// Name of a file that can optionally be written with minimized bitcode - /// to be used as input for the ThinLTO thin link step, which only needs - /// the summary and module symbol table (and not, e.g. any debug metadata). - std::string ThinLinkBitcodeFile; - - /// Prefix to use for -save-temps output. - std::string SaveTempsFilePrefix; + /// The EABI version to use + std::string EABIVersion; - /// Name of file passed with -fcuda-include-gpubinary option to forward to - /// CUDA runtime back-end for incorporating them into host-side object file. - std::string CudaGpuBinaryFileName; - - /// The name of the file to which the backend should save YAML optimization - /// records. - std::string OptRecordFile; + /// A list of file names passed with -fcuda-include-gpubinary options to + /// forward to CUDA runtime back-end for incorporating them into host-side + /// object file. + std::vector<std::string> CudaGpuBinaryFileNames; /// Regular expression to select optimizations for which we should enable /// optimization remarks. Transformation passes whose name matches this @@ -236,7 +208,7 @@ public: /// flag. std::shared_ptr<llvm::Regex> OptimizationRemarkAnalysisPattern; - /// Set of files defining the rules for the symbol rewriting. + /// Set of files definining the rules for the symbol rewriting. std::vector<std::string> RewriteMapFiles; /// Set of sanitizer checks that are non-fatal (i.e. execution should be @@ -246,22 +218,9 @@ public: /// Set of sanitizer checks that trap rather than diagnose. SanitizerSet SanitizeTrap; - /// List of backend command-line options for -fembed-bitcode. - std::vector<uint8_t> CmdArgs; - - /// A list of all -fno-builtin-* function names (e.g., memset). + /// \brief A list of all -fno-builtin-* function names (e.g., memset). std::vector<std::string> NoBuiltinFuncs; - std::vector<std::string> Reciprocals; - - /// The preferred width for auto-vectorization transforms. This is intended to - /// override default transforms based on the width of the architected vector - /// registers. - std::string PreferVectorWidth; - - /// Set of XRay instrumentation kinds to emit. - XRayInstrSet XRayInstrumentationBundle; - public: // Define accessors/mutators for code generation options of enumeration type. #define CODEGENOPT(Name, Bits, Default) @@ -272,34 +231,13 @@ public: CodeGenOptions(); - /// Is this a libc/libm function that is no longer recognized as a + /// \brief Is this a libc/libm function that is no longer recognized as a /// builtin because a -fno-builtin-* option has been specified? bool isNoBuiltinFunc(const char *Name) const; const std::vector<std::string> &getNoBuiltinFuncs() const { return NoBuiltinFuncs; } - - /// Check if Clang profile instrumenation is on. - bool hasProfileClangInstr() const { - return getProfileInstr() == ProfileClangInstr; - } - - /// Check if IR level profile instrumentation is on. - bool hasProfileIRInstr() const { - return getProfileInstr() == ProfileIRInstr; - } - - /// Check if Clang profile use is on. - bool hasProfileClangUse() const { - return getProfileUse() == ProfileClangInstr; - } - - /// Check if IR level profile use is on. - bool hasProfileIRUse() const { - return getProfileUse() == ProfileIRInstr; - } - }; } // end namespace clang diff --git a/gnu/llvm/tools/clang/include/clang/Lex/PTHLexer.h b/gnu/llvm/tools/clang/include/clang/Lex/PTHLexer.h index 0b84df1434a..904be792b2a 100644 --- a/gnu/llvm/tools/clang/include/clang/Lex/PTHLexer.h +++ b/gnu/llvm/tools/clang/include/clang/Lex/PTHLexer.h @@ -1,4 +1,4 @@ -//===- PTHLexer.h - Lexer based on Pre-tokenized input ----------*- C++ -*-===// +//===--- PTHLexer.h - Lexer based on Pre-tokenized input --------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -14,15 +14,12 @@ #ifndef LLVM_CLANG_LEX_PTHLEXER_H #define LLVM_CLANG_LEX_PTHLEXER_H -#include "clang/Basic/SourceLocation.h" -#include "clang/Basic/TokenKinds.h" #include "clang/Lex/PreprocessorLexer.h" -#include "clang/Lex/Token.h" namespace clang { -class Preprocessor; class PTHManager; +class PTHSpellingSearch; class PTHLexer : public PreprocessorLexer { SourceLocation FileStartLoc; @@ -36,10 +33,10 @@ class PTHLexer : public PreprocessorLexer { /// LastHashTokPtr - Pointer into TokBuf of the last processed '#' /// token that appears at the start of a line. - const unsigned char* LastHashTokPtr = nullptr; + const unsigned char* LastHashTokPtr; /// PPCond - Pointer to a side table in the PTH file that provides a - /// a concise summary of the preprocessor conditional block structure. + /// a consise summary of the preproccessor conditional block structure. /// This is used to perform quick skipping of conditional blocks. const unsigned char* PPCond; @@ -47,9 +44,12 @@ class PTHLexer : public PreprocessorLexer { /// to process when doing quick skipping of preprocessor blocks. const unsigned char* CurPPCondPtr; - /// ReadToken - Used by PTHLexer to read tokens TokBuf. - void ReadToken(Token &T); + PTHLexer(const PTHLexer &) = delete; + void operator=(const PTHLexer &) = delete; + /// ReadToken - Used by PTHLexer to read tokens TokBuf. + void ReadToken(Token& T); + bool LexEndOfFile(Token &Result); /// PTHMgr - The PTHManager object that created this PTHLexer. @@ -61,13 +61,10 @@ protected: friend class PTHManager; /// Create a PTHLexer for the specified token stream. - PTHLexer(Preprocessor &pp, FileID FID, const unsigned char *D, + PTHLexer(Preprocessor& pp, FileID FID, const unsigned char *D, const unsigned char* ppcond, PTHManager &PM); - public: - PTHLexer(const PTHLexer &) = delete; - PTHLexer &operator=(const PTHLexer &) = delete; - ~PTHLexer() override = default; + ~PTHLexer() override {} /// Lex - Return the next token. bool Lex(Token &Tok); @@ -102,6 +99,6 @@ public: bool SkipBlock(); }; -} // namespace clang +} // end namespace clang -#endif // LLVM_CLANG_LEX_PTHLEXER_H +#endif diff --git a/gnu/llvm/tools/clang/include/clang/Lex/PTHManager.h b/gnu/llvm/tools/clang/include/clang/Lex/PTHManager.h index 483b69f23a9..26178eddf36 100644 --- a/gnu/llvm/tools/clang/include/clang/Lex/PTHManager.h +++ b/gnu/llvm/tools/clang/include/clang/Lex/PTHManager.h @@ -1,4 +1,4 @@ -//===- PTHManager.h - Manager object for PTH processing ---------*- C++ -*-===// +//===--- PTHManager.h - Manager object for PTH processing -------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -14,36 +14,36 @@ #ifndef LLVM_CLANG_LEX_PTHMANAGER_H #define LLVM_CLANG_LEX_PTHMANAGER_H +#include "clang/Basic/Diagnostic.h" #include "clang/Basic/IdentifierTable.h" -#include "clang/Basic/SourceLocation.h" +#include "clang/Basic/LangOptions.h" +#include "clang/Lex/PTHLexer.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/StringRef.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/OnDiskHashTable.h" -#include <memory> +#include <string> namespace llvm { - -class MemoryBuffer; - -} // namespace llvm + class MemoryBuffer; +} namespace clang { +class FileEntry; +class PTHLexer; class DiagnosticsEngine; class FileSystemStatCache; -class Preprocessor; -class PTHLexer; class PTHManager : public IdentifierInfoLookup { friend class PTHLexer; + friend class PTHStatCache; - class PTHFileLookupTrait; class PTHStringLookupTrait; - - using PTHStringIdLookup = llvm::OnDiskChainedHashTable<PTHStringLookupTrait>; - using PTHFileLookup = llvm::OnDiskChainedHashTable<PTHFileLookupTrait>; + class PTHFileLookupTrait; + typedef llvm::OnDiskChainedHashTable<PTHStringLookupTrait> PTHStringIdLookup; + typedef llvm::OnDiskChainedHashTable<PTHFileLookupTrait> PTHFileLookup; /// The memory mapped PTH file. std::unique_ptr<const llvm::MemoryBuffer> Buf; @@ -73,7 +73,7 @@ class PTHManager : public IdentifierInfoLookup { /// PP - The Preprocessor object that will use this PTHManager to create /// PTHLexer objects. - Preprocessor* PP = nullptr; + Preprocessor* PP; /// SpellingBase - The base offset within the PTH memory buffer that /// contains the cached spellings for literals. @@ -92,13 +92,16 @@ class PTHManager : public IdentifierInfoLookup { std::unique_ptr<PTHStringIdLookup> stringIdLookup, unsigned numIds, const unsigned char *spellingBase, const char *originalSourceFile); + PTHManager(const PTHManager &) = delete; + void operator=(const PTHManager &) = delete; + /// getSpellingAtPTHOffset - Used by PTHLexer classes to get the cached /// spelling for a token. unsigned getSpellingAtPTHOffset(unsigned PTHOffset, const char*& Buffer); /// GetIdentifierInfo - Used to reconstruct IdentifierInfo objects from the /// PTH file. - IdentifierInfo *GetIdentifierInfo(unsigned PersistentID) { + inline IdentifierInfo* GetIdentifierInfo(unsigned PersistentID) { // Check if the IdentifierInfo has already been resolved. if (IdentifierInfo* II = PerIDCache[PersistentID]) return II; @@ -110,8 +113,6 @@ public: // The current PTH version. enum { Version = 10 }; - PTHManager(const PTHManager &) = delete; - PTHManager &operator=(const PTHManager &) = delete; ~PTHManager() override; /// getOriginalSourceFile - Return the full path to the original header @@ -122,18 +123,18 @@ public: /// get - Return the identifier token info for the specified named identifier. /// Unlike the version in IdentifierTable, this returns a pointer instead - /// of a reference. If the pointer is nullptr then the IdentifierInfo cannot + /// of a reference. If the pointer is NULL then the IdentifierInfo cannot /// be found. IdentifierInfo *get(StringRef Name) override; /// Create - This method creates PTHManager objects. The 'file' argument - /// is the name of the PTH file. This method returns nullptr upon failure. + /// is the name of the PTH file. This method returns NULL upon failure. static PTHManager *Create(StringRef file, DiagnosticsEngine &Diags); void setPreprocessor(Preprocessor *pp) { PP = pp; } /// CreateLexer - Return a PTHLexer that "lexes" the cached tokens for the - /// specified file. This method returns nullptr if no cached tokens exist. + /// specified file. This method returns NULL if no cached tokens exist. /// It is the responsibility of the caller to 'delete' the returned object. PTHLexer *CreateLexer(FileID FID); @@ -144,6 +145,6 @@ public: std::unique_ptr<FileSystemStatCache> createStatCache(); }; -} // namespace clang +} // end namespace clang -#endif // LLVM_CLANG_LEX_PTHMANAGER_H +#endif diff --git a/gnu/llvm/tools/clang/include/clang/Sema/LoopHint.h b/gnu/llvm/tools/clang/include/clang/Sema/LoopHint.h index 171435e69bc..c8b2ee845e5 100644 --- a/gnu/llvm/tools/clang/include/clang/Sema/LoopHint.h +++ b/gnu/llvm/tools/clang/include/clang/Sema/LoopHint.h @@ -12,12 +12,12 @@ #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/SourceLocation.h" +#include "clang/Sema/AttributeList.h" #include "clang/Sema/Ownership.h" -#include "clang/Sema/ParsedAttr.h" namespace clang { -/// Loop optimization hint for loop and unroll pragmas. +/// \brief Loop optimization hint for loop and unroll pragmas. struct LoopHint { // Source range of the directive. SourceRange Range; diff --git a/gnu/llvm/tools/clang/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h b/gnu/llvm/tools/clang/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h index f5a06394b18..5850656916e 100644 --- a/gnu/llvm/tools/clang/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h +++ b/gnu/llvm/tools/clang/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h @@ -120,6 +120,9 @@ public: NoRet, /// Indicates that the returned value is an owned (+1) symbol. OwnedSymbol, + /// Indicates that the returned value is an owned (+1) symbol and + /// that it should be treated as freshly allocated. + OwnedAllocatedSymbol, /// Indicates that the returned value is an object with retain count /// semantics but that it is not owned (+0). This is the default /// for getters, etc. @@ -136,7 +139,7 @@ public: // by inlining the function NoRetHard }; - + /// Determines the object kind of a tracked object. enum ObjKind { /// Indicates that the tracked object is a CF object. This is @@ -145,40 +148,39 @@ public: /// Indicates that the tracked object is an Objective-C object. ObjC, /// Indicates that the tracked object could be a CF or Objective-C object. - AnyObj, - /// Indicates that the tracked object is a generalized object. - Generalized + AnyObj }; - + private: Kind K; ObjKind O; - + RetEffect(Kind k, ObjKind o = AnyObj) : K(k), O(o) {} - + public: Kind getKind() const { return K; } - + ObjKind getObjKind() const { return O; } - + bool isOwned() const { - return K == OwnedSymbol || K == OwnedWhenTrackedReceiver; + return K == OwnedSymbol || K == OwnedAllocatedSymbol || + K == OwnedWhenTrackedReceiver; } - + bool notOwned() const { return K == NotOwnedSymbol; } - + bool operator==(const RetEffect &Other) const { return K == Other.K && O == Other.O; } - + static RetEffect MakeOwnedWhenTrackedReceiver() { return RetEffect(OwnedWhenTrackedReceiver, ObjC); } - - static RetEffect MakeOwned(ObjKind o) { - return RetEffect(OwnedSymbol, o); + + static RetEffect MakeOwned(ObjKind o, bool isAllocated = false) { + return RetEffect(isAllocated ? OwnedAllocatedSymbol : OwnedSymbol, o); } static RetEffect MakeNotOwned(ObjKind o) { return RetEffect(NotOwnedSymbol, o); diff --git a/gnu/llvm/tools/clang/include/clang/StaticAnalyzer/Core/CheckerOptInfo.h b/gnu/llvm/tools/clang/include/clang/StaticAnalyzer/Core/CheckerOptInfo.h index 2d13bf34cd1..e981871ae4e 100644 --- a/gnu/llvm/tools/clang/include/clang/StaticAnalyzer/Core/CheckerOptInfo.h +++ b/gnu/llvm/tools/clang/include/clang/StaticAnalyzer/Core/CheckerOptInfo.h @@ -28,7 +28,7 @@ class CheckerOptInfo { public: CheckerOptInfo(StringRef name, bool enable) : Name(name), Enable(enable), Claimed(false) { } - + StringRef getName() const { return Name; } bool isEnabled() const { return Enable; } bool isDisabled() const { return !isEnabled(); } diff --git a/gnu/llvm/tools/clang/include/clang/StaticAnalyzer/Core/CheckerRegistry.h b/gnu/llvm/tools/clang/include/clang/StaticAnalyzer/Core/CheckerRegistry.h index d580dda7348..c9724c08da2 100644 --- a/gnu/llvm/tools/clang/include/clang/StaticAnalyzer/Core/CheckerRegistry.h +++ b/gnu/llvm/tools/clang/include/clang/StaticAnalyzer/Core/CheckerRegistry.h @@ -1,4 +1,4 @@ -//===- CheckerRegistry.h - Maintains all available checkers -----*- C++ -*-===// +//===--- CheckerRegistry.h - Maintains all available checkers ---*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -12,9 +12,6 @@ #include "clang/Basic/LLVM.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" -#include "llvm/ADT/StringMap.h" -#include "llvm/ADT/StringRef.h" -#include <cstddef> #include <vector> // FIXME: move this information to an HTML file in docs/. @@ -47,7 +44,7 @@ // The clang_registerCheckers function may add any number of checkers to the // registry. If any checkers require additional initialization, use the three- // argument form of CheckerRegistry::addChecker. -// +// // To load a checker plugin, specify the full path to the dynamic library as // the argument to the -load option in the cc1 frontend. You can then enable // your custom checker using the -analyzer-checker: @@ -67,9 +64,8 @@ #endif namespace clang { - -class AnalyzerOptions; class DiagnosticsEngine; +class AnalyzerOptions; namespace ento { @@ -85,18 +81,17 @@ class CheckerRegistry { public: /// Initialization functions perform any necessary setup for a checker. /// They should include a call to CheckerManager::registerChecker. - using InitializationFunction = void (*)(CheckerManager &); - + typedef void (*InitializationFunction)(CheckerManager &); struct CheckerInfo { InitializationFunction Initialize; StringRef FullName; StringRef Desc; CheckerInfo(InitializationFunction fn, StringRef name, StringRef desc) - : Initialize(fn), FullName(name), Desc(desc) {} + : Initialize(fn), FullName(name), Desc(desc) {} }; - using CheckerInfoList = std::vector<CheckerInfo>; + typedef std::vector<CheckerInfo> CheckerInfoList; private: template <typename T> @@ -132,17 +127,14 @@ public: /// Prints the name and description of all checkers in this registry. /// This output is not intended to be machine-parseable. - void printHelp(raw_ostream &out, size_t maxNameChars = 30) const; - void printList(raw_ostream &out, - SmallVectorImpl<CheckerOptInfo> &opts) const; + void printHelp(raw_ostream &out, size_t maxNameChars = 30) const ; private: mutable CheckerInfoList Checkers; mutable llvm::StringMap<size_t> Packages; }; -} // namespace ento - -} // namespace clang +} // end namespace ento +} // end namespace clang -#endif // LLVM_CLANG_STATICANALYZER_CORE_CHECKERREGISTRY_H +#endif diff --git a/gnu/llvm/tools/clang/lib/Analysis/FormatStringParsing.h b/gnu/llvm/tools/clang/lib/Analysis/FormatStringParsing.h index a63140b366c..e1652964b8c 100644 --- a/gnu/llvm/tools/clang/lib/Analysis/FormatStringParsing.h +++ b/gnu/llvm/tools/clang/lib/Analysis/FormatStringParsing.h @@ -4,6 +4,7 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/Type.h" #include "clang/Analysis/Analyses/FormatString.h" +#include "llvm/Support/raw_ostream.h" namespace clang { @@ -23,7 +24,7 @@ public: }; namespace analyze_format_string { - + OptionalAmount ParseAmount(const char *&Beg, const char *E); OptionalAmount ParseNonPositionAmount(const char *&Beg, const char *E, unsigned &argIndex); @@ -31,12 +32,12 @@ OptionalAmount ParseNonPositionAmount(const char *&Beg, const char *E, OptionalAmount ParsePositionAmount(FormatStringHandler &H, const char *Start, const char *&Beg, const char *E, PositionContext p); - + bool ParseFieldWidth(FormatStringHandler &H, FormatSpecifier &CS, const char *Start, const char *&Beg, const char *E, unsigned *argIndex); - + bool ParseArgPosition(FormatStringHandler &H, FormatSpecifier &CS, const char *Start, const char *&Beg, const char *E); @@ -45,13 +46,7 @@ bool ParseArgPosition(FormatStringHandler &H, /// FormatSpecifier& argument, and false otherwise. bool ParseLengthModifier(FormatSpecifier &FS, const char *&Beg, const char *E, const LangOptions &LO, bool IsScanf = false); - -/// Returns true if the invalid specifier in \p SpecifierBegin is a UTF-8 -/// string; check that it won't go further than \p FmtStrEnd and write -/// up the total size in \p Len. -bool ParseUTF8InvalidSpecifier(const char *SpecifierBegin, - const char *FmtStrEnd, unsigned &Len); - + template <typename T> class SpecifierResult { T FS; const char *Start; @@ -62,7 +57,7 @@ public: SpecifierResult(const char *start, const T &fs) : FS(fs), Start(start), Stop(false) {} - + const char *getStart() const { return Start; } bool shouldStop() const { return Stop; } bool hasValue() const { return Start != nullptr; } @@ -72,7 +67,7 @@ public: } const T &getValue() { return FS; } }; - + } // end analyze_format_string namespace } // end clang namespace diff --git a/gnu/llvm/tools/clang/lib/Analysis/PrintfFormatString.cpp b/gnu/llvm/tools/clang/lib/Analysis/PrintfFormatString.cpp index dcb15c5e375..f0976bce972 100644 --- a/gnu/llvm/tools/clang/lib/Analysis/PrintfFormatString.cpp +++ b/gnu/llvm/tools/clang/lib/Analysis/PrintfFormatString.cpp @@ -13,7 +13,6 @@ //===----------------------------------------------------------------------===// #include "clang/Analysis/Analyses/FormatString.h" -#include "clang/Analysis/Analyses/OSLog.h" #include "FormatStringParsing.h" #include "clang/Basic/TargetInfo.h" @@ -120,59 +119,6 @@ static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H, return true; } - if (*I == '{') { - ++I; - unsigned char PrivacyFlags = 0; - StringRef MatchedStr; - - do { - StringRef Str(I, E - I); - std::string Match = "^[\t\n\v\f\r ]*(private|public)[\t\n\v\f\r ]*(,|})"; - llvm::Regex R(Match); - SmallVector<StringRef, 2> Matches; - - if (R.match(Str, &Matches)) { - MatchedStr = Matches[1]; - I += Matches[0].size(); - - // Set the privacy flag if the privacy annotation in the - // comma-delimited segment is at least as strict as the privacy - // annotations in previous comma-delimited segments. - if (MatchedStr.equals("private")) - PrivacyFlags = clang::analyze_os_log::OSLogBufferItem::IsPrivate; - else if (PrivacyFlags == 0 && MatchedStr.equals("public")) - PrivacyFlags = clang::analyze_os_log::OSLogBufferItem::IsPublic; - } else { - size_t CommaOrBracePos = - Str.find_if([](char c) { return c == ',' || c == '}'; }); - - if (CommaOrBracePos == StringRef::npos) { - // Neither a comma nor the closing brace was found. - if (Warn) - H.HandleIncompleteSpecifier(Start, E - Start); - return true; - } - - I += CommaOrBracePos + 1; - } - // Continue until the closing brace is found. - } while (*(I - 1) == ','); - - // Set the privacy flag. - switch (PrivacyFlags) { - case 0: - break; - case clang::analyze_os_log::OSLogBufferItem::IsPrivate: - FS.setIsPrivate(MatchedStr.data()); - break; - case clang::analyze_os_log::OSLogBufferItem::IsPublic: - FS.setIsPublic(MatchedStr.data()); - break; - default: - llvm_unreachable("Unexpected privacy flag value"); - } - } - // Look for flags (if any). bool hasMore = true; for ( ; I != E; ++I) { @@ -307,10 +253,6 @@ static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H, // POSIX specific. case 'C': k = ConversionSpecifier::CArg; break; case 'S': k = ConversionSpecifier::SArg; break; - // Apple extension for os_log - case 'P': - k = ConversionSpecifier::PArg; - break; // Objective-C. case '@': k = ConversionSpecifier::ObjCObjArg; break; // Glibc specific. @@ -348,7 +290,7 @@ static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H, if (Target.getTriple().isOSMSVCRT()) k = ConversionSpecifier::ZArg; } - + // Check to see if we used the Objective-C modifier flags with // a conversion specifier other than '@'. if (k != ConversionSpecifier::ObjCObjArg && @@ -359,7 +301,7 @@ static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H, conversionPosition); return true; } - + PrintfConversionSpecifier CS(conversionPosition, k); FS.setConversionSpecifier(CS); if (CS.consumesDataArgument() && !FS.usesPositionalArg()) @@ -370,13 +312,8 @@ static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H, argIndex++; if (k == ConversionSpecifier::InvalidSpecifier) { - unsigned Len = I - Start; - if (ParseUTF8InvalidSpecifier(Start, E, Len)) { - CS.setEndScanList(Start + Len); - FS.setConversionSpecifier(CS); - } // Assume the conversion takes one argument. - return !H.HandleInvalidPrintfConversionSpecifier(FS, Start, Len); + return !H.HandleInvalidPrintfConversionSpecifier(FS, Start, I - Start); } return PrintfSpecifierResult(Start, FS); } @@ -416,9 +353,9 @@ bool clang::analyze_format_string::ParseFormatStringHasSArg(const char *I, const char *E, const LangOptions &LO, const TargetInfo &Target) { - + unsigned argIndex = 0; - + // Keep looking for a %s format specifier until we have exhausted the string. FormatStringHandler H; while (I != E) { @@ -462,7 +399,6 @@ ArgType PrintfSpecifier::getArgType(ASTContext &Ctx, case LengthModifier::AsShort: if (Ctx.getTargetInfo().getTriple().isOSMSVCRT()) return Ctx.IntTy; - LLVM_FALLTHROUGH; default: return ArgType::Invalid(); } @@ -487,14 +423,14 @@ ArgType PrintfSpecifier::getArgType(ASTContext &Ctx, case LengthModifier::AsIntMax: return ArgType(Ctx.getIntMaxType(), "intmax_t"); case LengthModifier::AsSizeT: - return ArgType::makeSizeT(ArgType(Ctx.getSignedSizeType(), "ssize_t")); + // FIXME: How to get the corresponding signed version of size_t? + return ArgType(); case LengthModifier::AsInt3264: return Ctx.getTargetInfo().getTriple().isArch64Bit() ? ArgType(Ctx.LongLongTy, "__int64") : ArgType(Ctx.IntTy, "__int32"); case LengthModifier::AsPtrDiff: - return ArgType::makePtrdiffT( - ArgType(Ctx.getPointerDiffType(), "ptrdiff_t")); + return ArgType(Ctx.getPointerDiffType(), "ptrdiff_t"); case LengthModifier::AsAllocate: case LengthModifier::AsMAllocate: case LengthModifier::AsWide: @@ -521,14 +457,15 @@ ArgType PrintfSpecifier::getArgType(ASTContext &Ctx, case LengthModifier::AsIntMax: return ArgType(Ctx.getUIntMaxType(), "uintmax_t"); case LengthModifier::AsSizeT: - return ArgType::makeSizeT(ArgType(Ctx.getSizeType(), "size_t")); + return ArgType(Ctx.getSizeType(), "size_t"); case LengthModifier::AsInt3264: return Ctx.getTargetInfo().getTriple().isArch64Bit() ? ArgType(Ctx.UnsignedLongLongTy, "unsigned __int64") : ArgType(Ctx.UnsignedIntTy, "unsigned __int32"); case LengthModifier::AsPtrDiff: - return ArgType::makePtrdiffT( - ArgType(Ctx.getUnsignedPointerDiffType(), "unsigned ptrdiff_t")); + // FIXME: How to get the corresponding unsigned + // version of ptrdiff_t? + return ArgType(); case LengthModifier::AsAllocate: case LengthModifier::AsMAllocate: case LengthModifier::AsWide: @@ -557,7 +494,7 @@ ArgType PrintfSpecifier::getArgType(ASTContext &Ctx, case LengthModifier::AsIntMax: return ArgType::PtrTo(ArgType(Ctx.getIntMaxType(), "intmax_t")); case LengthModifier::AsSizeT: - return ArgType::PtrTo(ArgType(Ctx.getSignedSizeType(), "ssize_t")); + return ArgType(); // FIXME: ssize_t case LengthModifier::AsPtrDiff: return ArgType::PtrTo(ArgType(Ctx.getPointerDiffType(), "ptrdiff_t")); case LengthModifier::AsLongDouble: @@ -599,7 +536,6 @@ ArgType PrintfSpecifier::getArgType(ASTContext &Ctx, return Ctx.IntTy; return ArgType(Ctx.WideCharTy, "wchar_t"); case ConversionSpecifier::pArg: - case ConversionSpecifier::PArg: return ArgType::CPointerTy; case ConversionSpecifier::ObjCObjArg: return ArgType::ObjCPointerTy; @@ -670,44 +606,14 @@ bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt, case BuiltinType::Bool: case BuiltinType::WChar_U: case BuiltinType::WChar_S: - case BuiltinType::Char8: // FIXME: Treat like 'char'? case BuiltinType::Char16: case BuiltinType::Char32: case BuiltinType::UInt128: case BuiltinType::Int128: case BuiltinType::Half: - case BuiltinType::Float16: - case BuiltinType::Float128: - case BuiltinType::ShortAccum: - case BuiltinType::Accum: - case BuiltinType::LongAccum: - case BuiltinType::UShortAccum: - case BuiltinType::UAccum: - case BuiltinType::ULongAccum: - case BuiltinType::ShortFract: - case BuiltinType::Fract: - case BuiltinType::LongFract: - case BuiltinType::UShortFract: - case BuiltinType::UFract: - case BuiltinType::ULongFract: - case BuiltinType::SatShortAccum: - case BuiltinType::SatAccum: - case BuiltinType::SatLongAccum: - case BuiltinType::SatUShortAccum: - case BuiltinType::SatUAccum: - case BuiltinType::SatULongAccum: - case BuiltinType::SatShortFract: - case BuiltinType::SatFract: - case BuiltinType::SatLongFract: - case BuiltinType::SatUShortFract: - case BuiltinType::SatUFract: - case BuiltinType::SatULongFract: // Various types which are non-trivial to correct. return false; -#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ - case BuiltinType::Id: -#include "clang/Basic/OpenCLImageTypes.def" #define SIGNED_TYPE(Id, SingletonId) #define UNSIGNED_TYPE(Id, SingletonId) #define FLOATING_TYPE(Id, SingletonId) @@ -985,7 +891,7 @@ bool PrintfSpecifier::hasValidPrecision() const { if (Precision.getHowSpecified() == OptionalAmount::NotSpecified) return true; - // Precision is only valid with the diouxXaAeEfFgGsP conversions + // Precision is only valid with the diouxXaAeEfFgGs conversions switch (CS.getKind()) { case ConversionSpecifier::dArg: case ConversionSpecifier::DArg: @@ -1007,7 +913,6 @@ bool PrintfSpecifier::hasValidPrecision() const { case ConversionSpecifier::sArg: case ConversionSpecifier::FreeBSDrArg: case ConversionSpecifier::FreeBSDyArg: - case ConversionSpecifier::PArg: return true; default: diff --git a/gnu/llvm/tools/clang/lib/Analysis/PseudoConstantAnalysis.cpp b/gnu/llvm/tools/clang/lib/Analysis/PseudoConstantAnalysis.cpp index 83b545a7be8..5b917a7a27f 100644 --- a/gnu/llvm/tools/clang/lib/Analysis/PseudoConstantAnalysis.cpp +++ b/gnu/llvm/tools/clang/lib/Analysis/PseudoConstantAnalysis.cpp @@ -22,7 +22,9 @@ using namespace clang; -typedef llvm::SmallPtrSet<const VarDecl*, 32> VarDeclSet; +// The number of ValueDecls we want to keep track of by default (per-function) +#define VARDECL_SET_SIZE 256 +typedef llvm::SmallPtrSet<const VarDecl*, VARDECL_SET_SIZE> VarDeclSet; PseudoConstantAnalysis::PseudoConstantAnalysis(const Stmt *DeclBody) : DeclBody(DeclBody), Analyzed(false) { @@ -109,7 +111,6 @@ void PseudoConstantAnalysis::RunAnalysis() { // Do not visit the children continue; - LLVM_FALLTHROUGH; } case BO_AddAssign: case BO_SubAssign: diff --git a/gnu/llvm/tools/clang/lib/Analysis/ScanfFormatString.cpp b/gnu/llvm/tools/clang/lib/Analysis/ScanfFormatString.cpp index a9af0cdfdac..d484d8e828c 100644 --- a/gnu/llvm/tools/clang/lib/Analysis/ScanfFormatString.cpp +++ b/gnu/llvm/tools/clang/lib/Analysis/ScanfFormatString.cpp @@ -41,7 +41,7 @@ static bool ParseScanList(FormatStringHandler &H, H.HandleIncompleteScanList(start, I); return true; } - + // Special case: ']' is the first character. if (*I == ']') { if (++I == E) { @@ -65,7 +65,7 @@ static bool ParseScanList(FormatStringHandler &H, H.HandleIncompleteScanList(start, I - 1); return true; } - } + } CS.setEndScanList(I); return false; @@ -79,7 +79,7 @@ static ScanfSpecifierResult ParseScanfSpecifier(FormatStringHandler &H, unsigned &argIndex, const LangOptions &LO, const TargetInfo &Target) { - using namespace clang::analyze_format_string; + using namespace clang::analyze_scanf; const char *I = Beg; const char *Start = nullptr; @@ -98,17 +98,17 @@ static ScanfSpecifierResult ParseScanfSpecifier(FormatStringHandler &H, break; } } - + // No format specifier found? if (!Start) return false; - + if (I == E) { // No more characters left? H.HandleIncompleteSpecifier(Start, E - Start); return true; } - + ScanfSpecifier FS; if (ParseArgPosition(H, FS, Start, I, E)) return true; @@ -118,7 +118,7 @@ static ScanfSpecifierResult ParseScanfSpecifier(FormatStringHandler &H, H.HandleIncompleteSpecifier(Start, E - Start); return true; } - + // Look for '*' flag if it is present. if (*I == '*') { FS.setSuppressAssignment(I); @@ -127,7 +127,7 @@ static ScanfSpecifierResult ParseScanfSpecifier(FormatStringHandler &H, return true; } } - + // Look for the field width (if any). Unlike printf, this is either // a fixed integer or isn't present. const OptionalAmount &Amt = clang::analyze_format_string::ParseAmount(I, E); @@ -141,20 +141,20 @@ static ScanfSpecifierResult ParseScanfSpecifier(FormatStringHandler &H, return true; } } - + // Look for the length modifier. if (ParseLengthModifier(FS, I, E, LO, /*scanf=*/true) && I == E) { // No more characters left? H.HandleIncompleteSpecifier(Start, E - Start); return true; } - + // Detect spurious null characters, which are likely errors. if (*I == '\0') { H.HandleNullChar(I); return true; } - + // Finally, look for the conversion specifier. const char *conversionPosition = I++; ScanfConversionSpecifier::Kind k = ScanfConversionSpecifier::InvalidSpecifier; @@ -207,18 +207,13 @@ static ScanfSpecifierResult ParseScanfSpecifier(FormatStringHandler &H, if (CS.consumesDataArgument() && !FS.getSuppressAssignment() && !FS.usesPositionalArg()) FS.setArgIndex(argIndex++); - + // FIXME: '%' and '*' doesn't make sense. Issue a warning. // FIXME: 'ConsumedSoFar' and '*' doesn't make sense. - + if (k == ScanfConversionSpecifier::InvalidSpecifier) { - unsigned Len = I - Beg; - if (ParseUTF8InvalidSpecifier(Beg, E, Len)) { - CS.setEndScanList(Beg + Len); - FS.setConversionSpecifier(CS); - } // Assume the conversion takes one argument. - return !H.HandleInvalidScanfConversionSpecifier(FS, Beg, Len); + return !H.HandleInvalidScanfConversionSpecifier(FS, Beg, I - Beg); } return ScanfSpecifierResult(Start, FS); } @@ -251,7 +246,8 @@ ArgType ScanfSpecifier::getArgType(ASTContext &Ctx) const { case LengthModifier::AsIntMax: return ArgType::PtrTo(ArgType(Ctx.getIntMaxType(), "intmax_t")); case LengthModifier::AsSizeT: - return ArgType::PtrTo(ArgType(Ctx.getSignedSizeType(), "ssize_t")); + // FIXME: ssize_t. + return ArgType(); case LengthModifier::AsPtrDiff: return ArgType::PtrTo(ArgType(Ctx.getPointerDiffType(), "ptrdiff_t")); case LengthModifier::AsLongDouble: @@ -291,8 +287,8 @@ ArgType ScanfSpecifier::getArgType(ASTContext &Ctx) const { case LengthModifier::AsSizeT: return ArgType::PtrTo(ArgType(Ctx.getSizeType(), "size_t")); case LengthModifier::AsPtrDiff: - return ArgType::PtrTo( - ArgType(Ctx.getUnsignedPointerDiffType(), "unsigned ptrdiff_t")); + // FIXME: Unsigned version of ptrdiff_t? + return ArgType(); case LengthModifier::AsLongDouble: // GNU extension. return ArgType::PtrTo(Ctx.UnsignedLongLongTy); @@ -340,7 +336,6 @@ ArgType ScanfSpecifier::getArgType(ASTContext &Ctx) const { case LengthModifier::AsShort: if (Ctx.getTargetInfo().getTriple().isOSMSVCRT()) return ArgType::PtrTo(ArgType::AnyCharTy); - LLVM_FALLTHROUGH; default: return ArgType::Invalid(); } @@ -357,7 +352,6 @@ ArgType ScanfSpecifier::getArgType(ASTContext &Ctx) const { case LengthModifier::AsShort: if (Ctx.getTargetInfo().getTriple().isOSMSVCRT()) return ArgType::PtrTo(ArgType::AnyCharTy); - LLVM_FALLTHROUGH; default: return ArgType::Invalid(); } @@ -385,7 +379,7 @@ ArgType ScanfSpecifier::getArgType(ASTContext &Ctx) const { case LengthModifier::AsIntMax: return ArgType::PtrTo(ArgType(Ctx.getIntMaxType(), "intmax_t")); case LengthModifier::AsSizeT: - return ArgType::PtrTo(ArgType(Ctx.getSignedSizeType(), "ssize_t")); + return ArgType(); // FIXME: ssize_t case LengthModifier::AsPtrDiff: return ArgType::PtrTo(ArgType(Ctx.getPointerDiffType(), "ptrdiff_t")); case LengthModifier::AsLongDouble: @@ -419,12 +413,8 @@ bool ScanfSpecifier::fixType(QualType QT, QualType RawQT, QualType PT = QT->getPointeeType(); // If it's an enum, get its underlying type. - if (const EnumType *ETy = PT->getAs<EnumType>()) { - // Don't try to fix incomplete enums. - if (!ETy->getDecl()->isComplete()) - return false; + if (const EnumType *ETy = PT->getAs<EnumType>()) PT = ETy->getDecl()->getIntegerType(); - } const BuiltinType *BT = PT->getAs<BuiltinType>(); if (!BT) @@ -537,9 +527,9 @@ bool clang::analyze_format_string::ParseScanfString(FormatStringHandler &H, const char *E, const LangOptions &LO, const TargetInfo &Target) { - + unsigned argIndex = 0; - + // Keep looking for a format specifier until we have exhausted the string. while (I != E) { const ScanfSpecifierResult &FSR = ParseScanfSpecifier(H, I, E, argIndex, diff --git a/gnu/llvm/tools/clang/lib/Basic/VirtualFileSystem.cpp b/gnu/llvm/tools/clang/lib/Basic/VirtualFileSystem.cpp index bcfcbdbb901..6977f400287 100644 --- a/gnu/llvm/tools/clang/lib/Basic/VirtualFileSystem.cpp +++ b/gnu/llvm/tools/clang/lib/Basic/VirtualFileSystem.cpp @@ -1,4 +1,4 @@ -//===- VirtualFileSystem.cpp - Virtual File System Layer ------------------===// +//===- VirtualFileSystem.cpp - Virtual File System Layer --------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -6,57 +6,34 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -// // This file implements the VirtualFileSystem interface. -// //===----------------------------------------------------------------------===// #include "clang/Basic/VirtualFileSystem.h" -#include "clang/Basic/LLVM.h" -#include "llvm/ADT/ArrayRef.h" +#include "clang/Basic/FileManager.h" #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/IntrusiveRefCntPtr.h" -#include "llvm/ADT/Optional.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSet.h" -#include "llvm/ADT/Twine.h" #include "llvm/ADT/iterator_range.h" -#include "llvm/Config/llvm-config.h" -#include "llvm/Support/Compiler.h" -#include "llvm/Support/Casting.h" -#include "llvm/Support/Chrono.h" -#include "llvm/Support/Debug.h" #include "llvm/Support/Errc.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/ErrorOr.h" -#include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" -#include "llvm/Support/Process.h" -#include "llvm/Support/SMLoc.h" -#include "llvm/Support/SourceMgr.h" #include "llvm/Support/YAMLParser.h" -#include "llvm/Support/raw_ostream.h" -#include <algorithm> +#include "llvm/Config/llvm-config.h" #include <atomic> -#include <cassert> -#include <cstdint> -#include <iterator> -#include <limits> -#include <map> #include <memory> -#include <string> -#include <system_error> -#include <utility> -#include <vector> + +// For chdir. +#ifdef LLVM_ON_WIN32 +# include <direct.h> +#else +# include <unistd.h> +#endif using namespace clang; -using namespace vfs; +using namespace clang::vfs; using namespace llvm; - using llvm::sys::fs::file_status; using llvm::sys::fs::file_type; using llvm::sys::fs::perms; @@ -65,13 +42,13 @@ using llvm::sys::fs::UniqueID; Status::Status(const file_status &Status) : UID(Status.getUniqueID()), MTime(Status.getLastModificationTime()), User(Status.getUser()), Group(Status.getGroup()), Size(Status.getSize()), - Type(Status.type()), Perms(Status.permissions()) {} + Type(Status.type()), Perms(Status.permissions()), IsVFSMapped(false) {} -Status::Status(StringRef Name, UniqueID UID, sys::TimePoint<> MTime, +Status::Status(StringRef Name, UniqueID UID, sys::TimeValue MTime, uint32_t User, uint32_t Group, uint64_t Size, file_type Type, perms Perms) : Name(Name), UID(UID), MTime(MTime), User(User), Group(Group), Size(Size), - Type(Type), Perms(Perms) {} + Type(Type), Perms(Perms), IsVFSMapped(false) {} Status Status::copyWithNewName(const Status &In, StringRef NewName) { return Status(NewName, In.getUniqueID(), In.getLastModificationTime(), @@ -86,37 +63,30 @@ Status Status::copyWithNewName(const file_status &In, StringRef NewName) { } bool Status::equivalent(const Status &Other) const { - assert(isStatusKnown() && Other.isStatusKnown()); return getUniqueID() == Other.getUniqueID(); } - bool Status::isDirectory() const { return Type == file_type::directory_file; } - bool Status::isRegularFile() const { return Type == file_type::regular_file; } - bool Status::isOther() const { return exists() && !isRegularFile() && !isDirectory() && !isSymlink(); } - bool Status::isSymlink() const { return Type == file_type::symlink_file; } - bool Status::isStatusKnown() const { return Type != file_type::status_error; } - bool Status::exists() const { return isStatusKnown() && Type != file_type::file_not_found; } -File::~File() = default; +File::~File() {} -FileSystem::~FileSystem() = default; +FileSystem::~FileSystem() {} ErrorOr<std::unique_ptr<MemoryBuffer>> FileSystem::getBufferForFile(const llvm::Twine &Name, int64_t FileSize, @@ -129,9 +99,6 @@ FileSystem::getBufferForFile(const llvm::Twine &Name, int64_t FileSize, } std::error_code FileSystem::makeAbsolute(SmallVectorImpl<char> &Path) const { - if (llvm::sys::path::is_absolute(Path)) - return {}; - auto WorkingDir = getCurrentWorkingDirectory(); if (!WorkingDir) return WorkingDir.getError(); @@ -139,66 +106,37 @@ std::error_code FileSystem::makeAbsolute(SmallVectorImpl<char> &Path) const { return llvm::sys::fs::make_absolute(WorkingDir.get(), Path); } -std::error_code FileSystem::getRealPath(const Twine &Path, - SmallVectorImpl<char> &Output) const { - return errc::operation_not_permitted; -} - bool FileSystem::exists(const Twine &Path) { auto Status = status(Path); return Status && Status->exists(); } -#ifndef NDEBUG -static bool isTraversalComponent(StringRef Component) { - return Component.equals("..") || Component.equals("."); -} - -static bool pathHasTraversal(StringRef Path) { - using namespace llvm::sys; - - for (StringRef Comp : llvm::make_range(path::begin(Path), path::end(Path))) - if (isTraversalComponent(Comp)) - return true; - return false; -} -#endif - //===-----------------------------------------------------------------------===/ // RealFileSystem implementation //===-----------------------------------------------------------------------===/ namespace { - -/// Wrapper around a raw file descriptor. +/// \brief Wrapper around a raw file descriptor. class RealFile : public File { - friend class RealFileSystem; - int FD; Status S; - std::string RealName; - - RealFile(int FD, StringRef NewName, StringRef NewRealPathName) + friend class RealFileSystem; + RealFile(int FD, StringRef NewName) : FD(FD), S(NewName, {}, {}, {}, {}, {}, - llvm::sys::fs::file_type::status_error, {}), - RealName(NewRealPathName.str()) { + llvm::sys::fs::file_type::status_error, {}) { assert(FD >= 0 && "Invalid or inactive file descriptor"); } public: ~RealFile() override; - ErrorOr<Status> status() override; - ErrorOr<std::string> getName() override; ErrorOr<std::unique_ptr<MemoryBuffer>> getBuffer(const Twine &Name, int64_t FileSize, bool RequiresNullTerminator, bool IsVolatile) override; std::error_code close() override; }; - -} // namespace - +} // end anonymous namespace RealFile::~RealFile() { close(); } ErrorOr<Status> RealFile::status() { @@ -212,10 +150,6 @@ ErrorOr<Status> RealFile::status() { return S; } -ErrorOr<std::string> RealFile::getName() { - return RealName.empty() ? S.getName().str() : RealName; -} - ErrorOr<std::unique_ptr<MemoryBuffer>> RealFile::getBuffer(const Twine &Name, int64_t FileSize, bool RequiresNullTerminator, bool IsVolatile) { @@ -224,15 +158,25 @@ RealFile::getBuffer(const Twine &Name, int64_t FileSize, IsVolatile); } +// FIXME: This is terrible, we need this for ::close. +#if !defined(_MSC_VER) && !defined(__MINGW32__) +#include <unistd.h> +#include <sys/uio.h> +#else +#include <io.h> +#ifndef S_ISFIFO +#define S_ISFIFO(x) (0) +#endif +#endif std::error_code RealFile::close() { - std::error_code EC = sys::Process::SafelyCloseFileDescriptor(FD); + if (::close(FD)) + return std::error_code(errno, std::generic_category()); FD = -1; - return EC; + return std::error_code(); } namespace { - -/// The file system according to your operating system. +/// \brief The file system according to your operating system. class RealFileSystem : public FileSystem { public: ErrorOr<Status> status(const Twine &Path) override; @@ -241,11 +185,8 @@ public: llvm::ErrorOr<std::string> getCurrentWorkingDirectory() const override; std::error_code setCurrentWorkingDirectory(const Twine &Path) override; - std::error_code getRealPath(const Twine &Path, - SmallVectorImpl<char> &Output) const override; }; - -} // namespace +} // end anonymous namespace ErrorOr<Status> RealFileSystem::status(const Twine &Path) { sys::fs::file_status RealStatus; @@ -257,11 +198,9 @@ ErrorOr<Status> RealFileSystem::status(const Twine &Path) { ErrorOr<std::unique_ptr<File>> RealFileSystem::openFileForRead(const Twine &Name) { int FD; - SmallString<256> RealName; - if (std::error_code EC = - sys::fs::openFileForRead(Name, FD, sys::fs::OF_None, &RealName)) + if (std::error_code EC = sys::fs::openFileForRead(Name, FD)) return EC; - return std::unique_ptr<File>(new RealFile(FD, Name.str(), RealName.str())); + return std::unique_ptr<File>(new RealFile(FD, Name.str())); } llvm::ErrorOr<std::string> RealFileSystem::getCurrentWorkingDirectory() const { @@ -279,13 +218,11 @@ std::error_code RealFileSystem::setCurrentWorkingDirectory(const Twine &Path) { // difference for example on network filesystems, where symlinks might be // switched during runtime of the tool. Fixing this depends on having a // file system abstraction that allows openat() style interactions. - return llvm::sys::fs::set_current_path(Path); -} - -std::error_code -RealFileSystem::getRealPath(const Twine &Path, - SmallVectorImpl<char> &Output) const { - return llvm::sys::fs::real_path(Path, Output); + SmallString<256> Storage; + StringRef Dir = Path.toNullTerminatedStringRef(Storage); + if (int Err = ::chdir(Dir.data())) + return std::error_code(Err, std::generic_category()); + return std::error_code(); } IntrusiveRefCntPtr<FileSystem> vfs::getRealFileSystem() { @@ -294,38 +231,36 @@ IntrusiveRefCntPtr<FileSystem> vfs::getRealFileSystem() { } namespace { - class RealFSDirIter : public clang::vfs::detail::DirIterImpl { + std::string Path; llvm::sys::fs::directory_iterator Iter; - public: - RealFSDirIter(const Twine &Path, std::error_code &EC) : Iter(Path, EC) { - if (Iter != llvm::sys::fs::directory_iterator()) { + RealFSDirIter(const Twine &_Path, std::error_code &EC) + : Path(_Path.str()), Iter(Path, EC) { + if (!EC && Iter != llvm::sys::fs::directory_iterator()) { llvm::sys::fs::file_status S; - std::error_code ErrorCode = llvm::sys::fs::status(Iter->path(), S, true); - CurrentEntry = Status::copyWithNewName(S, Iter->path()); + EC = Iter->status(S); if (!EC) - EC = ErrorCode; + CurrentEntry = Status::copyWithNewName(S, Iter->path()); } } std::error_code increment() override { std::error_code EC; Iter.increment(EC); - if (Iter == llvm::sys::fs::directory_iterator()) { + if (EC) { + return EC; + } else if (Iter == llvm::sys::fs::directory_iterator()) { CurrentEntry = Status(); } else { llvm::sys::fs::file_status S; - std::error_code ErrorCode = llvm::sys::fs::status(Iter->path(), S, true); + EC = Iter->status(S); CurrentEntry = Status::copyWithNewName(S, Iter->path()); - if (!EC) - EC = ErrorCode; } return EC; } }; - -} // namespace +} directory_iterator RealFileSystem::dir_begin(const Twine &Dir, std::error_code &EC) { @@ -335,9 +270,8 @@ directory_iterator RealFileSystem::dir_begin(const Twine &Dir, //===-----------------------------------------------------------------------===/ // OverlayFileSystem implementation //===-----------------------------------------------------------------------===/ - OverlayFileSystem::OverlayFileSystem(IntrusiveRefCntPtr<FileSystem> BaseFS) { - FSList.push_back(std::move(BaseFS)); + FSList.push_back(BaseFS); } void OverlayFileSystem::pushOverlay(IntrusiveRefCntPtr<FileSystem> FS) { @@ -373,28 +307,17 @@ OverlayFileSystem::getCurrentWorkingDirectory() const { // All file systems are synchronized, just take the first working directory. return FSList.front()->getCurrentWorkingDirectory(); } - std::error_code OverlayFileSystem::setCurrentWorkingDirectory(const Twine &Path) { for (auto &FS : FSList) if (std::error_code EC = FS->setCurrentWorkingDirectory(Path)) return EC; - return {}; -} - -std::error_code -OverlayFileSystem::getRealPath(const Twine &Path, - SmallVectorImpl<char> &Output) const { - for (auto &FS : FSList) - if (FS->exists(Path)) - return FS->getRealPath(Path, Output); - return errc::no_such_file_or_directory; + return std::error_code(); } -clang::vfs::detail::DirIterImpl::~DirIterImpl() = default; +clang::vfs::detail::DirIterImpl::~DirIterImpl() { } namespace { - class OverlayFSDirIterImpl : public clang::vfs::detail::DirIterImpl { OverlayFileSystem &Overlays; std::string Path; @@ -413,7 +336,7 @@ class OverlayFSDirIterImpl : public clang::vfs::detail::DirIterImpl { if (CurrentDirIter != directory_iterator()) break; // found } - return {}; + return std::error_code(); } std::error_code incrementDirIter(bool IsFirstTime) { @@ -452,8 +375,7 @@ public: std::error_code increment() override { return incrementImpl(false); } }; - -} // namespace +} // end anonymous namespace directory_iterator OverlayFileSystem::dir_begin(const Twine &Dir, std::error_code &EC) { @@ -463,7 +385,6 @@ directory_iterator OverlayFileSystem::dir_begin(const Twine &Dir, namespace clang { namespace vfs { - namespace detail { enum InMemoryNodeKind { IME_File, IME_Directory }; @@ -477,15 +398,13 @@ class InMemoryNode { public: InMemoryNode(Status Stat, InMemoryNodeKind Kind) : Stat(std::move(Stat)), Kind(Kind) {} - virtual ~InMemoryNode() = default; - + virtual ~InMemoryNode() {} const Status &getStatus() const { return Stat; } InMemoryNodeKind getKind() const { return Kind; } virtual std::string toString(unsigned Indent) const = 0; }; namespace { - class InMemoryFile : public InMemoryNode { std::unique_ptr<llvm::MemoryBuffer> Buffer; @@ -494,11 +413,9 @@ public: : InMemoryNode(std::move(Stat), IME_File), Buffer(std::move(Buffer)) {} llvm::MemoryBuffer *getBuffer() { return Buffer.get(); } - std::string toString(unsigned Indent) const override { return (std::string(Indent, ' ') + getStatus().getName() + "\n").str(); } - static bool classof(const InMemoryNode *N) { return N->getKind() == IME_File; } @@ -512,7 +429,6 @@ public: explicit InMemoryFileAdaptor(InMemoryFile &Node) : Node(Node) {} llvm::ErrorOr<Status> status() override { return Node.getStatus(); } - llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> getBuffer(const Twine &Name, int64_t FileSize, bool RequiresNullTerminator, bool IsVolatile) override { @@ -520,11 +436,9 @@ public: return llvm::MemoryBuffer::getMemBuffer( Buf->getBuffer(), Buf->getBufferIdentifier(), RequiresNullTerminator); } - - std::error_code close() override { return {}; } + std::error_code close() override { return std::error_code(); } }; - -} // namespace +} // end anonymous namespace class InMemoryDirectory : public InMemoryNode { std::map<std::string, std::unique_ptr<InMemoryNode>> Entries; @@ -532,58 +446,50 @@ class InMemoryDirectory : public InMemoryNode { public: InMemoryDirectory(Status Stat) : InMemoryNode(std::move(Stat), IME_Directory) {} - InMemoryNode *getChild(StringRef Name) { auto I = Entries.find(Name); if (I != Entries.end()) return I->second.get(); return nullptr; } - InMemoryNode *addChild(StringRef Name, std::unique_ptr<InMemoryNode> Child) { return Entries.insert(make_pair(Name, std::move(Child))) .first->second.get(); } - using const_iterator = decltype(Entries)::const_iterator; - + typedef decltype(Entries)::const_iterator const_iterator; const_iterator begin() const { return Entries.begin(); } const_iterator end() const { return Entries.end(); } std::string toString(unsigned Indent) const override { std::string Result = (std::string(Indent, ' ') + getStatus().getName() + "\n").str(); - for (const auto &Entry : Entries) + for (const auto &Entry : Entries) { Result += Entry.second->toString(Indent + 2); + } return Result; } - static bool classof(const InMemoryNode *N) { return N->getKind() == IME_Directory; } }; - -} // namespace detail +} InMemoryFileSystem::InMemoryFileSystem(bool UseNormalizedPaths) : Root(new detail::InMemoryDirectory( - Status("", getNextVirtualUniqueID(), llvm::sys::TimePoint<>(), 0, 0, - 0, llvm::sys::fs::file_type::directory_file, + Status("", getNextVirtualUniqueID(), llvm::sys::TimeValue::MinTime(), + 0, 0, 0, llvm::sys::fs::file_type::directory_file, llvm::sys::fs::perms::all_all))), UseNormalizedPaths(UseNormalizedPaths) {} -InMemoryFileSystem::~InMemoryFileSystem() = default; +InMemoryFileSystem::~InMemoryFileSystem() {} std::string InMemoryFileSystem::toString() const { return Root->toString(/*Indent=*/0); } bool InMemoryFileSystem::addFile(const Twine &P, time_t ModificationTime, - std::unique_ptr<llvm::MemoryBuffer> Buffer, - Optional<uint32_t> User, - Optional<uint32_t> Group, - Optional<llvm::sys::fs::file_type> Type, - Optional<llvm::sys::fs::perms> Perms) { + std::unique_ptr<llvm::MemoryBuffer> Buffer) { SmallString<128> Path; P.toVector(Path); @@ -599,42 +505,32 @@ bool InMemoryFileSystem::addFile(const Twine &P, time_t ModificationTime, return false; detail::InMemoryDirectory *Dir = Root.get(); - auto I = llvm::sys::path::begin(Path), E = sys::path::end(Path); - const auto ResolvedUser = User.getValueOr(0); - const auto ResolvedGroup = Group.getValueOr(0); - const auto ResolvedType = Type.getValueOr(sys::fs::file_type::regular_file); - const auto ResolvedPerms = Perms.getValueOr(sys::fs::all_all); - // Any intermediate directories we create should be accessible by - // the owner, even if Perms says otherwise for the final path. - const auto NewDirectoryPerms = ResolvedPerms | sys::fs::owner_all; + auto I = llvm::sys::path::begin(Path), E = llvm::sys::path::end(Path); while (true) { StringRef Name = *I; detail::InMemoryNode *Node = Dir->getChild(Name); ++I; if (!Node) { if (I == E) { - // End of the path, create a new file or directory. + // End of the path, create a new file. + // FIXME: expose the status details in the interface. Status Stat(P.str(), getNextVirtualUniqueID(), - llvm::sys::toTimePoint(ModificationTime), ResolvedUser, - ResolvedGroup, Buffer->getBufferSize(), ResolvedType, - ResolvedPerms); - std::unique_ptr<detail::InMemoryNode> Child; - if (ResolvedType == sys::fs::file_type::directory_file) { - Child.reset(new detail::InMemoryDirectory(std::move(Stat))); - } else { - Child.reset(new detail::InMemoryFile(std::move(Stat), - std::move(Buffer))); - } - Dir->addChild(Name, std::move(Child)); + llvm::sys::TimeValue(ModificationTime, 0), 0, 0, + Buffer->getBufferSize(), + llvm::sys::fs::file_type::regular_file, + llvm::sys::fs::all_all); + Dir->addChild(Name, llvm::make_unique<detail::InMemoryFile>( + std::move(Stat), std::move(Buffer))); return true; } // Create a new directory. Use the path up to here. + // FIXME: expose the status details in the interface. Status Stat( StringRef(Path.str().begin(), Name.end() - Path.str().begin()), - getNextVirtualUniqueID(), llvm::sys::toTimePoint(ModificationTime), - ResolvedUser, ResolvedGroup, Buffer->getBufferSize(), - sys::fs::file_type::directory_file, NewDirectoryPerms); + getNextVirtualUniqueID(), llvm::sys::TimeValue(ModificationTime, 0), + 0, 0, Buffer->getBufferSize(), + llvm::sys::fs::file_type::directory_file, llvm::sys::fs::all_all); Dir = cast<detail::InMemoryDirectory>(Dir->addChild( Name, llvm::make_unique<detail::InMemoryDirectory>(std::move(Stat)))); continue; @@ -658,16 +554,10 @@ bool InMemoryFileSystem::addFile(const Twine &P, time_t ModificationTime, } bool InMemoryFileSystem::addFileNoOwn(const Twine &P, time_t ModificationTime, - llvm::MemoryBuffer *Buffer, - Optional<uint32_t> User, - Optional<uint32_t> Group, - Optional<llvm::sys::fs::file_type> Type, - Optional<llvm::sys::fs::perms> Perms) { + llvm::MemoryBuffer *Buffer) { return addFile(P, ModificationTime, llvm::MemoryBuffer::getMemBuffer( - Buffer->getBuffer(), Buffer->getBufferIdentifier()), - std::move(User), std::move(Group), std::move(Type), - std::move(Perms)); + Buffer->getBuffer(), Buffer->getBufferIdentifier())); } static ErrorOr<detail::InMemoryNode *> @@ -731,15 +621,13 @@ InMemoryFileSystem::openFileForRead(const Twine &Path) { } namespace { - /// Adaptor from InMemoryDir::iterator to directory_iterator. class InMemoryDirIterator : public clang::vfs::detail::DirIterImpl { detail::InMemoryDirectory::const_iterator I; detail::InMemoryDirectory::const_iterator E; public: - InMemoryDirIterator() = default; - + InMemoryDirIterator() {} explicit InMemoryDirIterator(detail::InMemoryDirectory &Dir) : I(Dir.begin()), E(Dir.end()) { if (I != E) @@ -751,11 +639,10 @@ public: // When we're at the end, make CurrentEntry invalid and DirIterImpl will do // the rest. CurrentEntry = I != E ? I->second->getStatus() : Status(); - return {}; + return std::error_code(); } }; - -} // namespace +} // end anonymous namespace directory_iterator InMemoryFileSystem::dir_begin(const Twine &Dir, std::error_code &EC) { @@ -786,24 +673,10 @@ std::error_code InMemoryFileSystem::setCurrentWorkingDirectory(const Twine &P) { if (!Path.empty()) WorkingDirectory = Path.str(); - return {}; + return std::error_code(); +} } - -std::error_code -InMemoryFileSystem::getRealPath(const Twine &Path, - SmallVectorImpl<char> &Output) const { - auto CWD = getCurrentWorkingDirectory(); - if (!CWD || CWD->empty()) - return errc::operation_not_permitted; - Path.toVector(Output); - if (auto EC = makeAbsolute(Output)) - return EC; - llvm::sys::path::remove_dots(Output, /*remove_dot_dot=*/true); - return {}; } - -} // namespace vfs -} // namespace clang //===-----------------------------------------------------------------------===/ // RedirectingFileSystem implementation @@ -816,15 +689,14 @@ enum EntryKind { EK_File }; -/// A single file or directory in the VFS. +/// \brief A single file or directory in the VFS. class Entry { EntryKind Kind; std::string Name; public: + virtual ~Entry(); Entry(EntryKind K, StringRef Name) : Kind(K), Name(Name) {} - virtual ~Entry() = default; - StringRef getName() const { return Name; } EntryKind getKind() const { return Kind; } }; @@ -839,22 +711,10 @@ public: Status S) : Entry(EK_Directory, Name), Contents(std::move(Contents)), S(std::move(S)) {} - RedirectingDirectoryEntry(StringRef Name, Status S) - : Entry(EK_Directory, Name), S(std::move(S)) {} - Status getStatus() { return S; } - - void addContent(std::unique_ptr<Entry> Content) { - Contents.push_back(std::move(Content)); - } - - Entry *getLastContent() const { return Contents.back().get(); } - - using iterator = decltype(Contents)::iterator; - + typedef decltype(Contents)::iterator iterator; iterator contents_begin() { return Contents.begin(); } iterator contents_end() { return Contents.end(); } - static bool classof(const Entry *E) { return E->getKind() == EK_Directory; } }; @@ -865,27 +725,20 @@ public: NK_External, NK_Virtual }; - private: std::string ExternalContentsPath; NameKind UseName; - public: RedirectingFileEntry(StringRef Name, StringRef ExternalContentsPath, NameKind UseName) : Entry(EK_File, Name), ExternalContentsPath(ExternalContentsPath), UseName(UseName) {} - StringRef getExternalContentsPath() const { return ExternalContentsPath; } - - /// whether to use the external path as the name for this file. + /// \brief whether to use the external path as the name for this file. bool useExternalName(bool GlobalUseExternalName) const { return UseName == NK_NotSet ? GlobalUseExternalName : (UseName == NK_External); } - - NameKind getUseName() const { return UseName; } - static bool classof(const Entry *E) { return E->getKind() == EK_File; } }; @@ -901,11 +754,10 @@ public: RedirectingDirectoryEntry::iterator Begin, RedirectingDirectoryEntry::iterator End, std::error_code &EC); - std::error_code increment() override; }; -/// A virtual file system parsed from a YAML file. +/// \brief A virtual file system parsed from a YAML file. /// /// Currently, this class allows creating virtual directories and mapping /// virtual file paths to existing external files, available in \c ExternalFS. @@ -924,8 +776,6 @@ public: /// All configuration options are optional. /// 'case-sensitive': <boolean, default=true> /// 'use-external-names': <boolean, default=true> -/// 'overlay-relative': <boolean, default=false> -/// 'ignore-non-existent-contents': <boolean, default=true> /// /// Virtual directories are represented as /// \verbatim @@ -961,76 +811,48 @@ public: /// /path/to/file). However, any directory that contains more than one child /// must be uniquely represented by a directory entry. class RedirectingFileSystem : public vfs::FileSystem { - friend class RedirectingFileSystemParser; - /// The root(s) of the virtual file system. std::vector<std::unique_ptr<Entry>> Roots; - - /// The file system to use for external references. + /// \brief The file system to use for external references. IntrusiveRefCntPtr<FileSystem> ExternalFS; - /// If IsRelativeOverlay is set, this represents the directory - /// path that should be prefixed to each 'external-contents' entry - /// when reading from YAML files. - std::string ExternalContentsPrefixDir; - /// @name Configuration /// @{ - /// Whether to perform case-sensitive comparisons. + /// \brief Whether to perform case-sensitive comparisons. /// /// Currently, case-insensitive matching only works correctly with ASCII. - bool CaseSensitive = true; - - /// IsRelativeOverlay marks whether a IsExternalContentsPrefixDir path must - /// be prefixed in every 'external-contents' when reading from YAML files. - bool IsRelativeOverlay = false; + bool CaseSensitive; - /// Whether to use to use the value of 'external-contents' for the + /// \brief Whether to use to use the value of 'external-contents' for the /// names of files. This global value is overridable on a per-file basis. - bool UseExternalNames = true; - - /// Whether an invalid path obtained via 'external-contents' should - /// cause iteration on the VFS to stop. If 'true', the VFS should ignore - /// the entry and continue with the next. Allows YAML files to be shared - /// across multiple compiler invocations regardless of prior existent - /// paths in 'external-contents'. This global value is overridable on a - /// per-file basis. - bool IgnoreNonExistentContents = true; + bool UseExternalNames; /// @} - /// Virtual file paths and external files could be canonicalized without "..", - /// "." and "./" in their paths. FIXME: some unittests currently fail on - /// win32 when using remove_dots and remove_leading_dotslash on paths. - bool UseCanonicalizedPaths = -#ifdef _WIN32 - false; -#else - true; -#endif + friend class RedirectingFileSystemParser; private: RedirectingFileSystem(IntrusiveRefCntPtr<FileSystem> ExternalFS) - : ExternalFS(std::move(ExternalFS)) {} + : ExternalFS(ExternalFS), CaseSensitive(true), UseExternalNames(true) {} - /// Looks up the path <tt>[Start, End)</tt> in \p From, possibly + /// \brief Looks up \p Path in \c Roots. + ErrorOr<Entry *> lookupPath(const Twine &Path); + + /// \brief Looks up the path <tt>[Start, End)</tt> in \p From, possibly /// recursing into the contents of \p From if it is a directory. ErrorOr<Entry *> lookupPath(sys::path::const_iterator Start, sys::path::const_iterator End, Entry *From); - /// Get the status of a given an \c Entry. + /// \brief Get the status of a given an \c Entry. ErrorOr<Status> status(const Twine &Path, Entry *E); public: - /// Looks up \p Path in \c Roots. - ErrorOr<Entry *> lookupPath(const Twine &Path); - - /// Parses \p Buffer, which is expected to be in YAML format and + /// \brief Parses \p Buffer, which is expected to be in YAML format and /// returns a virtual file system representing its contents. static RedirectingFileSystem * create(std::unique_ptr<MemoryBuffer> Buffer, - SourceMgr::DiagHandlerTy DiagHandler, StringRef YAMLFilePath, - void *DiagContext, IntrusiveRefCntPtr<FileSystem> ExternalFS); + SourceMgr::DiagHandlerTy DiagHandler, void *DiagContext, + IntrusiveRefCntPtr<FileSystem> ExternalFS); ErrorOr<Status> status(const Twine &Path) override; ErrorOr<std::unique_ptr<File>> openFileForRead(const Twine &Path) override; @@ -1038,7 +860,6 @@ public: llvm::ErrorOr<std::string> getCurrentWorkingDirectory() const override { return ExternalFS->getCurrentWorkingDirectory(); } - std::error_code setCurrentWorkingDirectory(const Twine &Path) override { return ExternalFS->setCurrentWorkingDirectory(Path); } @@ -1047,61 +868,26 @@ public: ErrorOr<Entry *> E = lookupPath(Dir); if (!E) { EC = E.getError(); - return {}; + return directory_iterator(); } ErrorOr<Status> S = status(Dir, *E); if (!S) { EC = S.getError(); - return {}; + return directory_iterator(); } if (!S->isDirectory()) { EC = std::error_code(static_cast<int>(errc::not_a_directory), std::system_category()); - return {}; + return directory_iterator(); } auto *D = cast<RedirectingDirectoryEntry>(*E); return directory_iterator(std::make_shared<VFSFromYamlDirIterImpl>(Dir, *this, D->contents_begin(), D->contents_end(), EC)); } - - void setExternalContentsPrefixDir(StringRef PrefixDir) { - ExternalContentsPrefixDir = PrefixDir.str(); - } - - StringRef getExternalContentsPrefixDir() const { - return ExternalContentsPrefixDir; - } - - bool ignoreNonExistentContents() const { - return IgnoreNonExistentContents; - } - -#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) -LLVM_DUMP_METHOD void dump() const { - for (const auto &Root : Roots) - dumpEntry(Root.get()); - } - -LLVM_DUMP_METHOD void dumpEntry(Entry *E, int NumSpaces = 0) const { - StringRef Name = E->getName(); - for (int i = 0, e = NumSpaces; i < e; ++i) - dbgs() << " "; - dbgs() << "'" << Name.str().c_str() << "'" << "\n"; - - if (E->getKind() == EK_Directory) { - auto *DE = dyn_cast<RedirectingDirectoryEntry>(E); - assert(DE && "Should be a directory"); - - for (std::unique_ptr<Entry> &SubEntry : - llvm::make_range(DE->contents_begin(), DE->contents_end())) - dumpEntry(SubEntry.get(), NumSpaces+2); - } - } -#endif }; -/// A helper class to hold the common YAML parsing state. +/// \brief A helper class to hold the common YAML parsing state. class RedirectingFileSystemParser { yaml::Stream &Stream; @@ -1112,8 +898,7 @@ class RedirectingFileSystemParser { // false on error bool parseScalarString(yaml::Node *N, StringRef &Result, SmallVectorImpl<char> &Storage) { - const auto *S = dyn_cast<yaml::ScalarNode>(N); - + yaml::ScalarNode *S = dyn_cast<yaml::ScalarNode>(N); if (!S) { error(N, "expected string"); return false; @@ -1144,13 +929,11 @@ class RedirectingFileSystemParser { } struct KeyStatus { + KeyStatus(bool Required=false) : Required(Required), Seen(false) {} bool Required; - bool Seen = false; - - KeyStatus(bool Required = false) : Required(Required) {} + bool Seen; }; - - using KeyStatusPair = std::pair<StringRef, KeyStatus>; + typedef std::pair<StringRef, KeyStatus> KeyStatusPair; // false on error bool checkDuplicateOrUnknownKey(yaml::Node *KeyNode, StringRef Key, @@ -1170,82 +953,19 @@ class RedirectingFileSystemParser { // false on error bool checkMissingKeys(yaml::Node *Obj, DenseMap<StringRef, KeyStatus> &Keys) { - for (const auto &I : Keys) { - if (I.second.Required && !I.second.Seen) { - error(Obj, Twine("missing key '") + I.first + "'"); + for (DenseMap<StringRef, KeyStatus>::iterator I = Keys.begin(), + E = Keys.end(); + I != E; ++I) { + if (I->second.Required && !I->second.Seen) { + error(Obj, Twine("missing key '") + I->first + "'"); return false; } } return true; } - Entry *lookupOrCreateEntry(RedirectingFileSystem *FS, StringRef Name, - Entry *ParentEntry = nullptr) { - if (!ParentEntry) { // Look for a existent root - for (const auto &Root : FS->Roots) { - if (Name.equals(Root->getName())) { - ParentEntry = Root.get(); - return ParentEntry; - } - } - } else { // Advance to the next component - auto *DE = dyn_cast<RedirectingDirectoryEntry>(ParentEntry); - for (std::unique_ptr<Entry> &Content : - llvm::make_range(DE->contents_begin(), DE->contents_end())) { - auto *DirContent = dyn_cast<RedirectingDirectoryEntry>(Content.get()); - if (DirContent && Name.equals(Content->getName())) - return DirContent; - } - } - - // ... or create a new one - std::unique_ptr<Entry> E = llvm::make_unique<RedirectingDirectoryEntry>( - Name, - Status("", getNextVirtualUniqueID(), std::chrono::system_clock::now(), - 0, 0, 0, file_type::directory_file, sys::fs::all_all)); - - if (!ParentEntry) { // Add a new root to the overlay - FS->Roots.push_back(std::move(E)); - ParentEntry = FS->Roots.back().get(); - return ParentEntry; - } - - auto *DE = dyn_cast<RedirectingDirectoryEntry>(ParentEntry); - DE->addContent(std::move(E)); - return DE->getLastContent(); - } - - void uniqueOverlayTree(RedirectingFileSystem *FS, Entry *SrcE, - Entry *NewParentE = nullptr) { - StringRef Name = SrcE->getName(); - switch (SrcE->getKind()) { - case EK_Directory: { - auto *DE = dyn_cast<RedirectingDirectoryEntry>(SrcE); - assert(DE && "Must be a directory"); - // Empty directories could be present in the YAML as a way to - // describe a file for a current directory after some of its subdir - // is parsed. This only leads to redundant walks, ignore it. - if (!Name.empty()) - NewParentE = lookupOrCreateEntry(FS, Name, NewParentE); - for (std::unique_ptr<Entry> &SubEntry : - llvm::make_range(DE->contents_begin(), DE->contents_end())) - uniqueOverlayTree(FS, SubEntry.get(), NewParentE); - break; - } - case EK_File: { - auto *FE = dyn_cast<RedirectingFileEntry>(SrcE); - assert(FE && "Must be a file"); - assert(NewParentE && "Parent entry must exist"); - auto *DE = dyn_cast<RedirectingDirectoryEntry>(NewParentE); - DE->addContent(llvm::make_unique<RedirectingFileEntry>( - Name, FE->getExternalContentsPath(), FE->getUseName())); - break; - } - } - } - - std::unique_ptr<Entry> parseEntry(yaml::Node *N, RedirectingFileSystem *FS) { - auto *M = dyn_cast<yaml::MappingNode>(N); + std::unique_ptr<Entry> parseEntry(yaml::Node *N) { + yaml::MappingNode *M = dyn_cast<yaml::MappingNode>(N); if (!M) { error(N, "expected mapping node for file or directory entry"); return nullptr; @@ -1268,93 +988,70 @@ class RedirectingFileSystemParser { auto UseExternalName = RedirectingFileEntry::NK_NotSet; EntryKind Kind; - for (auto &I : *M) { + for (yaml::MappingNode::iterator I = M->begin(), E = M->end(); I != E; + ++I) { StringRef Key; // Reuse the buffer for key and value, since we don't look at key after // parsing value. SmallString<256> Buffer; - if (!parseScalarString(I.getKey(), Key, Buffer)) + if (!parseScalarString(I->getKey(), Key, Buffer)) return nullptr; - if (!checkDuplicateOrUnknownKey(I.getKey(), Key, Keys)) + if (!checkDuplicateOrUnknownKey(I->getKey(), Key, Keys)) return nullptr; StringRef Value; if (Key == "name") { - if (!parseScalarString(I.getValue(), Value, Buffer)) + if (!parseScalarString(I->getValue(), Value, Buffer)) return nullptr; - - if (FS->UseCanonicalizedPaths) { - SmallString<256> Path(Value); - // Guarantee that old YAML files containing paths with ".." and "." - // are properly canonicalized before read into the VFS. - Path = sys::path::remove_leading_dotslash(Path); - sys::path::remove_dots(Path, /*remove_dot_dot=*/true); - Name = Path.str(); - } else { - Name = Value; - } + Name = Value; } else if (Key == "type") { - if (!parseScalarString(I.getValue(), Value, Buffer)) + if (!parseScalarString(I->getValue(), Value, Buffer)) return nullptr; if (Value == "file") Kind = EK_File; else if (Value == "directory") Kind = EK_Directory; else { - error(I.getValue(), "unknown value for 'type'"); + error(I->getValue(), "unknown value for 'type'"); return nullptr; } } else if (Key == "contents") { if (HasContents) { - error(I.getKey(), + error(I->getKey(), "entry already has 'contents' or 'external-contents'"); return nullptr; } HasContents = true; - auto *Contents = dyn_cast<yaml::SequenceNode>(I.getValue()); + yaml::SequenceNode *Contents = + dyn_cast<yaml::SequenceNode>(I->getValue()); if (!Contents) { // FIXME: this is only for directories, what about files? - error(I.getValue(), "expected array"); + error(I->getValue(), "expected array"); return nullptr; } - for (auto &I : *Contents) { - if (std::unique_ptr<Entry> E = parseEntry(&I, FS)) + for (yaml::SequenceNode::iterator I = Contents->begin(), + E = Contents->end(); + I != E; ++I) { + if (std::unique_ptr<Entry> E = parseEntry(&*I)) EntryArrayContents.push_back(std::move(E)); else return nullptr; } } else if (Key == "external-contents") { if (HasContents) { - error(I.getKey(), + error(I->getKey(), "entry already has 'contents' or 'external-contents'"); return nullptr; } HasContents = true; - if (!parseScalarString(I.getValue(), Value, Buffer)) + if (!parseScalarString(I->getValue(), Value, Buffer)) return nullptr; - - SmallString<256> FullPath; - if (FS->IsRelativeOverlay) { - FullPath = FS->getExternalContentsPrefixDir(); - assert(!FullPath.empty() && - "External contents prefix directory must exist"); - llvm::sys::path::append(FullPath, Value); - } else { - FullPath = Value; - } - - if (FS->UseCanonicalizedPaths) { - // Guarantee that old YAML files containing paths with ".." and "." - // are properly canonicalized before read into the VFS. - FullPath = sys::path::remove_leading_dotslash(FullPath); - sys::path::remove_dots(FullPath, /*remove_dot_dot=*/true); - } - ExternalContentsPath = FullPath.str(); + ExternalContentsPath = Value; } else if (Key == "use-external-name") { bool Val; - if (!parseScalarBool(I.getValue(), Val)) + if (!parseScalarBool(I->getValue(), Val)) return nullptr; UseExternalName = Val ? RedirectingFileEntry::NK_External : RedirectingFileEntry::NK_Virtual; @@ -1399,8 +1096,8 @@ class RedirectingFileSystemParser { case EK_Directory: Result = llvm::make_unique<RedirectingDirectoryEntry>( LastComponent, std::move(EntryArrayContents), - Status("", getNextVirtualUniqueID(), std::chrono::system_clock::now(), - 0, 0, 0, file_type::directory_file, sys::fs::all_all)); + Status("", getNextVirtualUniqueID(), sys::TimeValue::now(), 0, 0, 0, + file_type::directory_file, sys::fs::all_all)); break; } @@ -1416,8 +1113,8 @@ class RedirectingFileSystemParser { Entries.push_back(std::move(Result)); Result = llvm::make_unique<RedirectingDirectoryEntry>( *I, std::move(Entries), - Status("", getNextVirtualUniqueID(), std::chrono::system_clock::now(), - 0, 0, 0, file_type::directory_file, sys::fs::all_all)); + Status("", getNextVirtualUniqueID(), sys::TimeValue::now(), 0, 0, 0, + file_type::directory_file, sys::fs::all_all)); } return Result; } @@ -1427,7 +1124,7 @@ public: // false on error bool parse(yaml::Node *Root, RedirectingFileSystem *FS) { - auto *Top = dyn_cast<yaml::MappingNode>(Root); + yaml::MappingNode *Top = dyn_cast<yaml::MappingNode>(Root); if (!Top) { error(Root, "expected mapping node"); return false; @@ -1437,66 +1134,59 @@ public: KeyStatusPair("version", true), KeyStatusPair("case-sensitive", false), KeyStatusPair("use-external-names", false), - KeyStatusPair("overlay-relative", false), - KeyStatusPair("ignore-non-existent-contents", false), KeyStatusPair("roots", true), }; DenseMap<StringRef, KeyStatus> Keys(std::begin(Fields), std::end(Fields)); - std::vector<std::unique_ptr<Entry>> RootEntries; // Parse configuration and 'roots' - for (auto &I : *Top) { + for (yaml::MappingNode::iterator I = Top->begin(), E = Top->end(); I != E; + ++I) { SmallString<10> KeyBuffer; StringRef Key; - if (!parseScalarString(I.getKey(), Key, KeyBuffer)) + if (!parseScalarString(I->getKey(), Key, KeyBuffer)) return false; - if (!checkDuplicateOrUnknownKey(I.getKey(), Key, Keys)) + if (!checkDuplicateOrUnknownKey(I->getKey(), Key, Keys)) return false; if (Key == "roots") { - auto *Roots = dyn_cast<yaml::SequenceNode>(I.getValue()); + yaml::SequenceNode *Roots = dyn_cast<yaml::SequenceNode>(I->getValue()); if (!Roots) { - error(I.getValue(), "expected array"); + error(I->getValue(), "expected array"); return false; } - for (auto &I : *Roots) { - if (std::unique_ptr<Entry> E = parseEntry(&I, FS)) - RootEntries.push_back(std::move(E)); + for (yaml::SequenceNode::iterator I = Roots->begin(), E = Roots->end(); + I != E; ++I) { + if (std::unique_ptr<Entry> E = parseEntry(&*I)) + FS->Roots.push_back(std::move(E)); else return false; } } else if (Key == "version") { StringRef VersionString; SmallString<4> Storage; - if (!parseScalarString(I.getValue(), VersionString, Storage)) + if (!parseScalarString(I->getValue(), VersionString, Storage)) return false; int Version; if (VersionString.getAsInteger<int>(10, Version)) { - error(I.getValue(), "expected integer"); + error(I->getValue(), "expected integer"); return false; } if (Version < 0) { - error(I.getValue(), "invalid version number"); + error(I->getValue(), "invalid version number"); return false; } if (Version != 0) { - error(I.getValue(), "version mismatch, expected 0"); + error(I->getValue(), "version mismatch, expected 0"); return false; } } else if (Key == "case-sensitive") { - if (!parseScalarBool(I.getValue(), FS->CaseSensitive)) - return false; - } else if (Key == "overlay-relative") { - if (!parseScalarBool(I.getValue(), FS->IsRelativeOverlay)) + if (!parseScalarBool(I->getValue(), FS->CaseSensitive)) return false; } else if (Key == "use-external-names") { - if (!parseScalarBool(I.getValue(), FS->UseExternalNames)) - return false; - } else if (Key == "ignore-non-existent-contents") { - if (!parseScalarBool(I.getValue(), FS->IgnoreNonExistentContents)) + if (!parseScalarBool(I->getValue(), FS->UseExternalNames)) return false; } else { llvm_unreachable("key missing from Keys"); @@ -1508,24 +1198,17 @@ public: if (!checkMissingKeys(Top, Keys)) return false; - - // Now that we sucessefully parsed the YAML file, canonicalize the internal - // representation to a proper directory tree so that we can search faster - // inside the VFS. - for (auto &E : RootEntries) - uniqueOverlayTree(FS, E.get()); - return true; } }; +} // end of anonymous namespace + +Entry::~Entry() = default; -} // namespace +RedirectingFileSystem *RedirectingFileSystem::create( + std::unique_ptr<MemoryBuffer> Buffer, SourceMgr::DiagHandlerTy DiagHandler, + void *DiagContext, IntrusiveRefCntPtr<FileSystem> ExternalFS) { -RedirectingFileSystem * -RedirectingFileSystem::create(std::unique_ptr<MemoryBuffer> Buffer, - SourceMgr::DiagHandlerTy DiagHandler, - StringRef YAMLFilePath, void *DiagContext, - IntrusiveRefCntPtr<FileSystem> ExternalFS) { SourceMgr SM; yaml::Stream Stream(Buffer->getMemBufferRef(), SM); @@ -1540,24 +1223,7 @@ RedirectingFileSystem::create(std::unique_ptr<MemoryBuffer> Buffer, RedirectingFileSystemParser P(Stream); std::unique_ptr<RedirectingFileSystem> FS( - new RedirectingFileSystem(std::move(ExternalFS))); - - if (!YAMLFilePath.empty()) { - // Use the YAML path from -ivfsoverlay to compute the dir to be prefixed - // to each 'external-contents' path. - // - // Example: - // -ivfsoverlay dummy.cache/vfs/vfs.yaml - // yields: - // FS->ExternalContentsPrefixDir => /<absolute_path_to>/dummy.cache/vfs - // - SmallString<256> OverlayAbsDir = sys::path::parent_path(YAMLFilePath); - std::error_code EC = llvm::sys::fs::make_absolute(OverlayAbsDir); - assert(!EC && "Overlay dir final path must be absolute"); - (void)EC; - FS->setExternalContentsPrefixDir(OverlayAbsDir); - } - + new RedirectingFileSystem(ExternalFS)); if (!P.parse(Root, FS.get())) return nullptr; @@ -1572,20 +1238,12 @@ ErrorOr<Entry *> RedirectingFileSystem::lookupPath(const Twine &Path_) { if (std::error_code EC = makeAbsolute(Path)) return EC; - // Canonicalize path by removing ".", "..", "./", etc components. This is - // a VFS request, do bot bother about symlinks in the path components - // but canonicalize in order to perform the correct entry search. - if (UseCanonicalizedPaths) { - Path = sys::path::remove_leading_dotslash(Path); - sys::path::remove_dots(Path, /*remove_dot_dot=*/true); - } - if (Path.empty()) return make_error_code(llvm::errc::invalid_argument); sys::path::const_iterator Start = sys::path::begin(Path); sys::path::const_iterator End = sys::path::end(Path); - for (const auto &Root : Roots) { + for (const std::unique_ptr<Entry> &Root : Roots) { ErrorOr<Entry *> Result = lookupPath(Start, End, Root.get()); if (Result || Result.getError() != llvm::errc::no_such_file_or_directory) return Result; @@ -1596,32 +1254,20 @@ ErrorOr<Entry *> RedirectingFileSystem::lookupPath(const Twine &Path_) { ErrorOr<Entry *> RedirectingFileSystem::lookupPath(sys::path::const_iterator Start, sys::path::const_iterator End, Entry *From) { -#ifndef _WIN32 - assert(!isTraversalComponent(*Start) && - !isTraversalComponent(From->getName()) && - "Paths should not contain traversal components"); -#else - // FIXME: this is here to support windows, remove it once canonicalized - // paths become globally default. if (Start->equals(".")) ++Start; -#endif - - StringRef FromName = From->getName(); - // Forward the search to the next component in case this is an empty one. - if (!FromName.empty()) { - if (CaseSensitive ? !Start->equals(FromName) - : !Start->equals_lower(FromName)) - // failure to match - return make_error_code(llvm::errc::no_such_file_or_directory); + // FIXME: handle .. + if (CaseSensitive ? !Start->equals(From->getName()) + : !Start->equals_lower(From->getName())) + // failure to match + return make_error_code(llvm::errc::no_such_file_or_directory); - ++Start; + ++Start; - if (Start == End) { - // Match! - return From; - } + if (Start == End) { + // Match! + return From; } auto *DE = dyn_cast<RedirectingDirectoryEntry>(From); @@ -1669,7 +1315,6 @@ ErrorOr<Status> RedirectingFileSystem::status(const Twine &Path) { } namespace { - /// Provide a file wrapper with an overriden status. class FileWithFixedStatus : public File { std::unique_ptr<File> InnerFile; @@ -1677,21 +1322,18 @@ class FileWithFixedStatus : public File { public: FileWithFixedStatus(std::unique_ptr<File> InnerFile, Status S) - : InnerFile(std::move(InnerFile)), S(std::move(S)) {} + : InnerFile(std::move(InnerFile)), S(S) {} ErrorOr<Status> status() override { return S; } ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> - getBuffer(const Twine &Name, int64_t FileSize, bool RequiresNullTerminator, bool IsVolatile) override { return InnerFile->getBuffer(Name, FileSize, RequiresNullTerminator, IsVolatile); } - std::error_code close() override { return InnerFile->close(); } }; - -} // namespace +} // end anonymous namespace ErrorOr<std::unique_ptr<File>> RedirectingFileSystem::openFileForRead(const Twine &Path) { @@ -1720,54 +1362,10 @@ RedirectingFileSystem::openFileForRead(const Twine &Path) { IntrusiveRefCntPtr<FileSystem> vfs::getVFSFromYAML(std::unique_ptr<MemoryBuffer> Buffer, - SourceMgr::DiagHandlerTy DiagHandler, - StringRef YAMLFilePath, - void *DiagContext, + SourceMgr::DiagHandlerTy DiagHandler, void *DiagContext, IntrusiveRefCntPtr<FileSystem> ExternalFS) { return RedirectingFileSystem::create(std::move(Buffer), DiagHandler, - YAMLFilePath, DiagContext, - std::move(ExternalFS)); -} - -static void getVFSEntries(Entry *SrcE, SmallVectorImpl<StringRef> &Path, - SmallVectorImpl<YAMLVFSEntry> &Entries) { - auto Kind = SrcE->getKind(); - if (Kind == EK_Directory) { - auto *DE = dyn_cast<RedirectingDirectoryEntry>(SrcE); - assert(DE && "Must be a directory"); - for (std::unique_ptr<Entry> &SubEntry : - llvm::make_range(DE->contents_begin(), DE->contents_end())) { - Path.push_back(SubEntry->getName()); - getVFSEntries(SubEntry.get(), Path, Entries); - Path.pop_back(); - } - return; - } - - assert(Kind == EK_File && "Must be a EK_File"); - auto *FE = dyn_cast<RedirectingFileEntry>(SrcE); - assert(FE && "Must be a file"); - SmallString<128> VPath; - for (auto &Comp : Path) - llvm::sys::path::append(VPath, Comp); - Entries.push_back(YAMLVFSEntry(VPath.c_str(), FE->getExternalContentsPath())); -} - -void vfs::collectVFSFromYAML(std::unique_ptr<MemoryBuffer> Buffer, - SourceMgr::DiagHandlerTy DiagHandler, - StringRef YAMLFilePath, - SmallVectorImpl<YAMLVFSEntry> &CollectedEntries, - void *DiagContext, - IntrusiveRefCntPtr<FileSystem> ExternalFS) { - RedirectingFileSystem *VFS = RedirectingFileSystem::create( - std::move(Buffer), DiagHandler, YAMLFilePath, DiagContext, - std::move(ExternalFS)); - ErrorOr<Entry *> RootE = VFS->lookupPath("/"); - if (!RootE) - return; - SmallVector<StringRef, 8> Components; - Components.push_back("/"); - getVFSEntries(*RootE, Components, CollectedEntries); + DiagContext, ExternalFS); } UniqueID vfs::getNextVirtualUniqueID() { @@ -1778,6 +1376,16 @@ UniqueID vfs::getNextVirtualUniqueID() { return UniqueID(std::numeric_limits<uint64_t>::max(), ID); } +#ifndef NDEBUG +static bool pathHasTraversal(StringRef Path) { + using namespace llvm::sys; + for (StringRef Comp : llvm::make_range(path::begin(Path), path::end(Path))) + if (Comp == "." || Comp == "..") + return true; + return false; +} +#endif + void YAMLVFSWriter::addFileMapping(StringRef VirtualPath, StringRef RealPath) { assert(sys::path::is_absolute(VirtualPath) && "virtual path not absolute"); assert(sys::path::is_absolute(RealPath) && "real path not absolute"); @@ -1786,13 +1394,11 @@ void YAMLVFSWriter::addFileMapping(StringRef VirtualPath, StringRef RealPath) { } namespace { - class JSONWriter { llvm::raw_ostream &OS; SmallVector<StringRef, 16> DirStack; - - unsigned getDirIndent() { return 4 * DirStack.size(); } - unsigned getFileIndent() { return 4 * (DirStack.size() + 1); } + inline unsigned getDirIndent() { return 4 * DirStack.size(); } + inline unsigned getFileIndent() { return 4 * (DirStack.size() + 1); } bool containedIn(StringRef Parent, StringRef Path); StringRef containedPart(StringRef Parent, StringRef Path); void startDirectory(StringRef Path); @@ -1801,17 +1407,12 @@ class JSONWriter { public: JSONWriter(llvm::raw_ostream &OS) : OS(OS) {} - - void write(ArrayRef<YAMLVFSEntry> Entries, Optional<bool> UseExternalNames, - Optional<bool> IsCaseSensitive, Optional<bool> IsOverlayRelative, - Optional<bool> IgnoreNonExistentContents, StringRef OverlayDir); + void write(ArrayRef<YAMLVFSEntry> Entries, Optional<bool> IsCaseSensitive); }; - -} // namespace +} bool JSONWriter::containedIn(StringRef Parent, StringRef Path) { using namespace llvm::sys; - // Compare each path component. auto IParent = path::begin(Parent), EParent = path::end(Parent); for (auto IChild = path::begin(Path), EChild = path::end(Path); @@ -1859,11 +1460,7 @@ void JSONWriter::writeEntry(StringRef VPath, StringRef RPath) { } void JSONWriter::write(ArrayRef<YAMLVFSEntry> Entries, - Optional<bool> UseExternalNames, - Optional<bool> IsCaseSensitive, - Optional<bool> IsOverlayRelative, - Optional<bool> IgnoreNonExistentContents, - StringRef OverlayDir) { + Optional<bool> IsCaseSensitive) { using namespace llvm::sys; OS << "{\n" @@ -1871,33 +1468,12 @@ void JSONWriter::write(ArrayRef<YAMLVFSEntry> Entries, if (IsCaseSensitive.hasValue()) OS << " 'case-sensitive': '" << (IsCaseSensitive.getValue() ? "true" : "false") << "',\n"; - if (UseExternalNames.hasValue()) - OS << " 'use-external-names': '" - << (UseExternalNames.getValue() ? "true" : "false") << "',\n"; - bool UseOverlayRelative = false; - if (IsOverlayRelative.hasValue()) { - UseOverlayRelative = IsOverlayRelative.getValue(); - OS << " 'overlay-relative': '" - << (UseOverlayRelative ? "true" : "false") << "',\n"; - } - if (IgnoreNonExistentContents.hasValue()) - OS << " 'ignore-non-existent-contents': '" - << (IgnoreNonExistentContents.getValue() ? "true" : "false") << "',\n"; OS << " 'roots': [\n"; if (!Entries.empty()) { const YAMLVFSEntry &Entry = Entries.front(); startDirectory(path::parent_path(Entry.VPath)); - - StringRef RPath = Entry.RPath; - if (UseOverlayRelative) { - unsigned OverlayDirLen = OverlayDir.size(); - assert(RPath.substr(0, OverlayDirLen) == OverlayDir && - "Overlay dir must be contained in RPath"); - RPath = RPath.slice(OverlayDirLen, RPath.size()); - } - - writeEntry(path::filename(Entry.VPath), RPath); + writeEntry(path::filename(Entry.VPath), Entry.RPath); for (const auto &Entry : Entries.slice(1)) { StringRef Dir = path::parent_path(Entry.VPath); @@ -1911,14 +1487,7 @@ void JSONWriter::write(ArrayRef<YAMLVFSEntry> Entries, OS << ",\n"; startDirectory(Dir); } - StringRef RPath = Entry.RPath; - if (UseOverlayRelative) { - unsigned OverlayDirLen = OverlayDir.size(); - assert(RPath.substr(0, OverlayDirLen) == OverlayDir && - "Overlay dir must be contained in RPath"); - RPath = RPath.slice(OverlayDirLen, RPath.size()); - } - writeEntry(path::filename(Entry.VPath), RPath); + writeEntry(path::filename(Entry.VPath), Entry.RPath); } while (!DirStack.empty()) { @@ -1933,14 +1502,12 @@ void JSONWriter::write(ArrayRef<YAMLVFSEntry> Entries, } void YAMLVFSWriter::write(llvm::raw_ostream &OS) { - llvm::sort(Mappings.begin(), Mappings.end(), - [](const YAMLVFSEntry &LHS, const YAMLVFSEntry &RHS) { + std::sort(Mappings.begin(), Mappings.end(), + [](const YAMLVFSEntry &LHS, const YAMLVFSEntry &RHS) { return LHS.VPath < RHS.VPath; }); - JSONWriter(OS).write(Mappings, UseExternalNames, IsCaseSensitive, - IsOverlayRelative, IgnoreNonExistentContents, - OverlayDir); + JSONWriter(OS).write(Mappings, IsCaseSensitive); } VFSFromYamlDirIterImpl::VFSFromYamlDirIterImpl( @@ -1948,48 +1515,30 @@ VFSFromYamlDirIterImpl::VFSFromYamlDirIterImpl( RedirectingDirectoryEntry::iterator Begin, RedirectingDirectoryEntry::iterator End, std::error_code &EC) : Dir(_Path.str()), FS(FS), Current(Begin), End(End) { - while (Current != End) { + if (Current != End) { SmallString<128> PathStr(Dir); llvm::sys::path::append(PathStr, (*Current)->getName()); llvm::ErrorOr<vfs::Status> S = FS.status(PathStr); - if (S) { + if (S) CurrentEntry = *S; - return; - } - // Skip entries which do not map to a reliable external content. - if (FS.ignoreNonExistentContents() && - S.getError() == llvm::errc::no_such_file_or_directory) { - ++Current; - continue; - } else { + else EC = S.getError(); - break; - } } } std::error_code VFSFromYamlDirIterImpl::increment() { assert(Current != End && "cannot iterate past end"); - while (++Current != End) { + if (++Current != End) { SmallString<128> PathStr(Dir); llvm::sys::path::append(PathStr, (*Current)->getName()); llvm::ErrorOr<vfs::Status> S = FS.status(PathStr); - if (!S) { - // Skip entries which do not map to a reliable external content. - if (FS.ignoreNonExistentContents() && - S.getError() == llvm::errc::no_such_file_or_directory) { - continue; - } else { - return S.getError(); - } - } + if (!S) + return S.getError(); CurrentEntry = *S; - break; - } - - if (Current == End) + } else { CurrentEntry = Status(); - return {}; + } + return std::error_code(); } vfs::recursive_directory_iterator::recursive_directory_iterator(FileSystem &FS_, @@ -1997,7 +1546,7 @@ vfs::recursive_directory_iterator::recursive_directory_iterator(FileSystem &FS_, std::error_code &EC) : FS(&FS_) { directory_iterator I = FS->dir_begin(Path, EC); - if (I != directory_iterator()) { + if (!EC && I != directory_iterator()) { State = std::make_shared<IterState>(); State->push(I); } @@ -2010,6 +1559,8 @@ recursive_directory_iterator::increment(std::error_code &EC) { vfs::directory_iterator End; if (State->top()->isDirectory()) { vfs::directory_iterator I = FS->dir_begin(State->top()->getName(), EC); + if (EC) + return *this; if (I != End) { State->push(I); return *this; diff --git a/gnu/llvm/tools/clang/lib/Frontend/CacheTokens.cpp b/gnu/llvm/tools/clang/lib/Frontend/CacheTokens.cpp index c4504a14456..87f3d172581 100644 --- a/gnu/llvm/tools/clang/lib/Frontend/CacheTokens.cpp +++ b/gnu/llvm/tools/clang/lib/Frontend/CacheTokens.cpp @@ -12,22 +12,23 @@ // //===----------------------------------------------------------------------===// +#include "clang/Frontend/Utils.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/FileSystemStatCache.h" #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/SourceManager.h" -#include "clang/Frontend/Utils.h" #include "clang/Lex/Lexer.h" #include "clang/Lex/PTHManager.h" #include "clang/Lex/Preprocessor.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringMap.h" -#include "llvm/Support/DJB.h" #include "llvm/Support/EndianStream.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/OnDiskHashTable.h" #include "llvm/Support/Path.h" +#include "llvm/Support/raw_ostream.h" // FIXME: put this somewhere else? #ifndef S_ISDIR @@ -58,37 +59,30 @@ public: class PTHEntryKeyVariant { - union { - const FileEntry *FE; - // FIXME: Use "StringRef Path;" when MSVC 2013 is dropped. - const char *PathPtr; - }; - size_t PathSize; + union { const FileEntry* FE; const char* Path; }; enum { IsFE = 0x1, IsDE = 0x2, IsNoExist = 0x0 } Kind; FileData *Data; public: PTHEntryKeyVariant(const FileEntry *fe) : FE(fe), Kind(IsFE), Data(nullptr) {} - PTHEntryKeyVariant(FileData *Data, StringRef Path) - : PathPtr(Path.data()), PathSize(Path.size()), Kind(IsDE), - Data(new FileData(*Data)) {} + PTHEntryKeyVariant(FileData *Data, const char *path) + : Path(path), Kind(IsDE), Data(new FileData(*Data)) {} - explicit PTHEntryKeyVariant(StringRef Path) - : PathPtr(Path.data()), PathSize(Path.size()), Kind(IsNoExist), - Data(nullptr) {} + explicit PTHEntryKeyVariant(const char *path) + : Path(path), Kind(IsNoExist), Data(nullptr) {} bool isFile() const { return Kind == IsFE; } StringRef getString() const { - return Kind == IsFE ? FE->getName() : StringRef(PathPtr, PathSize); + return Kind == IsFE ? FE->getName() : Path; } unsigned getKind() const { return (unsigned) Kind; } void EmitData(raw_ostream& Out) { using namespace llvm::support; - endian::Writer LE(Out, little); + endian::Writer<little> LE(Out); switch (Kind) { case IsFE: { // Emit stat information. @@ -128,14 +122,14 @@ public: typedef unsigned offset_type; static hash_value_type ComputeHash(PTHEntryKeyVariant V) { - return llvm::djbHash(V.getString()); + return llvm::HashString(V.getString()); } static std::pair<unsigned,unsigned> EmitKeyDataLength(raw_ostream& Out, PTHEntryKeyVariant V, const PTHEntry& E) { using namespace llvm::support; - endian::Writer LE(Out, little); + endian::Writer<little> LE(Out); unsigned n = V.getString().size() + 1 + 1; LE.write<uint16_t>(n); @@ -149,7 +143,7 @@ public: static void EmitKey(raw_ostream& Out, PTHEntryKeyVariant V, unsigned n){ using namespace llvm::support; // Emit the entry kind. - Out << char(V.getKind()); + endian::Writer<little>(Out).write<uint8_t>((unsigned)V.getKind()); // Emit the string. Out.write(V.getString().data(), n - 1); } @@ -157,7 +151,7 @@ public: static void EmitData(raw_ostream& Out, PTHEntryKeyVariant V, const PTHEntry& E, unsigned) { using namespace llvm::support; - endian::Writer LE(Out, little); + endian::Writer<little> LE(Out); // For file entries emit the offsets into the PTH file for token data // and the preprocessor blocks table. @@ -189,14 +183,14 @@ class PTHWriter { typedef llvm::DenseMap<const IdentifierInfo*,uint32_t> IDMap; typedef llvm::StringMap<OffsetOpt, llvm::BumpPtrAllocator> CachedStrsTy; + IDMap IM; raw_pwrite_stream &Out; Preprocessor& PP; - IDMap IM; - std::vector<llvm::StringMapEntry<OffsetOpt>*> StrEntries; + uint32_t idcount; PTHMap PM; CachedStrsTy CachedStrs; - uint32_t idcount; Offset CurStrOffset; + std::vector<llvm::StringMapEntry<OffsetOpt>*> StrEntries; //// Get the persistent id for the given IdentifierInfo*. uint32_t ResolveID(const IdentifierInfo* II); @@ -205,17 +199,18 @@ class PTHWriter { void EmitToken(const Token& T); void Emit8(uint32_t V) { - Out << char(V); + using namespace llvm::support; + endian::Writer<little>(Out).write<uint8_t>(V); } void Emit16(uint32_t V) { using namespace llvm::support; - endian::write<uint16_t>(Out, V, little); + endian::Writer<little>(Out).write<uint16_t>(V); } void Emit32(uint32_t V) { using namespace llvm::support; - endian::write<uint32_t>(Out, V, little); + endian::Writer<little>(Out).write<uint32_t>(V); } void EmitBuf(const char *Ptr, unsigned NumBytes) { @@ -224,7 +219,7 @@ class PTHWriter { void EmitString(StringRef V) { using namespace llvm::support; - endian::write<uint16_t>(Out, V.size(), little); + endian::Writer<little>(Out).write<uint16_t>(V.size()); EmitBuf(V.data(), V.size()); } @@ -246,7 +241,7 @@ public: : Out(out), PP(pp), idcount(0), CurStrOffset(0) {} PTHMap &getPM() { return PM; } - void GeneratePTH(StringRef MainFile); + void GeneratePTH(const std::string &MainFile); }; } // end anonymous namespace @@ -298,7 +293,7 @@ PTHEntry PTHWriter::LexTokens(Lexer& L) { // Pad 0's so that we emit tokens to a 4-byte alignment. // This speed up reading them back in. using namespace llvm::support; - endian::Writer LE(Out, little); + endian::Writer<little> LE(Out); uint32_t TokenOff = Out.tell(); for (uint64_t N = llvm::OffsetToAlignment(TokenOff, 4); N; --N, ++TokenOff) LE.write<uint8_t>(0); @@ -484,7 +479,7 @@ static void pwrite32le(raw_pwrite_stream &OS, uint32_t Val, uint64_t &Off) { Off += 4; } -void PTHWriter::GeneratePTH(StringRef MainFile) { +void PTHWriter::GeneratePTH(const std::string &MainFile) { // Generate the prologue. Out << "cfe-pth" << '\0'; Emit32(PTHManager::Version); @@ -555,7 +550,7 @@ public: StatListener(PTHMap &pm) : PM(pm) {} ~StatListener() override {} - LookupResult getStat(StringRef Path, FileData &Data, bool isFile, + LookupResult getStat(const char *Path, FileData &Data, bool isFile, std::unique_ptr<vfs::File> *F, vfs::FileSystem &FS) override { LookupResult Result = statChained(Path, Data, isFile, F, FS); @@ -624,14 +619,14 @@ public: typedef unsigned offset_type; static hash_value_type ComputeHash(PTHIdKey* key) { - return llvm::djbHash(key->II->getName()); + return llvm::HashString(key->II->getName()); } static std::pair<unsigned,unsigned> EmitKeyDataLength(raw_ostream& Out, const PTHIdKey* key, uint32_t) { using namespace llvm::support; unsigned n = key->II->getLength() + 1; - endian::write<uint16_t>(Out, n, little); + endian::Writer<little>(Out).write<uint16_t>(n); return std::make_pair(n, sizeof(uint32_t)); } @@ -645,7 +640,7 @@ public: static void EmitData(raw_ostream& Out, PTHIdKey*, uint32_t pID, unsigned) { using namespace llvm::support; - endian::write<uint32_t>(Out, pID, little); + endian::Writer<little>(Out).write<uint32_t>(pID); } }; } // end anonymous namespace @@ -661,8 +656,7 @@ std::pair<Offset,Offset> PTHWriter::EmitIdentifierTable() { // (2) a map from (IdentifierInfo*, Offset)* -> persistent IDs // Note that we use 'calloc', so all the bytes are 0. - PTHIdKey *IIDMap = static_cast<PTHIdKey*>( - llvm::safe_calloc(idcount, sizeof(PTHIdKey))); + PTHIdKey *IIDMap = (PTHIdKey*)calloc(idcount, sizeof(PTHIdKey)); // Create the hashtable. llvm::OnDiskChainedHashTableGenerator<PTHIdentifierTableTrait> IIOffMap; diff --git a/gnu/llvm/tools/clang/lib/Frontend/CodeGenOptions.cpp b/gnu/llvm/tools/clang/lib/Frontend/CodeGenOptions.cpp index 84a39f2d570..50bb9f951be 100644 --- a/gnu/llvm/tools/clang/lib/Frontend/CodeGenOptions.cpp +++ b/gnu/llvm/tools/clang/lib/Frontend/CodeGenOptions.cpp @@ -17,7 +17,7 @@ CodeGenOptions::CodeGenOptions() { #define ENUM_CODEGENOPT(Name, Type, Bits, Default) set##Name(Default); #include "clang/Frontend/CodeGenOptions.def" - RelocationModel = llvm::Reloc::PIC_; + RelocationModel = "pic"; memcpy(CoverageVersion, "402*", 4); } diff --git a/gnu/llvm/tools/clang/lib/Frontend/PCHContainerOperations.cpp b/gnu/llvm/tools/clang/lib/Frontend/PCHContainerOperations.cpp index 340e8ce63ff..5e1d7720509 100644 --- a/gnu/llvm/tools/clang/lib/Frontend/PCHContainerOperations.cpp +++ b/gnu/llvm/tools/clang/lib/Frontend/PCHContainerOperations.cpp @@ -13,27 +13,23 @@ #include "clang/Frontend/PCHContainerOperations.h" #include "clang/AST/ASTConsumer.h" -#include "clang/Lex/ModuleLoader.h" #include "llvm/Bitcode/BitstreamReader.h" #include "llvm/Support/raw_ostream.h" -#include <utility> +#include "clang/Lex/ModuleLoader.h" using namespace clang; -PCHContainerWriter::~PCHContainerWriter() {} -PCHContainerReader::~PCHContainerReader() {} - namespace { -/// A PCHContainerGenerator that writes out the PCH to a flat file. +/// \brief A PCHContainerGenerator that writes out the PCH to a flat file. class RawPCHContainerGenerator : public ASTConsumer { std::shared_ptr<PCHBuffer> Buffer; - std::unique_ptr<raw_pwrite_stream> OS; + raw_pwrite_stream *OS; public: - RawPCHContainerGenerator(std::unique_ptr<llvm::raw_pwrite_stream> OS, + RawPCHContainerGenerator(llvm::raw_pwrite_stream *OS, std::shared_ptr<PCHBuffer> Buffer) - : Buffer(std::move(Buffer)), OS(std::move(OS)) {} + : Buffer(Buffer), OS(OS) {} ~RawPCHContainerGenerator() override = default; @@ -53,14 +49,15 @@ public: std::unique_ptr<ASTConsumer> RawPCHContainerWriter::CreatePCHContainerGenerator( CompilerInstance &CI, const std::string &MainFileName, - const std::string &OutputFileName, std::unique_ptr<llvm::raw_pwrite_stream> OS, + const std::string &OutputFileName, llvm::raw_pwrite_stream *OS, std::shared_ptr<PCHBuffer> Buffer) const { - return llvm::make_unique<RawPCHContainerGenerator>(std::move(OS), Buffer); + return llvm::make_unique<RawPCHContainerGenerator>(OS, Buffer); } -StringRef -RawPCHContainerReader::ExtractPCH(llvm::MemoryBufferRef Buffer) const { - return Buffer.getBuffer(); +void RawPCHContainerReader::ExtractPCH( + llvm::MemoryBufferRef Buffer, llvm::BitstreamReader &StreamFile) const { + StreamFile.init((const unsigned char *)Buffer.getBufferStart(), + (const unsigned char *)Buffer.getBufferEnd()); } PCHContainerOperations::PCHContainerOperations() { diff --git a/gnu/llvm/tools/clang/lib/Lex/PTHLexer.cpp b/gnu/llvm/tools/clang/lib/Lex/PTHLexer.cpp index 45cff56dcaa..5f63d35c5be 100644 --- a/gnu/llvm/tools/clang/lib/Lex/PTHLexer.cpp +++ b/gnu/llvm/tools/clang/lib/Lex/PTHLexer.cpp @@ -1,4 +1,4 @@ -//===- PTHLexer.cpp - Lex from a token stream -----------------------------===// +//===--- PTHLexer.cpp - Lex from a token stream ---------------------------===// // // The LLVM Compiler Infrastructure // @@ -12,32 +12,20 @@ //===----------------------------------------------------------------------===// #include "clang/Lex/PTHLexer.h" -#include "clang/Basic/Diagnostic.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/FileSystemStatCache.h" #include "clang/Basic/IdentifierTable.h" -#include "clang/Basic/SourceManager.h" #include "clang/Basic/TokenKinds.h" #include "clang/Lex/LexDiagnostic.h" #include "clang/Lex/PTHManager.h" #include "clang/Lex/Preprocessor.h" #include "clang/Lex/Token.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/DJB.h" -#include "llvm/Support/Endian.h" -#include "llvm/Support/ErrorOr.h" -#include "llvm/Support/FileSystem.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/Support/EndianStream.h" #include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/OnDiskHashTable.h" -#include <cassert> -#include <cstdint> -#include <cstdlib> -#include <cstring> -#include <ctime> #include <memory> -#include <utility> - +#include <system_error> using namespace clang; static const unsigned StoredTokenSize = 1 + 1 + 2 + 4 + 4; @@ -48,8 +36,9 @@ static const unsigned StoredTokenSize = 1 + 1 + 2 + 4 + 4; PTHLexer::PTHLexer(Preprocessor &PP, FileID FID, const unsigned char *D, const unsigned char *ppcond, PTHManager &PM) - : PreprocessorLexer(&PP, FID), TokBuf(D), CurPtr(D), PPCond(ppcond), - CurPPCondPtr(ppcond), PTHMgr(PM) { + : PreprocessorLexer(&PP, FID), TokBuf(D), CurPtr(D), LastHashTokPtr(nullptr), + PPCond(ppcond), CurPPCondPtr(ppcond), PTHMgr(PM) { + FileStartLoc = PP.getSourceManager().getLocForStartOfFile(FID); } @@ -145,7 +134,7 @@ bool PTHLexer::LexEndOfFile(Token &Result) { ParsingPreprocessorDirective = false; // Done parsing the "line". return true; // Have a token. } - + assert(!LexingRawMode); // If we are in a #if directive, emit an error. @@ -179,7 +168,7 @@ void PTHLexer::DiscardToEndOfLine() { // We don't need to actually reconstruct full tokens from the token buffer. // This saves some copies and it also reduces IdentifierInfo* lookup. const unsigned char* p = CurPtr; - while (true) { + while (1) { // Read the token kind. Are we at the end of the file? tok::TokenKind x = (tok::TokenKind) (uint8_t) *p; if (x == tok::eof) break; @@ -198,7 +187,6 @@ void PTHLexer::DiscardToEndOfLine() { /// SkipBlock - Used by Preprocessor to skip the current conditional block. bool PTHLexer::SkipBlock() { using namespace llvm::support; - assert(CurPPCondPtr && "No cached PP conditional information."); assert(LastHashTokPtr && "No known '#' token."); @@ -215,7 +203,7 @@ bool PTHLexer::SkipBlock() { // Compute the actual memory address of the '#' token data for this entry. HashEntryI = TokBuf + Offset; - // Optimization: "Sibling jumping". #if...#else...#endif blocks can + // Optmization: "Sibling jumping". #if...#else...#endif blocks can // contain nested blocks. In the side-table we can jump over these // nested blocks instead of doing a linear search if the next "sibling" // entry is not at a location greater than LastHashTokPtr. @@ -316,33 +304,31 @@ SourceLocation PTHLexer::getSourceLocation() { /// to map from FileEntry objects managed by FileManager to offsets within /// the PTH file. namespace { - class PTHFileData { const uint32_t TokenOff; const uint32_t PPCondOff; - public: PTHFileData(uint32_t tokenOff, uint32_t ppCondOff) - : TokenOff(tokenOff), PPCondOff(ppCondOff) {} + : TokenOff(tokenOff), PPCondOff(ppCondOff) {} uint32_t getTokenOffset() const { return TokenOff; } uint32_t getPPCondOffset() const { return PPCondOff; } }; + class PTHFileLookupCommonTrait { public: - using internal_key_type = std::pair<unsigned char, StringRef>; - using hash_value_type = unsigned; - using offset_type = unsigned; + typedef std::pair<unsigned char, const char*> internal_key_type; + typedef unsigned hash_value_type; + typedef unsigned offset_type; static hash_value_type ComputeHash(internal_key_type x) { - return llvm::djbHash(x.second); + return llvm::HashString(x.second); } static std::pair<unsigned, unsigned> ReadKeyDataLength(const unsigned char*& d) { using namespace llvm::support; - unsigned keyLen = (unsigned)endian::readNext<uint16_t, little, unaligned>(d); unsigned dataLen = (unsigned) *(d++); @@ -355,26 +341,25 @@ public: } }; -} // namespace +} // end anonymous namespace class PTHManager::PTHFileLookupTrait : public PTHFileLookupCommonTrait { public: - using external_key_type = const FileEntry *; - using data_type = PTHFileData; + typedef const FileEntry* external_key_type; + typedef PTHFileData data_type; static internal_key_type GetInternalKey(const FileEntry* FE) { return std::make_pair((unsigned char) 0x1, FE->getName()); } static bool EqualKey(internal_key_type a, internal_key_type b) { - return a.first == b.first && a.second == b.second; + return a.first == b.first && strcmp(a.second, b.second) == 0; } static PTHFileData ReadData(const internal_key_type& k, const unsigned char* d, unsigned) { - using namespace llvm::support; - assert(k.first == 0x1 && "Only file lookups can match!"); + using namespace llvm::support; uint32_t x = endian::readNext<uint32_t, little, unaligned>(d); uint32_t y = endian::readNext<uint32_t, little, unaligned>(d); return PTHFileData(x, y); @@ -383,11 +368,11 @@ public: class PTHManager::PTHStringLookupTrait { public: - using data_type = uint32_t; - using external_key_type = const std::pair<const char *, unsigned>; - using internal_key_type = external_key_type; - using hash_value_type = uint32_t; - using offset_type = unsigned; + typedef uint32_t data_type; + typedef const std::pair<const char*, unsigned> external_key_type; + typedef external_key_type internal_key_type; + typedef uint32_t hash_value_type; + typedef unsigned offset_type; static bool EqualKey(const internal_key_type& a, const internal_key_type& b) { @@ -396,7 +381,7 @@ public: } static hash_value_type ComputeHash(const internal_key_type& a) { - return llvm::djbHash(StringRef(a.first, a.second)); + return llvm::HashString(StringRef(a.first, a.second)); } // This hopefully will just get inlined and removed by the optimizer. @@ -406,7 +391,6 @@ public: static std::pair<unsigned, unsigned> ReadKeyDataLength(const unsigned char*& d) { using namespace llvm::support; - return std::make_pair( (unsigned)endian::readNext<uint16_t, little, unaligned>(d), sizeof(uint32_t)); @@ -421,7 +405,6 @@ public: static uint32_t ReadData(const internal_key_type& k, const unsigned char* d, unsigned) { using namespace llvm::support; - return endian::readNext<uint32_t, little, unaligned>(d); } }; @@ -438,10 +421,11 @@ PTHManager::PTHManager( const unsigned char *spellingBase, const char *originalSourceFile) : Buf(std::move(buf)), PerIDCache(std::move(perIDCache)), FileLookup(std::move(fileLookup)), IdDataTable(idDataTable), - StringIdLookup(std::move(stringIdLookup)), NumIds(numIds), + StringIdLookup(std::move(stringIdLookup)), NumIds(numIds), PP(nullptr), SpellingBase(spellingBase), OriginalSourceFile(originalSourceFile) {} -PTHManager::~PTHManager() = default; +PTHManager::~PTHManager() { +} static void InvalidPTH(DiagnosticsEngine &Diags, const char *Msg) { Diags.Report(Diags.getCustomDiagID(DiagnosticsEngine::Error, "%0")) << Msg; @@ -574,7 +558,6 @@ PTHManager *PTHManager::Create(StringRef file, DiagnosticsEngine &Diags) { IdentifierInfo* PTHManager::LazilyCreateIdentifierInfo(unsigned PersistentID) { using namespace llvm::support; - // Look in the PTH file for the string data for the IdentifierInfo object. const unsigned char* TableEntry = IdDataTable + sizeof(uint32_t)*PersistentID; const unsigned char *IDData = @@ -584,7 +567,7 @@ IdentifierInfo* PTHManager::LazilyCreateIdentifierInfo(unsigned PersistentID) { // Allocate the object. std::pair<IdentifierInfo,const unsigned char*> *Mem = - Alloc.Allocate<std::pair<IdentifierInfo, const unsigned char *>>(); + Alloc.Allocate<std::pair<IdentifierInfo,const unsigned char*> >(); Mem->second = IDData; assert(IDData[0] != '\0'); @@ -644,28 +627,28 @@ PTHLexer *PTHManager::CreateLexer(FileID FID) { //===----------------------------------------------------------------------===// namespace { - class PTHStatData { public: + const bool HasData; uint64_t Size; time_t ModTime; llvm::sys::fs::UniqueID UniqueID; - const bool HasData = false; bool IsDirectory; - PTHStatData() = default; PTHStatData(uint64_t Size, time_t ModTime, llvm::sys::fs::UniqueID UniqueID, bool IsDirectory) - : Size(Size), ModTime(ModTime), UniqueID(UniqueID), HasData(true), + : HasData(true), Size(Size), ModTime(ModTime), UniqueID(UniqueID), IsDirectory(IsDirectory) {} + + PTHStatData() : HasData(false) {} }; class PTHStatLookupTrait : public PTHFileLookupCommonTrait { public: - using external_key_type = StringRef; // const char* - using data_type = PTHStatData; + typedef const char* external_key_type; // const char* + typedef PTHStatData data_type; - static internal_key_type GetInternalKey(StringRef path) { + static internal_key_type GetInternalKey(const char *path) { // The key 'kind' doesn't matter here because it is ignored in EqualKey. return std::make_pair((unsigned char) 0x0, path); } @@ -673,11 +656,12 @@ public: static bool EqualKey(internal_key_type a, internal_key_type b) { // When doing 'stat' lookups we don't care about the kind of 'a' and 'b', // just the paths. - return a.second == b.second; + return strcmp(a.second, b.second) == 0; } static data_type ReadData(const internal_key_type& k, const unsigned char* d, unsigned) { + if (k.first /* File or Directory */) { bool IsDirectory = true; if (k.first == 0x1 /* File */) { @@ -699,14 +683,11 @@ public: return data_type(); } }; - -} // namespace +} // end anonymous namespace namespace clang { - class PTHStatCache : public FileSystemStatCache { - using CacheTy = llvm::OnDiskChainedHashTable<PTHStatLookupTrait>; - + typedef llvm::OnDiskChainedHashTable<PTHStatLookupTrait> CacheTy; CacheTy Cache; public: @@ -714,7 +695,7 @@ public: : Cache(FL.getNumBuckets(), FL.getNumEntries(), FL.getBuckets(), FL.getBase()) {} - LookupResult getStat(StringRef Path, FileData &Data, bool isFile, + LookupResult getStat(const char *Path, FileData &Data, bool isFile, std::unique_ptr<vfs::File> *F, vfs::FileSystem &FS) override { // Do the lookup for the file's data in the PTH file. @@ -740,8 +721,7 @@ public: return CacheExists; } }; - -} // namespace clang +} std::unique_ptr<FileSystemStatCache> PTHManager::createStatCache() { return llvm::make_unique<PTHStatCache>(*FileLookup); diff --git a/gnu/llvm/tools/clang/lib/StaticAnalyzer/Checkers/AllocationDiagnostics.h b/gnu/llvm/tools/clang/lib/StaticAnalyzer/Checkers/AllocationDiagnostics.h index 62b7fab0739..048418ef62d 100644 --- a/gnu/llvm/tools/clang/lib/StaticAnalyzer/Checkers/AllocationDiagnostics.h +++ b/gnu/llvm/tools/clang/lib/StaticAnalyzer/Checkers/AllocationDiagnostics.h @@ -18,7 +18,7 @@ namespace clang { namespace ento { -/// Returns true if leak diagnostics should directly reference +/// \brief Returns true if leak diagnostics should directly reference /// the allocatin site (where possible). /// /// The default is false. diff --git a/gnu/llvm/tools/clang/lib/StaticAnalyzer/Checkers/ClangCheckers.cpp b/gnu/llvm/tools/clang/lib/StaticAnalyzer/Checkers/ClangCheckers.cpp index fb9e366c3de..77a5a722645 100644 --- a/gnu/llvm/tools/clang/lib/StaticAnalyzer/Checkers/ClangCheckers.cpp +++ b/gnu/llvm/tools/clang/lib/StaticAnalyzer/Checkers/ClangCheckers.cpp @@ -27,6 +27,6 @@ void ento::registerBuiltinCheckers(CheckerRegistry ®istry) { #define GET_CHECKERS #define CHECKER(FULLNAME,CLASS,DESCFILE,HELPTEXT,GROUPINDEX,HIDDEN) \ registry.addChecker(register##CLASS, FULLNAME, HELPTEXT); -#include "clang/StaticAnalyzer/Checkers/Checkers.inc" +#include "Checkers.inc" #undef GET_CHECKERS } diff --git a/gnu/llvm/tools/clang/lib/StaticAnalyzer/Checkers/ClangSACheckers.h b/gnu/llvm/tools/clang/lib/StaticAnalyzer/Checkers/ClangSACheckers.h index d6e96f27a75..05b4a61c5af 100644 --- a/gnu/llvm/tools/clang/lib/StaticAnalyzer/Checkers/ClangSACheckers.h +++ b/gnu/llvm/tools/clang/lib/StaticAnalyzer/Checkers/ClangSACheckers.h @@ -26,7 +26,7 @@ class CheckerRegistry; #define GET_CHECKERS #define CHECKER(FULLNAME,CLASS,CXXFILE,HELPTEXT,GROUPINDEX,HIDDEN) \ void register##CLASS(CheckerManager &mgr); -#include "clang/StaticAnalyzer/Checkers/Checkers.inc" +#include "Checkers.inc" #undef CHECKER #undef GET_CHECKERS diff --git a/gnu/llvm/tools/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp b/gnu/llvm/tools/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp index 9c85c098372..f983c308563 100644 --- a/gnu/llvm/tools/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp +++ b/gnu/llvm/tools/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// -#include "AllocationDiagnostics.h" #include "ClangSACheckers.h" +#include "AllocationDiagnostics.h" #include "SelectorExtras.h" #include "clang/AST/Attr.h" #include "clang/AST/DeclCXX.h" @@ -39,7 +39,6 @@ #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" #include <cstdarg> -#include <utility> using namespace clang; using namespace ento; @@ -462,7 +461,6 @@ private: ArgEffect getDefaultArgEffect() const { return DefaultArgEffect; } friend class RetainSummaryManager; - friend class RetainCountChecker; }; } // end anonymous namespace @@ -555,7 +553,7 @@ public: } const RetainSummary *find(IdentifierInfo* II, Selector S) { - // FIXME: Class method lookup. Right now we don't have a good way + // FIXME: Class method lookup. Right now we dont' have a good way // of going between IdentifierInfo* and the class hierarchy. MapTy::iterator I = M.find(ObjCSummaryKey(II, S)); @@ -704,30 +702,31 @@ private: ObjCMethodSummaries[ObjCSummaryKey(ClsII, S)] = Summ; } - template <typename... Keywords> void addMethodSummary(IdentifierInfo *ClsII, ObjCMethodSummariesTy &Summaries, - const RetainSummary *Summ, Keywords *... Kws) { - Selector S = getKeywordSelector(Ctx, Kws...); + const RetainSummary *Summ, va_list argp) { + Selector S = getKeywordSelector(Ctx, argp); Summaries[ObjCSummaryKey(ClsII, S)] = Summ; } - template <typename... Keywords> - void addInstMethSummary(const char *Cls, const RetainSummary *Summ, - Keywords *... Kws) { - addMethodSummary(&Ctx.Idents.get(Cls), ObjCMethodSummaries, Summ, Kws...); + void addInstMethSummary(const char* Cls, const RetainSummary * Summ, ...) { + va_list argp; + va_start(argp, Summ); + addMethodSummary(&Ctx.Idents.get(Cls), ObjCMethodSummaries, Summ, argp); + va_end(argp); } - template <typename... Keywords> - void addClsMethSummary(const char *Cls, const RetainSummary *Summ, - Keywords *... Kws) { - addMethodSummary(&Ctx.Idents.get(Cls), ObjCClassMethodSummaries, Summ, - Kws...); + void addClsMethSummary(const char* Cls, const RetainSummary * Summ, ...) { + va_list argp; + va_start(argp, Summ); + addMethodSummary(&Ctx.Idents.get(Cls),ObjCClassMethodSummaries, Summ, argp); + va_end(argp); } - template <typename... Keywords> - void addClsMethSummary(IdentifierInfo *II, const RetainSummary *Summ, - Keywords *... Kws) { - addMethodSummary(II, ObjCClassMethodSummaries, Summ, Kws...); + void addClsMethSummary(IdentifierInfo *II, const RetainSummary * Summ, ...) { + va_list argp; + va_start(argp, Summ); + addMethodSummary(II, ObjCClassMethodSummaries, Summ, argp); + va_end(argp); } public: @@ -740,7 +739,7 @@ public: ObjCAllocRetE(gcenabled ? RetEffect::MakeGCNotOwned() : (usesARC ? RetEffect::MakeNotOwned(RetEffect::ObjC) - : RetEffect::MakeOwned(RetEffect::ObjC))), + : RetEffect::MakeOwned(RetEffect::ObjC, true))), ObjCInitRetE(gcenabled ? RetEffect::MakeGCNotOwned() : (usesARC ? RetEffect::MakeNotOwned(RetEffect::ObjC) @@ -883,22 +882,21 @@ RetainSummaryManager::getPersistentSummary(const RetainSummary &OldSumm) { //===----------------------------------------------------------------------===// static bool isRetain(const FunctionDecl *FD, StringRef FName) { - return FName.startswith_lower("retain") || FName.endswith_lower("retain"); + return FName.endswith("Retain"); } static bool isRelease(const FunctionDecl *FD, StringRef FName) { - return FName.startswith_lower("release") || FName.endswith_lower("release"); + return FName.endswith("Release"); } static bool isAutorelease(const FunctionDecl *FD, StringRef FName) { - return FName.startswith_lower("autorelease") || - FName.endswith_lower("autorelease"); + return FName.endswith("Autorelease"); } static bool isMakeCollectable(const FunctionDecl *FD, StringRef FName) { // FIXME: Remove FunctionDecl parameter. // FIXME: Is it really okay if MakeCollectable isn't a suffix? - return FName.find_lower("MakeCollectable") != StringRef::npos; + return FName.find("MakeCollectable") != StringRef::npos; } static ArgEffect getStopTrackingHardEquivalent(ArgEffect E) { @@ -954,10 +952,7 @@ void RetainSummaryManager::updateSummaryForCall(const RetainSummary *&S, if (IdentifierInfo *Name = FC->getDecl()->getIdentifier()) { // When the CGBitmapContext is deallocated, the callback here will free // the associated data buffer. - // The callback in dispatch_data_create frees the buffer, but not - // the data object. - if (Name->isStr("CGBitmapContextCreateWithData") || - Name->isStr("dispatch_data_create")) + if (Name->isStr("CGBitmapContextCreateWithData")) RE = S->getRetEffect(); } } @@ -1063,7 +1058,6 @@ RetainSummaryManager::getFunctionSummary(const FunctionDecl *FD) { // Inspect the result type. QualType RetTy = FT->getReturnType(); - std::string RetTyName = RetTy.getAsString(); // FIXME: This should all be refactored into a chain of "summary lookup" // filters. @@ -1083,17 +1077,15 @@ RetainSummaryManager::getFunctionSummary(const FunctionDecl *FD) { AllowAnnotations = false; } else if (FName == "CFPlugInInstanceCreate") { S = getPersistentSummary(RetEffect::MakeNoRet()); - } else if (FName == "IORegistryEntrySearchCFProperty" - || (RetTyName == "CFMutableDictionaryRef" && ( - FName == "IOBSDNameMatching" || + } else if (FName == "IOBSDNameMatching" || FName == "IOServiceMatching" || FName == "IOServiceNameMatching" || + FName == "IORegistryEntrySearchCFProperty" || FName == "IORegistryEntryIDMatching" || - FName == "IOOpenFirmwarePathMatching" - ))) { + FName == "IOOpenFirmwarePathMatching") { // Part of <rdar://problem/6961230>. (IOKit) // This should be addressed using a API table. - S = getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF), + S = getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF, true), DoNothing, DoNothing); } else if (FName == "IOServiceGetMatchingService" || FName == "IOServiceGetMatchingServices") { @@ -1123,7 +1115,7 @@ RetainSummaryManager::getFunctionSummary(const FunctionDecl *FD) { // passed to CGBitmapContextCreateWithData is released via // a callback and doing full IPA to make sure this is done correctly. ScratchArgs = AF.add(ScratchArgs, 8, StopTracking); - S = getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF), + S = getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF, true), DoNothing, DoNothing); } else if (FName == "CVPixelBufferCreateWithPlanarBytes") { // FIXES: <rdar://problem/7283567> @@ -1133,14 +1125,6 @@ RetainSummaryManager::getFunctionSummary(const FunctionDecl *FD) { // correctly. ScratchArgs = AF.add(ScratchArgs, 12, StopTracking); S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing); - } else if (FName == "VTCompressionSessionEncodeFrame") { - // The context argument passed to VTCompressionSessionEncodeFrame() - // is passed to the callback specified when creating the session - // (e.g. with VTCompressionSessionCreate()) which can release it. - // To account for this possibility, conservatively stop tracking - // the context. - ScratchArgs = AF.add(ScratchArgs, 5, StopTracking); - S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing); } else if (FName == "dispatch_set_context" || FName == "xpc_connection_set_context") { // <rdar://problem/11059275> - The analyzer currently doesn't have @@ -1171,11 +1155,6 @@ RetainSummaryManager::getFunctionSummary(const FunctionDecl *FD) { if (cocoa::isRefType(RetTy, "CF", FName)) { if (isRetain(FD, FName)) { S = getUnarySummary(FT, cfretain); - // CFRetain isn't supposed to be annotated. However, this may as well - // be a user-made "safe" CFRetain function that is incorrectly - // annotated as cf_returns_retained due to lack of better options. - // We want to ignore such annotation. - AllowAnnotations = false; } else if (isAutorelease(FD, FName)) { S = getUnarySummary(FT, cfautorelease); // The headers use cf_consumed, but we can fully model CFAutorelease @@ -1191,9 +1170,8 @@ RetainSummaryManager::getFunctionSummary(const FunctionDecl *FD) { break; } - // For CoreGraphics ('CG') and CoreVideo ('CV') types. - if (cocoa::isRefType(RetTy, "CG", FName) || - cocoa::isRefType(RetTy, "CV", FName)) { + // For CoreGraphics ('CG') types. + if (cocoa::isRefType(RetTy, "CG", FName)) { if (isRetain(FD, FName)) S = getUnarySummary(FT, cfretain); else @@ -1202,10 +1180,10 @@ RetainSummaryManager::getFunctionSummary(const FunctionDecl *FD) { break; } - // For all other CF-style types, use the Create/Get - // rule for summaries but don't support Retain functions - // with framework-specific prefixes. - if (coreFoundation::isCFObjectRef(RetTy)) { + // For the Disk Arbitration API (DiskArbitration/DADisk.h) + if (cocoa::isRefType(RetTy, "DADisk") || + cocoa::isRefType(RetTy, "DADissenter") || + cocoa::isRefType(RetTy, "DASessionRef")) { S = getCFCreateGetRuleSummary(FD); break; } @@ -1220,8 +1198,7 @@ RetainSummaryManager::getFunctionSummary(const FunctionDecl *FD) { // Check for release functions, the only kind of functions that we care // about that don't return a pointer type. - if (FName.size() >= 2 && - FName[0] == 'C' && (FName[1] == 'F' || FName[1] == 'G')) { + if (FName[0] == 'C' && (FName[1] == 'F' || FName[1] == 'G')) { // Test for 'CGCF'. FName = FName.substr(FName.startswith("CGCF") ? 4 : 2); @@ -1305,7 +1282,7 @@ const RetainSummary * RetainSummaryManager::getCFSummaryCreateRule(const FunctionDecl *FD) { assert (ScratchArgs.isEmpty()); - return getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF)); + return getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF, true)); } const RetainSummary * @@ -1315,28 +1292,6 @@ RetainSummaryManager::getCFSummaryGetRule(const FunctionDecl *FD) { DoNothing, DoNothing); } -/// Returns true if the declaration 'D' is annotated with 'rcAnnotation'. -static bool hasRCAnnotation(const Decl *D, StringRef rcAnnotation) { - for (const auto *Ann : D->specific_attrs<AnnotateAttr>()) { - if (Ann->getAnnotation() == rcAnnotation) - return true; - } - return false; -} - -/// Returns true if the function declaration 'FD' contains -/// 'rc_ownership_trusted_implementation' annotate attribute. -static bool isTrustedReferenceCountImplementation(const FunctionDecl *FD) { - return hasRCAnnotation(FD, "rc_ownership_trusted_implementation"); -} - -static bool isGeneralizedObjectRef(QualType Ty) { - if (Ty.getAsString().substr(0, 4) == "isl_") - return true; - else - return false; -} - //===----------------------------------------------------------------------===// // Summary creation for Selectors. //===----------------------------------------------------------------------===// @@ -1357,9 +1312,7 @@ RetainSummaryManager::getRetEffectFromAnnotations(QualType RetTy, } if (D->hasAttr<CFReturnsRetainedAttr>()) - return RetEffect::MakeOwned(RetEffect::CF); - else if (hasRCAnnotation(D, "rc_ownership_returns_retained")) - return RetEffect::MakeOwned(RetEffect::Generalized); + return RetEffect::MakeOwned(RetEffect::CF, true); if (D->hasAttr<CFReturnsNotRetainedAttr>()) return RetEffect::MakeNotOwned(RetEffect::CF); @@ -1383,11 +1336,9 @@ RetainSummaryManager::updateSummaryFromAnnotations(const RetainSummary *&Summ, const ParmVarDecl *pd = *pi; if (pd->hasAttr<NSConsumedAttr>()) Template->addArg(AF, parm_idx, DecRefMsg); - else if (pd->hasAttr<CFConsumedAttr>() || - hasRCAnnotation(pd, "rc_ownership_consumed")) + else if (pd->hasAttr<CFConsumedAttr>()) Template->addArg(AF, parm_idx, DecRef); - else if (pd->hasAttr<CFReturnsRetainedAttr>() || - hasRCAnnotation(pd, "rc_ownership_returns_retained")) { + else if (pd->hasAttr<CFReturnsRetainedAttr>()) { QualType PointeeTy = pd->getType()->getPointeeType(); if (!PointeeTy.isNull()) if (coreFoundation::isCFObjectRef(PointeeTy)) @@ -1474,7 +1425,7 @@ RetainSummaryManager::getStandardMethodSummary(const ObjCMethodDecl *MD, case OMF_new: case OMF_copy: case OMF_mutableCopy: - ResultEff = RetEffect::MakeOwned(RetEffect::CF); + ResultEff = RetEffect::MakeOwned(RetEffect::CF, true); break; default: ResultEff = RetEffect::MakeNotOwned(RetEffect::CF); @@ -1496,7 +1447,7 @@ RetainSummaryManager::getStandardMethodSummary(const ObjCMethodDecl *MD, if (cocoa::isCocoaObjectRef(RetTy)) ResultEff = ObjCAllocRetE; else if (coreFoundation::isCFObjectRef(RetTy)) - ResultEff = RetEffect::MakeOwned(RetEffect::CF); + ResultEff = RetEffect::MakeOwned(RetEffect::CF, true); break; case OMF_autorelease: ReceiverEff = Autorelease; @@ -1627,7 +1578,7 @@ void RetainSummaryManager::InitializeMethodSummaries() { // The next methods are allocators. const RetainSummary *AllocSumm = getPersistentSummary(ObjCAllocRetE); const RetainSummary *CFAllocSumm = - getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF)); + getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF, true)); // Create the "retain" selector. RetEffect NoRet = RetEffect::MakeNoRet(); @@ -1676,16 +1627,20 @@ void RetainSummaryManager::InitializeMethodSummaries() { addClassMethSummary("NSAutoreleasePool", "new", NoTrackYet); // Create summaries QCRenderer/QCView -createSnapShotImageOfType: - addInstMethSummary("QCRenderer", AllocSumm, "createSnapshotImageOfType"); - addInstMethSummary("QCView", AllocSumm, "createSnapshotImageOfType"); + addInstMethSummary("QCRenderer", AllocSumm, + "createSnapshotImageOfType", nullptr); + addInstMethSummary("QCView", AllocSumm, + "createSnapshotImageOfType", nullptr); // Create summaries for CIContext, 'createCGImage' and // 'createCGLayerWithSize'. These objects are CF objects, and are not // automatically garbage collected. - addInstMethSummary("CIContext", CFAllocSumm, "createCGImage", "fromRect"); + addInstMethSummary("CIContext", CFAllocSumm, + "createCGImage", "fromRect", nullptr); addInstMethSummary("CIContext", CFAllocSumm, "createCGImage", "fromRect", - "format", "colorSpace"); - addInstMethSummary("CIContext", CFAllocSumm, "createCGLayerWithSize", "info"); + "format", "colorSpace", nullptr); + addInstMethSummary("CIContext", CFAllocSumm, "createCGLayerWithSize", "info", + nullptr); } //===----------------------------------------------------------------------===// @@ -1788,7 +1743,8 @@ namespace { //===---------===// // Bug Reports. // //===---------===// - class CFRefReportVisitor : public BugReporterVisitor { + + class CFRefReportVisitor : public BugReporterVisitorImpl<CFRefReportVisitor> { protected: SymbolRef Sym; const SummaryLogTy &SummaryLog; @@ -1804,12 +1760,12 @@ namespace { ID.AddPointer(Sym); } - std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N, - const ExplodedNode *PrevN, - BugReporterContext &BRC, - BugReport &BR) override; + PathDiagnosticPiece *VisitNode(const ExplodedNode *N, + const ExplodedNode *PrevN, + BugReporterContext &BRC, + BugReport &BR) override; - std::shared_ptr<PathDiagnosticPiece> getEndPath(BugReporterContext &BRC, + std::unique_ptr<PathDiagnosticPiece> getEndPath(BugReporterContext &BRC, const ExplodedNode *N, BugReport &BR) override; }; @@ -1820,9 +1776,18 @@ namespace { const SummaryLogTy &log) : CFRefReportVisitor(sym, GCEnabled, log) {} - std::shared_ptr<PathDiagnosticPiece> getEndPath(BugReporterContext &BRC, + std::unique_ptr<PathDiagnosticPiece> getEndPath(BugReporterContext &BRC, const ExplodedNode *N, BugReport &BR) override; + + std::unique_ptr<BugReporterVisitor> clone() const override { + // The curiously-recurring template pattern only works for one level of + // subclassing. Rather than make a new template base for + // CFRefReportVisitor, we simply override clone() to do the right thing. + // This could be trouble someday if BugReporterVisitorImpl is ever + // used for something else besides a convenient implementation of clone(). + return llvm::make_unique<CFRefLeakReportVisitor>(*this); + } }; class CFRefReport : public BugReport { @@ -1856,15 +1821,6 @@ namespace { class CFRefLeakReport : public CFRefReport { const MemRegion* AllocBinding; - const Stmt *AllocStmt; - - // Finds the function declaration where a leak warning for the parameter 'sym' should be raised. - void deriveParamLocation(CheckerContext &Ctx, SymbolRef sym); - // Finds the location where a leak warning for 'sym' should be raised. - void deriveAllocLocation(CheckerContext &Ctx, SymbolRef sym); - // Produces description of a leak warning which is printed on the console. - void createDescription(CheckerContext &Ctx, bool GCEnabled, bool IncludeAllocationLine); - public: CFRefLeakReport(CFRefBug &D, const LangOptions &LOpts, bool GCEnabled, const SummaryLogTy &Log, ExplodedNode *n, SymbolRef sym, @@ -1920,14 +1876,6 @@ static bool isNumericLiteralExpression(const Expr *E) { isa<CXXBoolLiteralExpr>(E); } -static Optional<std::string> describeRegion(const MemRegion *MR) { - if (const auto *VR = dyn_cast_or_null<VarRegion>(MR)) - return std::string(VR->getDecl()->getName()); - // Once we support more storage locations for bindings, - // this would need to be improved. - return None; -} - /// Returns true if this stack frame is for an Objective-C method that is a /// property getter or setter whose body has been synthesized by the analyzer. static bool isSynthesizedAccessor(const StackFrameContext *SFC) { @@ -1938,9 +1886,10 @@ static bool isSynthesizedAccessor(const StackFrameContext *SFC) { return SFC->getAnalysisDeclContext()->isBodyAutosynthesized(); } -std::shared_ptr<PathDiagnosticPiece> -CFRefReportVisitor::VisitNode(const ExplodedNode *N, const ExplodedNode *PrevN, - BugReporterContext &BRC, BugReport &BR) { +PathDiagnosticPiece *CFRefReportVisitor::VisitNode(const ExplodedNode *N, + const ExplodedNode *PrevN, + BugReporterContext &BRC, + BugReport &BR) { // FIXME: We will eventually need to handle non-statement-based events // (__attribute__((cleanup))). if (!N->getLocation().getAs<StmtPoint>()) @@ -1968,8 +1917,8 @@ CFRefReportVisitor::VisitNode(const ExplodedNode *N, const ExplodedNode *PrevN, const Stmt *S = N->getLocation().castAs<StmtPoint>().getStmt(); if (isa<ObjCIvarRefExpr>(S) && - isSynthesizedAccessor(LCtx->getStackFrame())) { - S = LCtx->getStackFrame()->getCallSite(); + isSynthesizedAccessor(LCtx->getCurrentStackFrame())) { + S = LCtx->getCurrentStackFrame()->getCallSite(); } if (isa<ObjCArrayLiteral>(S)) { @@ -2028,21 +1977,11 @@ CFRefReportVisitor::VisitNode(const ExplodedNode *N, const ExplodedNode *PrevN, } if (CurrV.getObjKind() == RetEffect::CF) { - os << " returns a Core Foundation object of type " - << Sym->getType().getAsString() << " with a "; - } else if (CurrV.getObjKind() == RetEffect::Generalized) { - os << " returns an object of type " << Sym->getType().getAsString() - << " with a "; - } else { + os << " returns a Core Foundation object with a "; + } + else { assert (CurrV.getObjKind() == RetEffect::ObjC); - QualType T = Sym->getType(); - if (!isa<ObjCObjectPointerType>(T)) { - os << " returns an Objective-C object with a "; - } else { - const ObjCObjectPointerType *PT = cast<ObjCObjectPointerType>(T); - os << " returns an instance of " - << PT->getPointeeType().getAsString() << " with a "; - } + os << " returns an Objective-C object with a "; } if (CurrV.isOwned()) { @@ -2062,7 +2001,7 @@ CFRefReportVisitor::VisitNode(const ExplodedNode *N, const ExplodedNode *PrevN, PathDiagnosticLocation Pos(S, BRC.getSourceManager(), N->getLocationContext()); - return std::make_shared<PathDiagnosticEventPiece>(Pos, os.str()); + return new PathDiagnosticEventPiece(Pos, os.str()); } // Gather up the effects that were performed on the object at this @@ -2239,7 +2178,7 @@ CFRefReportVisitor::VisitNode(const ExplodedNode *N, const ExplodedNode *PrevN, const Stmt *S = N->getLocation().castAs<StmtPoint>().getStmt(); PathDiagnosticLocation Pos(S, BRC.getSourceManager(), N->getLocationContext()); - auto P = std::make_shared<PathDiagnosticEventPiece>(Pos, os.str()); + PathDiagnosticPiece *P = new PathDiagnosticEventPiece(Pos, os.str()); // Add the range by scanning the children of the statement for any bindings // to Sym. @@ -2250,7 +2189,7 @@ CFRefReportVisitor::VisitNode(const ExplodedNode *N, const ExplodedNode *PrevN, break; } - return std::move(P); + return P; } namespace { @@ -2297,7 +2236,7 @@ GetAllocationSite(ProgramStateManager& StateMgr, const ExplodedNode *N, const VarRegion *VR = R->getBaseRegion()->getAs<VarRegion>(); // Do not show local variables belonging to a function other than // where the error is reported. - if (!VR || VR->getStackFrame() == LeakContext->getStackFrame()) + if (!VR || VR->getStackFrame() == LeakContext->getCurrentStackFrame()) FirstBinding = R; } @@ -2355,14 +2294,14 @@ GetAllocationSite(ProgramStateManager& StateMgr, const ExplodedNode *N, InterestingMethodContext); } -std::shared_ptr<PathDiagnosticPiece> +std::unique_ptr<PathDiagnosticPiece> CFRefReportVisitor::getEndPath(BugReporterContext &BRC, const ExplodedNode *EndN, BugReport &BR) { BR.markInteresting(Sym); return BugReporterVisitor::getDefaultEndPath(BRC, EndN, BR); } -std::shared_ptr<PathDiagnosticPiece> +std::unique_ptr<PathDiagnosticPiece> CFRefLeakReportVisitor::getEndPath(BugReporterContext &BRC, const ExplodedNode *EndN, BugReport &BR) { @@ -2392,9 +2331,9 @@ CFRefLeakReportVisitor::getEndPath(BugReporterContext &BRC, os << "Object leaked: "; - Optional<std::string> RegionDescription = describeRegion(FirstBinding); - if (RegionDescription) { - os << "object allocated and stored into '" << *RegionDescription << '\''; + if (FirstBinding) { + os << "object allocated and stored into '" + << FirstBinding->getString() << '\''; } else os << "allocated object"; @@ -2418,15 +2357,10 @@ CFRefLeakReportVisitor::getEndPath(BugReporterContext &BRC, os << "that is annotated as NS_RETURNS_NOT_RETAINED"; else { if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { - if (BRC.getASTContext().getLangOpts().ObjCAutoRefCount) { - os << "managed by Automatic Reference Counting"; - } else { - os << "whose name ('" << MD->getSelector().getAsString() - << "') does not start with " - "'copy', 'mutableCopy', 'alloc' or 'new'." - " This violates the naming convention rules" - " given in the Memory Management Guide for Cocoa"; - } + os << "whose name ('" << MD->getSelector().getAsString() + << "') does not start with 'copy', 'mutableCopy', 'alloc' or 'new'." + " This violates the naming convention rules" + " given in the Memory Management Guide for Cocoa"; } else { const FunctionDecl *FD = cast<FunctionDecl>(D); @@ -2449,28 +2383,16 @@ CFRefLeakReportVisitor::getEndPath(BugReporterContext &BRC, os << " is not referenced later in this execution path and has a retain " "count of +" << RV->getCount(); - return std::make_shared<PathDiagnosticEventPiece>(L, os.str()); + return llvm::make_unique<PathDiagnosticEventPiece>(L, os.str()); } -void CFRefLeakReport::deriveParamLocation(CheckerContext &Ctx, SymbolRef sym) { - const SourceManager& SMgr = Ctx.getSourceManager(); - - if (!sym->getOriginRegion()) - return; - - auto *Region = dyn_cast<DeclRegion>(sym->getOriginRegion()); - if (Region) { - const Decl *PDecl = Region->getDecl(); - if (PDecl && isa<ParmVarDecl>(PDecl)) { - PathDiagnosticLocation ParamLocation = PathDiagnosticLocation::create(PDecl, SMgr); - Location = ParamLocation; - UniqueingLocation = ParamLocation; - UniqueingDecl = Ctx.getLocationContext()->getDecl(); - } - } -} +CFRefLeakReport::CFRefLeakReport(CFRefBug &D, const LangOptions &LOpts, + bool GCEnabled, const SummaryLogTy &Log, + ExplodedNode *n, SymbolRef sym, + CheckerContext &Ctx, + bool IncludeAllocationLine) + : CFRefReport(D, LOpts, GCEnabled, Log, n, sym, false) { -void CFRefLeakReport::deriveAllocLocation(CheckerContext &Ctx,SymbolRef sym) { // Most bug reports are cached at the location where they occurred. // With leaks, we want to unique them by the location where they were // allocated, and only report a single path. To do this, we need to find @@ -2494,12 +2416,13 @@ void CFRefLeakReport::deriveAllocLocation(CheckerContext &Ctx,SymbolRef sym) { // FIXME: This will crash the analyzer if an allocation comes from an // implicit call (ex: a destructor call). // (Currently there are no such allocations in Cocoa, though.) - AllocStmt = PathDiagnosticLocation::getStmt(AllocNode); - - if (!AllocStmt) { - AllocBinding = nullptr; - return; - } + const Stmt *AllocStmt = nullptr; + ProgramPoint P = AllocNode->getLocation(); + if (Optional<CallExitEnd> Exit = P.getAs<CallExitEnd>()) + AllocStmt = Exit->getCalleeContext()->getCallSite(); + else + AllocStmt = P.castAs<PostStmt>().getStmt(); + assert(AllocStmt && "Cannot find allocation statement"); PathDiagnosticLocation AllocLocation = PathDiagnosticLocation::createBegin(AllocStmt, SMgr, @@ -2510,11 +2433,8 @@ void CFRefLeakReport::deriveAllocLocation(CheckerContext &Ctx,SymbolRef sym) { // leaks should be uniqued on the allocation site. UniqueingLocation = AllocLocation; UniqueingDecl = AllocNode->getLocationContext()->getDecl(); -} -void CFRefLeakReport::createDescription(CheckerContext &Ctx, bool GCEnabled, - bool IncludeAllocationLine) { - assert(Location.isValid() && UniqueingDecl && UniqueingLocation.isValid()); + // Fill in the description of the bug. Description.clear(); llvm::raw_string_ostream os(Description); os << "Potential leak "; @@ -2522,28 +2442,13 @@ void CFRefLeakReport::createDescription(CheckerContext &Ctx, bool GCEnabled, os << "(when using garbage collection) "; os << "of an object"; - Optional<std::string> RegionDescription = describeRegion(AllocBinding); - if (RegionDescription) { - os << " stored into '" << *RegionDescription << '\''; + if (AllocBinding) { + os << " stored into '" << AllocBinding->getString() << '\''; if (IncludeAllocationLine) { FullSourceLoc SL(AllocStmt->getLocStart(), Ctx.getSourceManager()); os << " (allocated on line " << SL.getSpellingLineNumber() << ")"; } } -} - -CFRefLeakReport::CFRefLeakReport(CFRefBug &D, const LangOptions &LOpts, - bool GCEnabled, const SummaryLogTy &Log, - ExplodedNode *n, SymbolRef sym, - CheckerContext &Ctx, - bool IncludeAllocationLine) - : CFRefReport(D, LOpts, GCEnabled, Log, n, sym, false) { - - deriveAllocLocation(Ctx, sym); - if (!AllocBinding) - deriveParamLocation(Ctx, sym); - - createDescription(Ctx, GCEnabled, IncludeAllocationLine); addVisitor(llvm::make_unique<CFRefLeakReportVisitor>(sym, GCEnabled, Log)); } @@ -2557,7 +2462,6 @@ class RetainCountChecker : public Checker< check::Bind, check::DeadSymbols, check::EndAnalysis, - check::BeginFunction, check::EndFunction, check::PostStmt<BlockExpr>, check::PostStmt<CastExpr>, @@ -2733,17 +2637,19 @@ public: const InvalidatedSymbols *invalidated, ArrayRef<const MemRegion *> ExplicitRegions, ArrayRef<const MemRegion *> Regions, - const LocationContext* LCtx, const CallEvent *Call) const; + bool wantsRegionChangeUpdate(ProgramStateRef state) const { + return true; + } + void checkPreStmt(const ReturnStmt *S, CheckerContext &C) const; void checkReturnWithRetEffect(const ReturnStmt *S, CheckerContext &C, ExplodedNode *Pred, RetEffect RE, RefVal X, SymbolRef Sym, ProgramStateRef state) const; void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const; - void checkBeginFunction(CheckerContext &C) const; - void checkEndFunction(const ReturnStmt *RS, CheckerContext &C) const; + void checkEndFunction(CheckerContext &C) const; ProgramStateRef updateSymbol(ProgramStateRef state, SymbolRef sym, RefVal V, ArgEffect E, RefVal::Kind &hasErr, @@ -2777,7 +2683,7 @@ namespace { class StopTrackingCallback final : public SymbolVisitor { ProgramStateRef state; public: - StopTrackingCallback(ProgramStateRef st) : state(std::move(st)) {} + StopTrackingCallback(ProgramStateRef st) : state(st) {} ProgramStateRef getState() const { return state; } bool VisitSymbol(SymbolRef sym) override { @@ -2800,7 +2706,9 @@ void RetainCountChecker::checkPostStmt(const BlockExpr *BE, return; ProgramStateRef state = C.getState(); - auto *R = cast<BlockDataRegion>(C.getSVal(BE).getAsRegion()); + const BlockDataRegion *R = + cast<BlockDataRegion>(state->getSVal(BE, + C.getLocationContext()).getAsRegion()); BlockDataRegion::referenced_vars_iterator I = R->referenced_vars_begin(), E = R->referenced_vars_end(); @@ -2850,7 +2758,7 @@ void RetainCountChecker::checkPostStmt(const CastExpr *CE, } ProgramStateRef state = C.getState(); - SymbolRef Sym = C.getSVal(CE).getAsLocSymbol(); + SymbolRef Sym = state->getSVal(CE, C.getLocationContext()).getAsLocSymbol(); if (!Sym) return; const RefVal* T = getRefBinding(state, Sym); @@ -2873,7 +2781,7 @@ void RetainCountChecker::processObjCLiterals(CheckerContext &C, ProgramStateRef state = C.getState(); const ExplodedNode *pred = C.getPredecessor(); for (const Stmt *Child : Ex->children()) { - SVal V = pred->getSVal(Child); + SVal V = state->getSVal(Child, pred->getLocationContext()); if (SymbolRef sym = V.getAsSymbol()) if (const RefVal* T = getRefBinding(state, sym)) { RefVal::Kind hasErr = (RefVal::Kind) 0; @@ -2912,9 +2820,10 @@ void RetainCountChecker::checkPostStmt(const ObjCDictionaryLiteral *DL, void RetainCountChecker::checkPostStmt(const ObjCBoxedExpr *Ex, CheckerContext &C) const { const ExplodedNode *Pred = C.getPredecessor(); + const LocationContext *LCtx = Pred->getLocationContext(); ProgramStateRef State = Pred->getState(); - if (SymbolRef Sym = Pred->getSVal(Ex).getAsSymbol()) { + if (SymbolRef Sym = State->getSVal(Ex, LCtx).getAsSymbol()) { QualType ResultTy = Ex->getType(); State = setRefBinding(State, Sym, RefVal::makeNotOwned(RetEffect::ObjC, ResultTy)); @@ -2923,6 +2832,14 @@ void RetainCountChecker::checkPostStmt(const ObjCBoxedExpr *Ex, C.addTransition(State); } +static bool wasLoadedFromIvar(SymbolRef Sym) { + if (auto DerivedVal = dyn_cast<SymbolDerived>(Sym)) + return isa<ObjCIvarRegion>(DerivedVal->getRegion()); + if (auto RegionVal = dyn_cast<SymbolRegionValue>(Sym)) + return isa<ObjCIvarRegion>(RegionVal->getRegion()); + return false; +} + void RetainCountChecker::checkPostStmt(const ObjCIvarRefExpr *IRE, CheckerContext &C) const { Optional<Loc> IVarLoc = C.getSVal(IRE).getAs<Loc>(); @@ -2931,7 +2848,7 @@ void RetainCountChecker::checkPostStmt(const ObjCIvarRefExpr *IRE, ProgramStateRef State = C.getState(); SymbolRef Sym = State->getSVal(*IVarLoc).getAsSymbol(); - if (!Sym || !dyn_cast_or_null<ObjCIvarRegion>(Sym->getOriginRegion())) + if (!Sym || !wasLoadedFromIvar(Sym)) return; // Accessing an ivar directly is unusual. If we've done that, be more @@ -3161,6 +3078,7 @@ void RetainCountChecker::checkSummary(const RetainSummary &Summ, // No work necessary. break; + case RetEffect::OwnedAllocatedSymbol: case RetEffect::OwnedSymbol: { SymbolRef Sym = CallOrMsg.getReturnValue().getAsSymbol(); if (!Sym) @@ -3455,29 +3373,20 @@ bool RetainCountChecker::evalCall(const CallExpr *CE, CheckerContext &C) const { // See if it's one of the specific functions we know how to eval. bool canEval = false; - // See if the function has 'rc_ownership_trusted_implementation' - // annotate attribute. If it does, we will not inline it. - bool hasTrustedImplementationAnnotation = false; QualType ResultTy = CE->getCallReturnType(C.getASTContext()); if (ResultTy->isObjCIdType()) { // Handle: id NSMakeCollectable(CFTypeRef) canEval = II->isStr("NSMakeCollectable"); } else if (ResultTy->isPointerType()) { - // Handle: (CF|CG|CV)Retain + // Handle: (CF|CG)Retain // CFAutorelease // CFMakeCollectable // It's okay to be a little sloppy here (CGMakeCollectable doesn't exist). if (cocoa::isRefType(ResultTy, "CF", FName) || - cocoa::isRefType(ResultTy, "CG", FName) || - cocoa::isRefType(ResultTy, "CV", FName)) { + cocoa::isRefType(ResultTy, "CG", FName)) { canEval = isRetain(FD, FName) || isAutorelease(FD, FName) || isMakeCollectable(FD, FName); - } else { - if (FD->getDefinition()) { - canEval = isTrustedReferenceCountImplementation(FD->getDefinition()); - hasTrustedImplementationAnnotation = canEval; - } } } @@ -3487,11 +3396,8 @@ bool RetainCountChecker::evalCall(const CallExpr *CE, CheckerContext &C) const { // Bind the return value. const LocationContext *LCtx = C.getLocationContext(); SVal RetVal = state->getSVal(CE->getArg(0), LCtx); - if (RetVal.isUnknown() || - (hasTrustedImplementationAnnotation && !ResultTy.isNull())) { - // If the receiver is unknown or the function has - // 'rc_ownership_trusted_implementation' annotate attribute, conjure a - // return value. + if (RetVal.isUnknown()) { + // If the receiver is unknown, conjure a return value. SValBuilder &SVB = C.getSValBuilder(); RetVal = SVB.conjureSymbolVal(nullptr, CE, LCtx, ResultTy, C.blockCount()); } @@ -3507,9 +3413,8 @@ bool RetainCountChecker::evalCall(const CallExpr *CE, CheckerContext &C) const { Binding = getRefBinding(state, Sym); // Invalidate the argument region. - state = state->invalidateRegions( - ArgRegion, CE, C.blockCount(), LCtx, - /*CausesPointerEscape*/ hasTrustedImplementationAnnotation); + state = state->invalidateRegions(ArgRegion, CE, C.blockCount(), LCtx, + /*CausesPointerEscape*/ false); // Restore the refcount status of the argument. if (Binding) @@ -3730,7 +3635,7 @@ void RetainCountChecker::checkBind(SVal loc, SVal val, const Stmt *S, // same state. SVal StoredVal = state->getSVal(regionLoc->getRegion()); if (StoredVal != val) - escapes = (state == (state->bindLoc(*regionLoc, val, C.getLocationContext()))); + escapes = (state == (state->bindLoc(*regionLoc, val))); } if (!escapes) { // Case 4: We do not currently model what happens when a symbol is @@ -3797,11 +3702,10 @@ ProgramStateRef RetainCountChecker::evalAssume(ProgramStateRef state, ProgramStateRef RetainCountChecker::checkRegionChanges(ProgramStateRef state, - const InvalidatedSymbols *invalidated, - ArrayRef<const MemRegion *> ExplicitRegions, - ArrayRef<const MemRegion *> Regions, - const LocationContext *LCtx, - const CallEvent *Call) const { + const InvalidatedSymbols *invalidated, + ArrayRef<const MemRegion *> ExplicitRegions, + ArrayRef<const MemRegion *> Regions, + const CallEvent *Call) const { if (!invalidated) return state; @@ -3961,38 +3865,7 @@ RetainCountChecker::processLeaks(ProgramStateRef state, return N; } -void RetainCountChecker::checkBeginFunction(CheckerContext &Ctx) const { - if (!Ctx.inTopFrame()) - return; - - const LocationContext *LCtx = Ctx.getLocationContext(); - const FunctionDecl *FD = dyn_cast<FunctionDecl>(LCtx->getDecl()); - - if (!FD || isTrustedReferenceCountImplementation(FD)) - return; - - ProgramStateRef state = Ctx.getState(); - - const RetainSummary *FunctionSummary = getSummaryManager(Ctx).getFunctionSummary(FD); - ArgEffects CalleeSideArgEffects = FunctionSummary->getArgEffects(); - - for (unsigned idx = 0, e = FD->getNumParams(); idx != e; ++idx) { - const ParmVarDecl *Param = FD->getParamDecl(idx); - SymbolRef Sym = state->getSVal(state->getRegion(Param, LCtx)).getAsSymbol(); - - QualType Ty = Param->getType(); - const ArgEffect *AE = CalleeSideArgEffects.lookup(idx); - if (AE && *AE == DecRef && isGeneralizedObjectRef(Ty)) - state = setRefBinding(state, Sym, RefVal::makeOwned(RetEffect::ObjKind::Generalized, Ty)); - else if (isGeneralizedObjectRef(Ty)) - state = setRefBinding(state, Sym, RefVal::makeNotOwned(RetEffect::ObjKind::Generalized, Ty)); - } - - Ctx.addTransition(state); -} - -void RetainCountChecker::checkEndFunction(const ReturnStmt *RS, - CheckerContext &Ctx) const { +void RetainCountChecker::checkEndFunction(CheckerContext &Ctx) const { ProgramStateRef state = Ctx.getState(); RefBindingsTy B = state->get<RefBindings>(); ExplodedNode *Pred = Ctx.getPredecessor(); @@ -4000,7 +3873,7 @@ void RetainCountChecker::checkEndFunction(const ReturnStmt *RS, // Don't process anything within synthesized bodies. const LocationContext *LCtx = Pred->getLocationContext(); if (LCtx->getAnalysisDeclContext()->isBodyAutosynthesized()) { - assert(!LCtx->inTopFrame()); + assert(LCtx->getParent()); return; } diff --git a/gnu/llvm/tools/clang/lib/StaticAnalyzer/Checkers/SelectorExtras.h b/gnu/llvm/tools/clang/lib/StaticAnalyzer/Checkers/SelectorExtras.h index b11d070c629..41f70d7d5b6 100644 --- a/gnu/llvm/tools/clang/lib/StaticAnalyzer/Checkers/SelectorExtras.h +++ b/gnu/llvm/tools/clang/lib/StaticAnalyzer/Checkers/SelectorExtras.h @@ -11,26 +11,48 @@ #define LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_SELECTOREXTRAS_H #include "clang/AST/ASTContext.h" +#include <cstdarg> namespace clang { namespace ento { -template <typename... IdentifierInfos> -static inline Selector getKeywordSelector(ASTContext &Ctx, - IdentifierInfos *... IIs) { - static_assert(sizeof...(IdentifierInfos), - "keyword selectors must have at least one argument"); - SmallVector<IdentifierInfo *, 10> II({&Ctx.Idents.get(IIs)...}); +static inline Selector getKeywordSelectorImpl(ASTContext &Ctx, + const char *First, + va_list argp) { + SmallVector<IdentifierInfo*, 10> II; + II.push_back(&Ctx.Idents.get(First)); + + while (const char *s = va_arg(argp, const char *)) + II.push_back(&Ctx.Idents.get(s)); return Ctx.Selectors.getSelector(II.size(), &II[0]); } -template <typename... IdentifierInfos> +static inline Selector getKeywordSelector(ASTContext &Ctx, va_list argp) { + const char *First = va_arg(argp, const char *); + assert(First && "keyword selectors must have at least one argument"); + return getKeywordSelectorImpl(Ctx, First, argp); +} + +LLVM_END_WITH_NULL +static inline Selector getKeywordSelector(ASTContext &Ctx, + const char *First, ...) { + va_list argp; + va_start(argp, First); + Selector result = getKeywordSelectorImpl(Ctx, First, argp); + va_end(argp); + return result; +} + +LLVM_END_WITH_NULL static inline void lazyInitKeywordSelector(Selector &Sel, ASTContext &Ctx, - IdentifierInfos *... IIs) { + const char *First, ...) { if (!Sel.isNull()) return; - Sel = getKeywordSelector(Ctx, IIs...); + va_list argp; + va_start(argp, First); + Sel = getKeywordSelectorImpl(Ctx, First, argp); + va_end(argp); } static inline void lazyInitNullarySelector(Selector &Sel, ASTContext &Ctx, diff --git a/gnu/llvm/tools/clang/lib/StaticAnalyzer/Core/CheckerRegistry.cpp b/gnu/llvm/tools/clang/lib/StaticAnalyzer/Core/CheckerRegistry.cpp index 645845ec218..a15e1573e22 100644 --- a/gnu/llvm/tools/clang/lib/StaticAnalyzer/Core/CheckerRegistry.cpp +++ b/gnu/llvm/tools/clang/lib/StaticAnalyzer/Core/CheckerRegistry.cpp @@ -1,4 +1,4 @@ -//===- CheckerRegistry.cpp - Maintains all available checkers -------------===// +//===--- CheckerRegistry.cpp - Maintains all available checkers -*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -9,26 +9,18 @@ #include "clang/StaticAnalyzer/Core/CheckerRegistry.h" #include "clang/Basic/Diagnostic.h" -#include "clang/Basic/LLVM.h" #include "clang/Frontend/FrontendDiagnostic.h" -#include "clang/StaticAnalyzer/Core/CheckerManager.h" #include "clang/StaticAnalyzer/Core/CheckerOptInfo.h" #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h" -#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SetVector.h" -#include "llvm/ADT/StringMap.h" -#include "llvm/ADT/StringRef.h" #include "llvm/Support/raw_ostream.h" -#include <algorithm> -#include <cstddef> -#include <tuple> using namespace clang; using namespace ento; static const char PackageSeparator = '.'; +typedef llvm::SetVector<const CheckerRegistry::CheckerInfo *> CheckerInfoSet; -using CheckerInfoSet = llvm::SetVector<const CheckerRegistry::CheckerInfo *>; static bool checkerNameLT(const CheckerRegistry::CheckerInfo &a, const CheckerRegistry::CheckerInfo &b) { @@ -57,11 +49,12 @@ static void collectCheckers(const CheckerRegistry::CheckerInfoList &checkers, CheckerOptInfo &opt, CheckerInfoSet &collected) { // Use a binary search to find the possible start of the package. CheckerRegistry::CheckerInfo packageInfo(nullptr, opt.getName(), ""); - auto end = checkers.cend(); - auto i = std::lower_bound(checkers.cbegin(), end, packageInfo, checkerNameLT); + CheckerRegistry::CheckerInfoList::const_iterator e = checkers.end(); + CheckerRegistry::CheckerInfoList::const_iterator i = + std::lower_bound(checkers.begin(), e, packageInfo, checkerNameLT); // If we didn't even find a possible package, give up. - if (i == end) + if (i == e) return; // If what we found doesn't actually start the package, give up. @@ -80,11 +73,12 @@ static void collectCheckers(const CheckerRegistry::CheckerInfoList &checkers, size = packageSize->getValue(); // Step through all the checkers in the package. - for (auto checkEnd = i+size; i != checkEnd; ++i) + for (e = i+size; i != e; ++i) { if (opt.isEnabled()) collected.insert(&*i); else collected.remove(&*i); + } } void CheckerRegistry::addChecker(InitializationFunction fn, StringRef name, @@ -103,38 +97,42 @@ void CheckerRegistry::addChecker(InitializationFunction fn, StringRef name, void CheckerRegistry::initializeManager(CheckerManager &checkerMgr, SmallVectorImpl<CheckerOptInfo> &opts) const { // Sort checkers for efficient collection. - llvm::sort(Checkers.begin(), Checkers.end(), checkerNameLT); + std::sort(Checkers.begin(), Checkers.end(), checkerNameLT); // Collect checkers enabled by the options. CheckerInfoSet enabledCheckers; - for (auto &i : opts) - collectCheckers(Checkers, Packages, i, enabledCheckers); + for (SmallVectorImpl<CheckerOptInfo>::iterator + i = opts.begin(), e = opts.end(); i != e; ++i) { + collectCheckers(Checkers, Packages, *i, enabledCheckers); + } // Initialize the CheckerManager with all enabled checkers. - for (const auto *i :enabledCheckers) { - checkerMgr.setCurrentCheckName(CheckName(i->FullName)); - i->Initialize(checkerMgr); + for (CheckerInfoSet::iterator + i = enabledCheckers.begin(), e = enabledCheckers.end(); i != e; ++i) { + checkerMgr.setCurrentCheckName(CheckName((*i)->FullName)); + (*i)->Initialize(checkerMgr); } } void CheckerRegistry::validateCheckerOptions(const AnalyzerOptions &opts, DiagnosticsEngine &diags) const { - for (const auto &config : opts.Config) { + for (auto &config : opts.Config) { size_t pos = config.getKey().find(':'); if (pos == StringRef::npos) continue; bool hasChecker = false; StringRef checkerName = config.getKey().substr(0, pos); - for (const auto &checker : Checkers) { + for (auto &checker : Checkers) { if (checker.FullName.startswith(checkerName) && (checker.FullName.size() == pos || checker.FullName[pos] == '.')) { hasChecker = true; break; } } - if (!hasChecker) + if (!hasChecker) { diags.Report(diag::err_unknown_analyzer_checker) << checkerName; + } } } @@ -143,7 +141,7 @@ void CheckerRegistry::printHelp(raw_ostream &out, // FIXME: Alphabetical sort puts 'experimental' in the middle. // Would it be better to name it '~experimental' or something else // that's ASCIIbetically last? - llvm::sort(Checkers.begin(), Checkers.end(), checkerNameLT); + std::sort(Checkers.begin(), Checkers.end(), checkerNameLT); // FIXME: Print available packages. @@ -151,40 +149,29 @@ void CheckerRegistry::printHelp(raw_ostream &out, // Find the maximum option length. size_t optionFieldWidth = 0; - for (const auto &i : Checkers) { + for (CheckerInfoList::const_iterator i = Checkers.begin(), e = Checkers.end(); + i != e; ++i) { // Limit the amount of padding we are willing to give up for alignment. // Package.Name Description [Hidden] - size_t nameLength = i.FullName.size(); + size_t nameLength = i->FullName.size(); if (nameLength <= maxNameChars) optionFieldWidth = std::max(optionFieldWidth, nameLength); } const size_t initialPad = 2; - for (const auto &i : Checkers) { - out.indent(initialPad) << i.FullName; + for (CheckerInfoList::const_iterator i = Checkers.begin(), e = Checkers.end(); + i != e; ++i) { + out.indent(initialPad) << i->FullName; - int pad = optionFieldWidth - i.FullName.size(); + int pad = optionFieldWidth - i->FullName.size(); // Break on long option names. if (pad < 0) { out << '\n'; pad = optionFieldWidth + initialPad; } - out.indent(pad + 2) << i.Desc; + out.indent(pad + 2) << i->Desc; out << '\n'; } } - -void CheckerRegistry::printList( - raw_ostream &out, SmallVectorImpl<CheckerOptInfo> &opts) const { - llvm::sort(Checkers.begin(), Checkers.end(), checkerNameLT); - - // Collect checkers enabled by the options. - CheckerInfoSet enabledCheckers; - for (auto &i : opts) - collectCheckers(Checkers, Packages, i, enabledCheckers); - - for (const auto *i : enabledCheckers) - out << i->FullName << '\n'; -} diff --git a/gnu/llvm/tools/clang/unittests/Basic/VirtualFileSystemTest.cpp b/gnu/llvm/tools/clang/unittests/Basic/VirtualFileSystemTest.cpp index c795be07acf..7abc549292e 100644 --- a/gnu/llvm/tools/clang/unittests/Basic/VirtualFileSystemTest.cpp +++ b/gnu/llvm/tools/clang/unittests/Basic/VirtualFileSystemTest.cpp @@ -8,11 +8,9 @@ //===----------------------------------------------------------------------===// #include "clang/Basic/VirtualFileSystem.h" -#include "llvm/ADT/Triple.h" -#include "llvm/Config/llvm-config.h" #include "llvm/Support/Errc.h" -#include "llvm/Support/Host.h" #include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/Path.h" #include "llvm/Support/SourceMgr.h" #include "gtest/gtest.h" #include <map> @@ -31,7 +29,7 @@ struct DummyFile : public vfs::File { bool IsVolatile) override { llvm_unreachable("unimplemented"); } - std::error_code close() override { return std::error_code(); } + virtual std::error_code close() override { return std::error_code(); } }; class DummyFileSystem : public vfs::FileSystem { @@ -67,21 +65,6 @@ public: std::error_code setCurrentWorkingDirectory(const Twine &Path) override { return std::error_code(); } - // Map any symlink to "/symlink". - std::error_code getRealPath(const Twine &Path, - SmallVectorImpl<char> &Output) const override { - auto I = FilesAndDirs.find(Path.str()); - if (I == FilesAndDirs.end()) - return make_error_code(llvm::errc::no_such_file_or_directory); - if (I->second.isSymlink()) { - Output.clear(); - Twine("/symlink").toVector(Output); - return std::error_code(); - } - Output.clear(); - Path.toVector(Output); - return std::error_code(); - } struct DirIterImpl : public clang::vfs::detail::DirIterImpl { std::map<std::string, vfs::Status> &FilesAndDirs; @@ -131,23 +114,20 @@ public: } void addRegularFile(StringRef Path, sys::fs::perms Perms = sys::fs::all_all) { - vfs::Status S(Path, UniqueID(FSID, FileID++), - std::chrono::system_clock::now(), 0, 0, 1024, - sys::fs::file_type::regular_file, Perms); + vfs::Status S(Path, UniqueID(FSID, FileID++), sys::TimeValue::now(), 0, 0, + 1024, sys::fs::file_type::regular_file, Perms); addEntry(Path, S); } void addDirectory(StringRef Path, sys::fs::perms Perms = sys::fs::all_all) { - vfs::Status S(Path, UniqueID(FSID, FileID++), - std::chrono::system_clock::now(), 0, 0, 0, - sys::fs::file_type::directory_file, Perms); + vfs::Status S(Path, UniqueID(FSID, FileID++), sys::TimeValue::now(), 0, 0, + 0, sys::fs::file_type::directory_file, Perms); addEntry(Path, S); } void addSymlink(StringRef Path) { - vfs::Status S(Path, UniqueID(FSID, FileID++), - std::chrono::system_clock::now(), 0, 0, 0, - sys::fs::file_type::symlink_file, sys::fs::all_all); + vfs::Status S(Path, UniqueID(FSID, FileID++), sys::TimeValue::now(), 0, 0, + 0, sys::fs::file_type::symlink_file, sys::fs::all_all); addEntry(Path, S); } }; @@ -211,35 +191,6 @@ TEST(VirtualFileSystemTest, BaseOnlyOverlay) { EXPECT_TRUE(Status->equivalent(*Status2)); } -TEST(VirtualFileSystemTest, GetRealPathInOverlay) { - IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); - Lower->addRegularFile("/foo"); - Lower->addSymlink("/lower_link"); - IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem()); - - IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( - new vfs::OverlayFileSystem(Lower)); - O->pushOverlay(Upper); - - // Regular file. - SmallString<16> RealPath; - EXPECT_FALSE(O->getRealPath("/foo", RealPath)); - EXPECT_EQ(RealPath.str(), "/foo"); - - // Expect no error getting real path for symlink in lower overlay. - EXPECT_FALSE(O->getRealPath("/lower_link", RealPath)); - EXPECT_EQ(RealPath.str(), "/symlink"); - - // Try a non-existing link. - EXPECT_EQ(O->getRealPath("/upper_link", RealPath), - errc::no_such_file_or_directory); - - // Add a new symlink in upper. - Upper->addSymlink("/upper_link"); - EXPECT_FALSE(O->getRealPath("/upper_link", RealPath)); - EXPECT_EQ(RealPath.str(), "/symlink"); -} - TEST(VirtualFileSystemTest, OverlayFiles) { IntrusiveRefCntPtr<DummyFileSystem> Base(new DummyFileSystem()); IntrusiveRefCntPtr<DummyFileSystem> Middle(new DummyFileSystem()); @@ -345,26 +296,8 @@ struct ScopedDir { EXPECT_FALSE(EC); } ~ScopedDir() { - if (Path != "") { - EXPECT_FALSE(llvm::sys::fs::remove(Path.str())); - } - } - operator StringRef() { return Path.str(); } -}; - -struct ScopedLink { - SmallString<128> Path; - ScopedLink(const Twine &To, const Twine &From) { - Path = From.str(); - std::error_code EC = sys::fs::create_link(To, From); - if (EC) - Path = ""; - EXPECT_FALSE(EC); - } - ~ScopedLink() { - if (Path != "") { + if (Path != "") EXPECT_FALSE(llvm::sys::fs::remove(Path.str())); - } } operator StringRef() { return Path.str(); } }; @@ -397,42 +330,6 @@ TEST(VirtualFileSystemTest, BasicRealFSIteration) { EXPECT_EQ(vfs::directory_iterator(), I); } -#ifdef LLVM_ON_UNIX -TEST(VirtualFileSystemTest, BrokenSymlinkRealFSIteration) { - ScopedDir TestDirectory("virtual-file-system-test", /*Unique*/ true); - IntrusiveRefCntPtr<vfs::FileSystem> FS = vfs::getRealFileSystem(); - - ScopedLink _a("no_such_file", TestDirectory + "/a"); - ScopedDir _b(TestDirectory + "/b"); - ScopedLink _c("no_such_file", TestDirectory + "/c"); - - std::error_code EC; - for (vfs::directory_iterator I = FS->dir_begin(Twine(TestDirectory), EC), E; - I != E; I.increment(EC)) { - // Skip broken symlinks. - auto EC2 = std::make_error_code(std::errc::no_such_file_or_directory); - if (EC == EC2) { - EC.clear(); - continue; - } - // For bot debugging. - if (EC) { - outs() << "Error code found:\n" - << "EC value: " << EC.value() << "\n" - << "EC category: " << EC.category().name() - << "EC message: " << EC.message() << "\n"; - - outs() << "Error code tested for:\n" - << "EC value: " << EC2.value() << "\n" - << "EC category: " << EC2.category().name() - << "EC message: " << EC2.message() << "\n"; - } - ASSERT_FALSE(EC); - EXPECT_TRUE(I->getName() == _b); - } -} -#endif - TEST(VirtualFileSystemTest, BasicRealFSRecursiveIteration) { ScopedDir TestDirectory("virtual-file-system-test", /*Unique*/true); IntrusiveRefCntPtr<vfs::FileSystem> FS = vfs::getRealFileSystem(); @@ -451,6 +348,7 @@ TEST(VirtualFileSystemTest, BasicRealFSRecursiveIteration) { ASSERT_FALSE(EC); ASSERT_NE(vfs::recursive_directory_iterator(), I); + std::vector<std::string> Contents; for (auto E = vfs::recursive_directory_iterator(); !EC && I != E; I.increment(EC)) { @@ -472,82 +370,17 @@ TEST(VirtualFileSystemTest, BasicRealFSRecursiveIteration) { EXPECT_EQ(1, Counts[3]); // d } -#ifdef LLVM_ON_UNIX -TEST(VirtualFileSystemTest, BrokenSymlinkRealFSRecursiveIteration) { - ScopedDir TestDirectory("virtual-file-system-test", /*Unique*/ true); - IntrusiveRefCntPtr<vfs::FileSystem> FS = vfs::getRealFileSystem(); - - ScopedLink _a("no_such_file", TestDirectory + "/a"); - ScopedDir _b(TestDirectory + "/b"); - ScopedLink _ba("no_such_file", TestDirectory + "/b/a"); - ScopedDir _bb(TestDirectory + "/b/b"); - ScopedLink _bc("no_such_file", TestDirectory + "/b/c"); - ScopedLink _c("no_such_file", TestDirectory + "/c"); - ScopedDir _d(TestDirectory + "/d"); - ScopedDir _dd(TestDirectory + "/d/d"); - ScopedDir _ddd(TestDirectory + "/d/d/d"); - ScopedLink _e("no_such_file", TestDirectory + "/e"); - - std::vector<StringRef> ExpectedBrokenSymlinks = {_a, _ba, _bc, _c, _e}; - std::vector<StringRef> ExpectedNonBrokenSymlinks = {_b, _bb, _d, _dd, _ddd}; - std::vector<std::string> VisitedBrokenSymlinks; - std::vector<std::string> VisitedNonBrokenSymlinks; - std::error_code EC; - for (vfs::recursive_directory_iterator I(*FS, Twine(TestDirectory), EC), E; - I != E; I.increment(EC)) { - auto EC2 = std::make_error_code(std::errc::no_such_file_or_directory); - if (EC == EC2) { - VisitedBrokenSymlinks.push_back(I->getName()); - continue; - } - // For bot debugging. - if (EC) { - outs() << "Error code found:\n" - << "EC value: " << EC.value() << "\n" - << "EC category: " << EC.category().name() - << "EC message: " << EC.message() << "\n"; - - outs() << "Error code tested for:\n" - << "EC value: " << EC2.value() << "\n" - << "EC category: " << EC2.category().name() - << "EC message: " << EC2.message() << "\n"; - } - ASSERT_FALSE(EC); - VisitedNonBrokenSymlinks.push_back(I->getName()); - } - - // Check visited file names. - std::sort(VisitedBrokenSymlinks.begin(), VisitedBrokenSymlinks.end()); - std::sort(VisitedNonBrokenSymlinks.begin(), VisitedNonBrokenSymlinks.end()); - EXPECT_EQ(ExpectedBrokenSymlinks.size(), VisitedBrokenSymlinks.size()); - EXPECT_TRUE(std::equal(VisitedBrokenSymlinks.begin(), - VisitedBrokenSymlinks.end(), - ExpectedBrokenSymlinks.begin())); - EXPECT_EQ(ExpectedNonBrokenSymlinks.size(), VisitedNonBrokenSymlinks.size()); - EXPECT_TRUE(std::equal(VisitedNonBrokenSymlinks.begin(), - VisitedNonBrokenSymlinks.end(), - ExpectedNonBrokenSymlinks.begin())); -} -#endif - template <typename DirIter> -static void checkContents(DirIter I, ArrayRef<StringRef> ExpectedOut) { +static void checkContents(DirIter I, ArrayRef<StringRef> Expected) { std::error_code EC; - SmallVector<StringRef, 4> Expected(ExpectedOut.begin(), ExpectedOut.end()); - SmallVector<std::string, 4> InputToCheck; - - // Do not rely on iteration order to check for contents, sort both - // content vectors before comparison. - for (DirIter E; !EC && I != E; I.increment(EC)) - InputToCheck.push_back(I->getName()); - - llvm::sort(InputToCheck.begin(), InputToCheck.end()); - llvm::sort(Expected.begin(), Expected.end()); - EXPECT_EQ(InputToCheck.size(), Expected.size()); - - unsigned LastElt = std::min(InputToCheck.size(), Expected.size()); - for (unsigned Idx = 0; Idx != LastElt; ++Idx) - EXPECT_EQ(StringRef(InputToCheck[Idx]), Expected[Idx]); + auto ExpectedIter = Expected.begin(), ExpectedEnd = Expected.end(); + for (DirIter E; + !EC && I != E && ExpectedIter != ExpectedEnd; + I.increment(EC), ++ExpectedIter) + EXPECT_EQ(*ExpectedIter, I->getName()); + + EXPECT_EQ(ExpectedEnd, ExpectedIter); + EXPECT_EQ(DirIter(), I); } TEST(VirtualFileSystemTest, OverlayIteration) { @@ -813,112 +646,6 @@ TEST_F(InMemoryFileSystemTest, WorkingDirectory) { NormalizedFS.getCurrentWorkingDirectory().get())); } -#if !defined(_WIN32) -TEST_F(InMemoryFileSystemTest, GetRealPath) { - SmallString<16> Path; - EXPECT_EQ(FS.getRealPath("b", Path), errc::operation_not_permitted); - - auto GetRealPath = [this](StringRef P) { - SmallString<16> Output; - auto EC = FS.getRealPath(P, Output); - EXPECT_FALSE(EC); - return Output.str().str(); - }; - - FS.setCurrentWorkingDirectory("a"); - EXPECT_EQ(GetRealPath("b"), "a/b"); - EXPECT_EQ(GetRealPath("../b"), "b"); - EXPECT_EQ(GetRealPath("b/./c"), "a/b/c"); - - FS.setCurrentWorkingDirectory("/a"); - EXPECT_EQ(GetRealPath("b"), "/a/b"); - EXPECT_EQ(GetRealPath("../b"), "/b"); - EXPECT_EQ(GetRealPath("b/./c"), "/a/b/c"); -} -#endif // _WIN32 - -TEST_F(InMemoryFileSystemTest, AddFileWithUser) { - FS.addFile("/a/b/c", 0, MemoryBuffer::getMemBuffer("abc"), 0xFEEDFACE); - auto Stat = FS.status("/a"); - ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString(); - ASSERT_TRUE(Stat->isDirectory()); - ASSERT_EQ(0xFEEDFACE, Stat->getUser()); - Stat = FS.status("/a/b"); - ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString(); - ASSERT_TRUE(Stat->isDirectory()); - ASSERT_EQ(0xFEEDFACE, Stat->getUser()); - Stat = FS.status("/a/b/c"); - ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString(); - ASSERT_TRUE(Stat->isRegularFile()); - ASSERT_EQ(sys::fs::perms::all_all, Stat->getPermissions()); - ASSERT_EQ(0xFEEDFACE, Stat->getUser()); -} - -TEST_F(InMemoryFileSystemTest, AddFileWithGroup) { - FS.addFile("/a/b/c", 0, MemoryBuffer::getMemBuffer("abc"), None, 0xDABBAD00); - auto Stat = FS.status("/a"); - ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString(); - ASSERT_TRUE(Stat->isDirectory()); - ASSERT_EQ(0xDABBAD00, Stat->getGroup()); - Stat = FS.status("/a/b"); - ASSERT_TRUE(Stat->isDirectory()); - ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString(); - ASSERT_EQ(0xDABBAD00, Stat->getGroup()); - Stat = FS.status("/a/b/c"); - ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString(); - ASSERT_TRUE(Stat->isRegularFile()); - ASSERT_EQ(sys::fs::perms::all_all, Stat->getPermissions()); - ASSERT_EQ(0xDABBAD00, Stat->getGroup()); -} - -TEST_F(InMemoryFileSystemTest, AddFileWithFileType) { - FS.addFile("/a/b/c", 0, MemoryBuffer::getMemBuffer("abc"), None, None, - sys::fs::file_type::socket_file); - auto Stat = FS.status("/a"); - ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString(); - ASSERT_TRUE(Stat->isDirectory()); - Stat = FS.status("/a/b"); - ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString(); - ASSERT_TRUE(Stat->isDirectory()); - Stat = FS.status("/a/b/c"); - ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString(); - ASSERT_EQ(sys::fs::file_type::socket_file, Stat->getType()); - ASSERT_EQ(sys::fs::perms::all_all, Stat->getPermissions()); -} - -TEST_F(InMemoryFileSystemTest, AddFileWithPerms) { - FS.addFile("/a/b/c", 0, MemoryBuffer::getMemBuffer("abc"), None, None, - None, sys::fs::perms::owner_read | sys::fs::perms::owner_write); - auto Stat = FS.status("/a"); - ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString(); - ASSERT_TRUE(Stat->isDirectory()); - ASSERT_EQ(sys::fs::perms::owner_read | sys::fs::perms::owner_write | - sys::fs::perms::owner_exe, Stat->getPermissions()); - Stat = FS.status("/a/b"); - ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString(); - ASSERT_TRUE(Stat->isDirectory()); - ASSERT_EQ(sys::fs::perms::owner_read | sys::fs::perms::owner_write | - sys::fs::perms::owner_exe, Stat->getPermissions()); - Stat = FS.status("/a/b/c"); - ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString(); - ASSERT_TRUE(Stat->isRegularFile()); - ASSERT_EQ(sys::fs::perms::owner_read | sys::fs::perms::owner_write, - Stat->getPermissions()); -} - -TEST_F(InMemoryFileSystemTest, AddDirectoryThenAddChild) { - FS.addFile("/a", 0, MemoryBuffer::getMemBuffer(""), /*User=*/None, - /*Group=*/None, sys::fs::file_type::directory_file); - FS.addFile("/a/b", 0, MemoryBuffer::getMemBuffer("abc"), /*User=*/None, - /*Group=*/None, sys::fs::file_type::regular_file); - auto Stat = FS.status("/a"); - ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString(); - ASSERT_TRUE(Stat->isDirectory()); - Stat = FS.status("/a/b"); - ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString(); - ASSERT_TRUE(Stat->isRegularFile()); -} - // NOTE: in the tests below, we use '//root/' as our root directory, since it is // a legal *absolute* path on Windows as well as *nix. class VFSFromYAMLTest : public ::testing::Test { @@ -936,7 +663,7 @@ public: getFromYAMLRawString(StringRef Content, IntrusiveRefCntPtr<vfs::FileSystem> ExternalFS) { std::unique_ptr<MemoryBuffer> Buffer = MemoryBuffer::getMemBuffer(Content); - return getVFSFromYAML(std::move(Buffer), CountingDiagHandler, "", this, + return getVFSFromYAML(std::move(Buffer), CountingDiagHandler, this, ExternalFS); } @@ -947,12 +674,6 @@ public: VersionPlusContent += Content.slice(Content.find('{') + 1, StringRef::npos); return getFromYAMLRawString(VersionPlusContent, ExternalFS); } - - // This is intended as a "XFAIL" for windows hosts. - bool supportsSameDirMultipleYAMLEntries() { - Triple Host(Triple::normalize(sys::getProcessTriple())); - return !Host.isOSWindows(); - } }; TEST_F(VFSFromYAMLTest, BasicVFSFromYAML) { @@ -1339,93 +1060,3 @@ TEST_F(VFSFromYAMLTest, DirectoryIteration) { checkContents(O->dir_begin("//root/foo/bar", EC), {"//root/foo/bar/a", "//root/foo/bar/b"}); } - -TEST_F(VFSFromYAMLTest, DirectoryIterationSameDirMultipleEntries) { - // https://llvm.org/bugs/show_bug.cgi?id=27725 - if (!supportsSameDirMultipleYAMLEntries()) - return; - - IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); - Lower->addDirectory("//root/zab"); - Lower->addDirectory("//root/baz"); - Lower->addRegularFile("//root/zab/a"); - Lower->addRegularFile("//root/zab/b"); - IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString( - "{ 'use-external-names': false,\n" - " 'roots': [\n" - "{\n" - " 'type': 'directory',\n" - " 'name': '//root/baz/',\n" - " 'contents': [ {\n" - " 'type': 'file',\n" - " 'name': 'x',\n" - " 'external-contents': '//root/zab/a'\n" - " }\n" - " ]\n" - "},\n" - "{\n" - " 'type': 'directory',\n" - " 'name': '//root/baz/',\n" - " 'contents': [ {\n" - " 'type': 'file',\n" - " 'name': 'y',\n" - " 'external-contents': '//root/zab/b'\n" - " }\n" - " ]\n" - "}\n" - "]\n" - "}", - Lower); - ASSERT_TRUE(FS.get() != nullptr); - - IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( - new vfs::OverlayFileSystem(Lower)); - O->pushOverlay(FS); - - std::error_code EC; - - checkContents(O->dir_begin("//root/baz/", EC), - {"//root/baz/x", "//root/baz/y"}); -} - -TEST_F(VFSFromYAMLTest, RecursiveDirectoryIterationLevel) { - - IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); - Lower->addDirectory("//root/a"); - Lower->addDirectory("//root/a/b"); - Lower->addDirectory("//root/a/b/c"); - Lower->addRegularFile("//root/a/b/c/file"); - IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString( - "{ 'use-external-names': false,\n" - " 'roots': [\n" - "{\n" - " 'type': 'directory',\n" - " 'name': '//root/a/b/c/',\n" - " 'contents': [ {\n" - " 'type': 'file',\n" - " 'name': 'file',\n" - " 'external-contents': '//root/a/b/c/file'\n" - " }\n" - " ]\n" - "},\n" - "]\n" - "}", - Lower); - ASSERT_TRUE(FS.get() != nullptr); - - IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( - new vfs::OverlayFileSystem(Lower)); - O->pushOverlay(FS); - - std::error_code EC; - - // Test recursive_directory_iterator level() - vfs::recursive_directory_iterator I = vfs::recursive_directory_iterator( - *O, "//root", EC), E; - ASSERT_FALSE(EC); - for (int l = 0; I != E; I.increment(EC), ++l) { - ASSERT_FALSE(EC); - EXPECT_EQ(I.level(), l); - } - EXPECT_EQ(I, E); -} diff --git a/gnu/llvm/tools/clang/utils/analyzer/ubiviz b/gnu/llvm/tools/clang/utils/analyzer/ubiviz index 137e130fe74..9d821c3c10a 100755 --- a/gnu/llvm/tools/clang/utils/analyzer/ubiviz +++ b/gnu/llvm/tools/clang/utils/analyzer/ubiviz @@ -5,72 +5,69 @@ # This file is distributed under the University of Illinois Open Source # License. See LICENSE.TXT for details. # -##===--------------------------------------------------------------------===## +##===----------------------------------------------------------------------===## # # This script reads visualization data emitted by the static analyzer for # display in Ubigraph. # -##===--------------------------------------------------------------------===## +##===----------------------------------------------------------------------===## import xmlrpclib import sys - def Error(message): print >> sys.stderr, 'ubiviz: ' + message sys.exit(1) - def StreamData(filename): - file = open(filename) - for ln in file: - yield eval(ln) - file.close() - + file = open(filename) + for ln in file: + yield eval(ln) + file.close() def Display(G, data): - action = data[0] - if action == 'vertex': - vertex = data[1] - G.new_vertex_w_id(vertex) - for attribute in data[2:]: - G.set_vertex_attribute(vertex, attribute[0], attribute[1]) - elif action == 'edge': - src = data[1] - dst = data[2] - edge = G.new_edge(src, dst) - for attribute in data[3:]: - G.set_edge_attribute(edge, attribute[0], attribute[1]) - elif action == "vertex_style": - style_id = data[1] - parent_id = data[2] - G.new_vertex_style_w_id(style_id, parent_id) - for attribute in data[3:]: - G.set_vertex_style_attribute(style_id, attribute[0], attribute[1]) - elif action == "vertex_style_attribute": - style_id = data[1] - for attribute in data[2:]: - G.set_vertex_style_attribute(style_id, attribute[0], attribute[1]) - elif action == "change_vertex_style": - vertex_id = data[1] - style_id = data[2] - G.change_vertex_style(vertex_id, style_id) - + action = data[0] + if action == 'vertex': + vertex = data[1] + G.new_vertex_w_id(vertex) + for attribute in data[2:]: + G.set_vertex_attribute(vertex, attribute[0], attribute[1]) + elif action == 'edge': + src = data[1] + dst = data[2] + edge = G.new_edge(src,dst) + for attribute in data[3:]: + G.set_edge_attribute(edge, attribute[0], attribute[1]) + elif action == "vertex_style": + style_id = data[1] + parent_id = data[2] + G.new_vertex_style_w_id(style_id, parent_id) + for attribute in data[3:]: + G.set_vertex_style_attribute(style_id, attribute[0], attribute[1]) + elif action == "vertex_style_attribute": + style_id = data[1] + for attribute in data[2:]: + G.set_vertex_style_attribute(style_id, attribute[0], attribute[1]) + elif action == "change_vertex_style": + vertex_id = data[1] + style_id = data[2] + G.change_vertex_style(vertex_id,style_id) def main(args): - if len(args) == 0: - Error('no input files') + if len(args) == 0: + Error('no input files') - server = xmlrpclib.Server('http://127.0.0.1:20738/RPC2') - G = server.ubigraph + server = xmlrpclib.Server('http://127.0.0.1:20738/RPC2') + G = server.ubigraph - for arg in args: - G.clear() - for x in StreamData(arg): - Display(G, x) + for arg in args: + G.clear() + for x in StreamData(arg): + Display(G,x) - sys.exit(0) + sys.exit(0) if __name__ == '__main__': main(sys.argv[1:]) + diff --git a/gnu/llvm/tools/clang/www/cxx_dr_status.html b/gnu/llvm/tools/clang/www/cxx_dr_status.html index 8085616ff4a..a062b03945f 100644 --- a/gnu/llvm/tools/clang/www/cxx_dr_status.html +++ b/gnu/llvm/tools/clang/www/cxx_dr_status.html @@ -28,7 +28,7 @@ <!--*************************************************************************--> <h1>C++ Defect Report Support in Clang</h1> <!--*************************************************************************--> -<p>Last updated: $Date: 2019/01/27 16:43:08 $</p> +<p>Last updated: $Date: 2016/09/03 22:46:56 $</p> <h2 id="cxxdr">C++ defect report implementation status</h2> @@ -207,7 +207,7 @@ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#28">28</a></td> <td>CD1</td> <td>'exit', 'signal' and static object destruction</td> - <td class="na" align="center">N/A (Library DR)</td> + <td class="na" align="center">N/A</td> </tr> <tr id="29"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#29">29</a></td> @@ -303,7 +303,7 @@ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#44">44</a></td> <td>CD1</td> <td>Member specializations</td> - <td class="partial" align="center">Superseded by <a href="#727">727</a></td> + <td class="full" align="center">Yes</td> </tr> <tr id="45"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#45">45</a></td> @@ -587,11 +587,11 @@ <td>A union's associated types should include the union itself</td> <td class="full" align="center">Yes</td> </tr> - <tr id="92"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#92">92</a></td> - <td>CD4</td> + <tr class="open" id="92"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#92">92</a></td> + <td>extension</td> <td>Should <I>exception-specification</I>s be part of the type system?</td> - <td class="full" align="center">Clang 4 (C++17 onwards)</td> + <td align="center">Not resolved</td> </tr> <tr id="93"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#93">93</a></td> @@ -663,7 +663,7 @@ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#104">104</a></td> <td>NAD</td> <td>Destroying the exception temp when no handler is found</td> - <td class="na" align="center">N/A (Library DR)</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="105"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#105">105</a></td> @@ -747,7 +747,7 @@ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#118">118</a></td> <td>CD1</td> <td>Calls via pointers to virtual member functions</td> - <td class="full" align="center">Yes</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="119"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#119">119</a></td> @@ -795,7 +795,7 @@ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#126">126</a></td> <td>TC1</td> <td>Exception specifications and <TT>const</TT></td> - <td class="partial" align="center">Partial</td> + <td class="none" align="center">No</td> </tr> <tr id="127"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#127">127</a></td> @@ -813,7 +813,7 @@ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#129">129</a></td> <td>CD3</td> <td>Stability of uninitialized auto variables</td> - <td class="full" align="center">Duplicate of <a href="#616">616</a></td> + <td class="none" align="center">Duplicate of <a href="#616">616</a></td> </tr> <tr id="130"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#130">130</a></td> @@ -921,7 +921,7 @@ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#147">147</a></td> <td>TC1</td> <td>Naming the constructor</td> - <td class="full" align="center">Yes</td> + <td class="none" align="center">No</td> </tr> <tr id="148"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#148">148</a></td> @@ -935,11 +935,11 @@ <td>Accessibility and ambiguity</td> <td class="na" align="center">N/A</td> </tr> - <tr id="150"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#150">150</a></td> - <td>C++17</td> + <tr class="open" id="150"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#150">150</a></td> + <td>open</td> <td>Template template parameters and default arguments</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr id="151"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#151">151</a></td> @@ -987,7 +987,7 @@ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#158">158</a></td> <td>CD1</td> <td>Aliasing and qualification conversions</td> - <td class="full" align="center">Yes</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="159"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#159">159</a></td> @@ -1308,11 +1308,11 @@ accessible?</td> <td>Constructors should not be allowed to return normally after an exception</td> <td class="full" align="center">Yes</td> </tr> - <tr id="212"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#212">212</a></td> - <td>CD4</td> + <tr class="open" id="212"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#212">212</a></td> + <td>drafting</td> <td>Implicit instantiation is not described clearly enough</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr id="213"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#213">213</a></td> @@ -1464,11 +1464,11 @@ accessible?</td> <td>Explicit instantiation and base class members</td> <td class="full" align="center">Duplicate of <a href="#470">470</a></td> </tr> - <tr id="238"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#238">238</a></td> - <td>CD4</td> + <tr class="open" id="238"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#238">238</a></td> + <td>open</td> <td>Precision and accuracy constraints on floating point</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr id="239"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#239">239</a></td> @@ -1480,7 +1480,7 @@ accessible?</td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#240">240</a></td> <td>CD3</td> <td>Uninitialized values and undefined behavior</td> - <td class="full" align="center">Duplicate of <a href="#616">616</a></td> + <td class="none" align="center">Duplicate of <a href="#616">616</a></td> </tr> <tr id="241"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#241">241</a></td> @@ -1488,11 +1488,11 @@ accessible?</td> <td>Error in example in 14.8.1</td> <td class="full" align="center">Yes</td> </tr> - <tr id="242"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#242">242</a></td> - <td>CD4</td> + <tr class="open" id="242"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#242">242</a></td> + <td>drafting</td> <td>Interpretation of old-style casts</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr id="243"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#243">243</a></td> @@ -1554,11 +1554,11 @@ accessible?</td> <td>Looking up deallocation functions in virtual destructors</td> <td class="full" align="center">Yes</td> </tr> - <tr id="253"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#253">253</a></td> - <td>C++17</td> + <tr class="open" id="253"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#253">253</a></td> + <td>drafting</td> <td>Why must empty or fully-initialized const objects be initialized?</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr id="254"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#254">254</a></td> @@ -1594,7 +1594,7 @@ accessible?</td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#259">259</a></td> <td>CD1</td> <td>Restrictions on explicit specialization and instantiation</td> - <td class="full" align="center">Clang 4</td> + <td class="full" align="center">Yes (C++11 onwards)</td> </tr> <tr class="open" id="260"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#260">260</a></td> @@ -1913,7 +1913,7 @@ of class templates</td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#312">312</a></td> <td>CD3</td> <td>“use” of invalid pointer value not defined</td> - <td class="full" align="center">Duplicate of <a href="#616">616</a></td> + <td class="none" align="center">Duplicate of <a href="#616">616</a></td> </tr> <tr id="313"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#313">313</a></td> @@ -1921,11 +1921,11 @@ of class templates</td> <td>Class with single conversion function to integral as array size in <TT>new</TT></td> <td class="full" align="center">Duplicate of <a href="#299">299</a> (C++11 onwards)</td> </tr> - <tr id="314"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#314">314</a></td> - <td>C++17</td> + <tr class="open" id="314"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#314">314</a></td> + <td>review</td> <td><TT>template</TT> in base class specifier</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr id="315"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#315">315</a></td> @@ -1937,7 +1937,7 @@ of class templates</td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#316">316</a></td> <td>NAD</td> <td>Injected-class-name of template used as template template parameter</td> - <td class="full" align="center">Superseded by <a href="#1004">1004</a></td> + <td class="none" align="center">Superseded by <a href="#1004">1004</a></td> </tr> <tr id="317"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#317">317</a></td> @@ -1949,7 +1949,7 @@ of class templates</td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#318">318</a></td> <td>CD1</td> <td><TT>struct A::A</TT> should not name the constructor of <TT>A</TT></td> - <td class="full" align="center">Superseded by <a href="#1310">1310</a></td> + <td class="none" align="center">Superseded by <a href="#1310">1310</a></td> </tr> <tr id="319"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#319">319</a></td> @@ -2019,9 +2019,9 @@ of class templates</td> </tr> <tr id="330"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#330">330</a></td> - <td>CD4</td> + <td>DR</td> <td>Qualification conversions and pointers to arrays of pointers</td> - <td class="svn" align="center">Clang 7</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="331"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#331">331</a></td> @@ -2095,11 +2095,11 @@ of class templates</td> <td>Terminology: "indirection" versus "dereference"</td> <td class="na" align="center">N/A</td> </tr> - <tr id="343"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#343">343</a></td> - <td>C++17</td> + <tr class="open" id="343"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#343">343</a></td> + <td>review</td> <td>Make <TT>template</TT> optional in contexts that require a type</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr id="344"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#344">344</a></td> @@ -2279,13 +2279,13 @@ of class templates</td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#373">373</a></td> <td>C++11</td> <td>Lookup on namespace qualified name in using-directive</td> - <td class="full" align="center">Clang 5</td> + <td class="none" align="center">No</td> </tr> <tr id="374"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#374">374</a></td> <td>CD2</td> <td>Can explicit specialization outside namespace use qualified name?</td> - <td class="full" align="center">Yes</td> + <td class="full" align="center">Yes (C++11 onwards)</td> </tr> <tr id="375"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#375">375</a></td> @@ -2397,7 +2397,7 @@ of class templates</td> </tr> <tr id="393"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#393">393</a></td> - <td>CD4</td> + <td>DR</td> <td>Pointer to array of unknown bound in template argument list in parameter</td> <td class="none" align="center">Unknown</td> </tr> @@ -2593,11 +2593,11 @@ of class templates</td> <td>Set of candidates for overloaded built-in operator with float operand</td> <td class="full" align="center">Yes</td> </tr> - <tr id="426"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#426">426</a></td> - <td>C++17</td> + <tr class="open" id="426"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#426">426</a></td> + <td>drafting</td> <td>Identically-named variables, one internally and one externally linked, allowed?</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr id="427"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#427">427</a></td> @@ -3017,13 +3017,13 @@ of class templates</td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#496">496</a></td> <td>CD3</td> <td>Is a volatile-qualified type really a POD?</td> - <td class="full" align="center">Superseded by <a href="#2094">2094</a></td> + <td class="none" align="center">No</td> </tr> <tr id="497"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#497">497</a></td> <td>CD1</td> <td>Missing required initialization in example</td> - <td class="none" align="center">Superseded by <a href="#253">253</a></td> + <td class="full" align="center">Yes</td> </tr> <tr class="open" id="498"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#498">498</a></td> @@ -3365,7 +3365,7 @@ and <I>POD class</I></td> </tr> <tr class="open" id="554"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#554">554</a></td> - <td>drafting</td> + <td>review</td> <td>Definition of “declarative region” and “scope”</td> <td align="center">Not resolved</td> </tr> @@ -3523,7 +3523,7 @@ and <I>POD class</I></td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#580">580</a></td> <td>C++11</td> <td>Access in <I>template-parameter</I>s of member and friend definitions</td> - <td class="partial" align="center">Partial</td> + <td class="none" align="center">No</td> </tr> <tr class="open" id="581"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#581">581</a></td> @@ -3541,7 +3541,7 @@ and <I>POD class</I></td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#583">583</a></td> <td>CD3</td> <td>Relational pointer comparisons against the null pointer constant</td> - <td class="full" align="center">Clang 4</td> + <td class="none" align="center">No</td> </tr> <tr id="584"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#584">584</a></td> @@ -3587,7 +3587,7 @@ and <I>POD class</I></td> </tr> <tr id="591"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#591">591</a></td> - <td>CD4</td> + <td>DR</td> <td>When a dependent base class is the current instantiation</td> <td class="none" align="center">No</td> </tr> @@ -3613,13 +3613,13 @@ and <I>POD class</I></td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#595">595</a></td> <td>dup</td> <td>Exception specifications in templates instantiated from class bodies</td> - <td class="full" align="center">Duplicate of <a href="#1330">1330</a></td> + <td class="none" align="center">Duplicate of <a href="#1330">1330</a></td> </tr> - <tr id="596"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#596">596</a></td> - <td>NAD</td> + <tr class="open" id="596"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#596">596</a></td> + <td>open</td> <td>Replacing an exception object</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr id="597"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#597">597</a></td> @@ -3695,7 +3695,7 @@ and <I>POD class</I></td> </tr> <tr id="609"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#609">609</a></td> - <td>CD4</td> + <td>DR</td> <td>What is a “top-level” cv-qualifier?</td> <td class="none" align="center">Unknown</td> </tr> @@ -3739,7 +3739,7 @@ and <I>POD class</I></td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#616">616</a></td> <td>CD3</td> <td>Definition of “indeterminate value”</td> - <td class="full" align="center">Clang 4</td> + <td class="none" align="center">No</td> </tr> <tr class="open" id="617"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#617">617</a></td> @@ -3855,11 +3855,11 @@ and <I>POD class</I></td> <td>Names of constructors and destructors of templates</td> <td class="full" align="center">Yes</td> </tr> - <tr id="636"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#636">636</a></td> - <td>CD4</td> + <tr class="open" id="636"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#636">636</a></td> + <td>drafting</td> <td>Dynamic type of objects and aliasing</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr id="637"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#637">637</a></td> @@ -3889,55 +3889,55 @@ and <I>POD class</I></td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#641">641</a></td> <td>CD2</td> <td>Overload resolution and conversion-to-same-type operators</td> - <td class="full" align="center">Yes</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="642"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#642">642</a></td> <td>CD2</td> <td>Definition and use of “block scope” and “local scope”</td> - <td class="full" align="center">Yes</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="643"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#643">643</a></td> <td>NAD</td> <td>Use of <TT>decltype</TT> in a class <I>member-specification</I></td> - <td class="full" align="center">Yes</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="644"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#644">644</a></td> <td>CD1</td> <td>Should a trivial class type be a literal type?</td> - <td class="partial" align="center">Partial</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="645"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#645">645</a></td> <td>CD2</td> <td>Are bit-field and non-bit-field members layout compatible?</td> - <td class="na" align="center">N/A</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="646"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#646">646</a></td> <td>NAD</td> <td>Can a class with a constexpr copy constructor be a literal type?</td> - <td class="none" align="center">Superseded by <a href="#981">981</a></td> + <td class="none" align="center">Unknown</td> </tr> <tr id="647"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#647">647</a></td> <td>CD1</td> <td>Non-constexpr instances of constexpr constructor templates</td> - <td class="full" align="center">Yes</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="648"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#648">648</a></td> <td>CD1</td> <td>Constant expressions in constexpr initializers</td> - <td class="full" align="center">Yes</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="649"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#649">649</a></td> <td>CD1</td> <td>Optionally ill-formed extended alignment requests</td> - <td class="full" align="center">Yes</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="650"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#650">650</a></td> @@ -3949,13 +3949,13 @@ and <I>POD class</I></td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#651">651</a></td> <td>CD1</td> <td>Problems in <TT>decltype</TT> specification and examples</td> - <td class="full" align="center">Yes</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="652"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#652">652</a></td> <td>CD2</td> <td>Compile-time evaluation of floating-point expressions</td> - <td class="full" align="center">Yes</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="653"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#653">653</a></td> @@ -3967,25 +3967,25 @@ and <I>POD class</I></td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#654">654</a></td> <td>CD1</td> <td>Conversions to and from <TT>nullptr_t</TT></td> - <td class="full" align="center">Yes</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="655"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#655">655</a></td> <td>C++11</td> <td>Initialization not specified for forwarding constructors</td> - <td class="full" align="center">Yes</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="656"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#656">656</a></td> <td>CD2</td> <td>Direct binding to the result of a conversion operator</td> - <td class="full" align="center">Yes</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="657"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#657">657</a></td> <td>CD2</td> <td>Abstract class parameter in synthesized declaration</td> - <td class="partial" align="center">Partial</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="658"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#658">658</a></td> @@ -3997,13 +3997,13 @@ and <I>POD class</I></td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#659">659</a></td> <td>CD1</td> <td>Alignment of function types</td> - <td class="full" align="center">Yes</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="660"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#660">660</a></td> <td>CD1</td> <td>Unnamed scoped enumerations</td> - <td class="full" align="center">Yes</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="661"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#661">661</a></td> @@ -4015,37 +4015,37 @@ and <I>POD class</I></td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#662">662</a></td> <td>NAD</td> <td>Forming a pointer to a reference type</td> - <td class="full" align="center">Yes</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="663"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#663">663</a></td> <td>CD1</td> <td>Valid Cyrillic identifier characters</td> - <td class="full" align="center">Yes (C++11 onwards)</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="664"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#664">664</a></td> <td>CD2</td> <td>Direct binding of references to non-class rvalue references</td> - <td class="full" align="center">Yes</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="665"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#665">665</a></td> <td>CD2</td> <td>Problems in the specification of <TT>dynamic_cast</TT></td> - <td class="full" align="center">Yes</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="666"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#666">666</a></td> <td>CD1</td> <td>Dependent <I>qualified-id</I>s without the <TT>typename</TT> keyword</td> - <td class="full" align="center">Yes</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="667"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#667">667</a></td> <td>CD2</td> <td>Trivial special member functions that cannot be implicitly defined</td> - <td class="full" align="center">Yes</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="668"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#668">668</a></td> @@ -4057,7 +4057,7 @@ and <I>POD class</I></td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#669">669</a></td> <td>NAD</td> <td>Confusing specification of the meaning of <TT>decltype</TT></td> - <td class="full" align="center">Yes</td> + <td class="none" align="center">Unknown</td> </tr> <tr class="open" id="670"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#670">670</a></td> @@ -4069,7 +4069,7 @@ and <I>POD class</I></td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#671">671</a></td> <td>CD1</td> <td>Explicit conversion from a scoped enumeration type to integral type</td> - <td class="full" align="center">Yes</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="672"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#672">672</a></td> @@ -4081,31 +4081,31 @@ and <I>POD class</I></td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#673">673</a></td> <td>NAD</td> <td>Injection of names from <I>elaborated-type-specifier</I>s in <TT>friend</TT> declarations</td> - <td class="full" align="center">Yes</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="674"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#674">674</a></td> <td>C++11</td> <td>“matching specialization” for a friend declaration</td> - <td class="none" align="center">No</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="675"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#675">675</a></td> <td>CD3</td> <td>Signedness of bit-field with typedef or template parameter type</td> - <td class="none" align="center">Duplicate of <a href="#739">739</a></td> + <td class="none" align="center">Unknown</td> </tr> <tr id="676"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#676">676</a></td> <td>C++11</td> <td><I>static_assert-declaration</I>s and general requirements for declarations</td> - <td class="na" align="center">N/A</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="677"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#677">677</a></td> <td>CD1</td> <td>Deleted <TT>operator delete</TT> and virtual destructors</td> - <td class="none" align="center">No</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="678"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#678">678</a></td> @@ -4117,19 +4117,19 @@ and <I>POD class</I></td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#679">679</a></td> <td>CD1</td> <td>Equivalence of <I>template-id</I>s and operator function templates</td> - <td class="full" align="center">Yes</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="680"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#680">680</a></td> <td>CD2</td> <td>What is a move constructor?</td> - <td class="na" align="center">N/A</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="681"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#681">681</a></td> <td>CD1</td> <td>Restrictions on declarators with late-specified return types</td> - <td class="partial" align="center">Partial</td> + <td class="none" align="center">Unknown</td> </tr> <tr class="open" id="682"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#682">682</a></td> @@ -4141,25 +4141,25 @@ and <I>POD class</I></td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#683">683</a></td> <td>CD1</td> <td>Requirements for trivial subobject special functions</td> - <td class="full" align="center">Yes</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="684"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#684">684</a></td> <td>CD1</td> <td>Constant expressions involving the address of an automatic variable</td> - <td class="none" align="center">Superseded by <a href="#1454">1454</a></td> + <td class="none" align="center">Unknown</td> </tr> <tr id="685"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#685">685</a></td> <td>CD2</td> <td>Integral promotion of enumeration ignores fixed underlying type</td> - <td class="full" align="center">Yes</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="686"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#686">686</a></td> <td>CD1</td> <td>Type declarations/definitions in <I>type-specifier-seq</I>s and <I>type-id</I>s</td> - <td class="full" align="center">Yes</td> + <td class="none" align="center">Unknown</td> </tr> <tr class="open" id="687"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#687">687</a></td> @@ -4195,7 +4195,7 @@ and <I>POD class</I></td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#692">692</a></td> <td>C++11</td> <td>Partial ordering of variadic class template partial specializations</td> - <td class="none" align="center">No</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="693"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#693">693</a></td> @@ -4383,11 +4383,11 @@ and <I>POD class</I></td> <td>Atomic and non-atomic objects in the memory model</td> <td class="none" align="center">Unknown</td> </tr> - <tr id="727"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#727">727</a></td> - <td>C++17</td> + <tr class="open" id="727"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#727">727</a></td> + <td>drafting</td> <td>In-class explicit specializations</td> - <td class="partial" align="center">Partial</td> + <td align="center">Not resolved</td> </tr> <tr class="open" id="728"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#728">728</a></td> @@ -5235,11 +5235,11 @@ and <I>POD class</I></td> <td>Explicit conversion functions in direct class initialization</td> <td class="none" align="center">Unknown</td> </tr> - <tr class="open" id="900"> + <tr id="900"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#900">900</a></td> - <td>extension</td> + <td>NAD</td> <td>Lifetime of temporaries in range-based <TT>for</TT></td> - <td align="center">Not resolved</td> + <td class="none" align="center">Unknown</td> </tr> <tr class="open" id="901"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#901">901</a></td> @@ -5469,15 +5469,15 @@ and <I>POD class</I></td> <td>Is <TT>this</TT> an entity?</td> <td class="none" align="center">Unknown</td> </tr> - <tr id="943"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#943">943</a></td> - <td>DRWP</td> + <tr class="open" id="943"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#943">943</a></td> + <td>open</td> <td>Is <TT>T()</TT> a temporary?</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr class="open" id="944"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#944">944</a></td> - <td>extension</td> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#944">944</a></td> + <td>open</td> <td><TT>reinterpret_cast</TT> for all types with the same size and alignment</td> <td align="center">Not resolved</td> </tr> @@ -5735,7 +5735,7 @@ and <I>POD class</I></td> </tr> <tr id="987"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#987">987</a></td> - <td>CD4</td> + <td>DR</td> <td>Which declarations introduce namespace members?</td> <td class="none" align="center">Unknown</td> </tr> @@ -5839,7 +5839,7 @@ and <I>POD class</I></td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1004">1004</a></td> <td>C++11</td> <td>Injected-class-names as arguments for template template parameters</td> - <td class="full" align="center">Clang 5</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="1005"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1005">1005</a></td> @@ -5939,7 +5939,7 @@ and <I>POD class</I></td> </tr> <tr id="1021"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1021">1021</a></td> - <td>CD4</td> + <td>DR</td> <td>Definitions of namespace members</td> <td class="none" align="center">Unknown</td> </tr> @@ -6139,7 +6139,7 @@ and <I>POD class</I></td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1054">1054</a></td> <td>C++11</td> <td>Lvalue-to-rvalue conversions in expression statements</td> - <td class="none" align="center">No</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="1055"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1055">1055</a></td> @@ -6267,11 +6267,11 @@ and <I>POD class</I></td> <td>Grammar does not allow template alias in <I>type-name</I></td> <td class="none" align="center">Unknown</td> </tr> - <tr id="1076"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1076">1076</a></td> - <td>DRWP</td> + <tr class="open" id="1076"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1076">1076</a></td> + <td>open</td> <td>Value categories and lvalue temporaries</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr class="open" id="1077"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1077">1077</a></td> @@ -6493,7 +6493,7 @@ and <I>POD class</I></td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1113">1113</a></td> <td>C++11</td> <td>Linkage of namespace member of unnamed namespace</td> - <td class="partial" align="center">Partial</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="1114"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1114">1114</a></td> @@ -6507,11 +6507,11 @@ and <I>POD class</I></td> <td>C-compatible alignment specification</td> <td class="none" align="center">Unknown</td> </tr> - <tr id="1116"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1116">1116</a></td> - <td>CD4</td> + <tr class="open" id="1116"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1116">1116</a></td> + <td>drafting</td> <td>Aliasing of union members</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr id="1117"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1117">1117</a></td> @@ -7093,7 +7093,7 @@ and <I>POD class</I></td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1213">1213</a></td> <td>CD3</td> <td>Array subscripting and xvalues</td> - <td class="svn" align="center">Clang 7</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="1214"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1214">1214</a></td> @@ -7294,8 +7294,8 @@ and <I>POD class</I></td> <td class="none" align="center">Unknown</td> </tr> <tr id="1247"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1247">1247</a></td> - <td>CD4</td> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1247">1247</a></td> + <td>tentatively ready</td> <td>Restriction on alias name appearing in <I>type-id</I></td> <td class="none" align="center">Unknown</td> </tr> @@ -7315,7 +7315,7 @@ and <I>POD class</I></td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1250">1250</a></td> <td>CD3</td> <td>Cv-qualification of incomplete virtual function return types</td> - <td class="full" align="center">Clang 3.9</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="1251"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1251">1251</a></td> @@ -7405,7 +7405,7 @@ and <I>POD class</I></td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1265">1265</a></td> <td>CD3</td> <td>Mixed use of the <TT>auto</TT> specifier</td> - <td class="full" align="center">Clang 5</td> + <td class="none" align="center">Unknown</td> </tr> <tr class="open" id="1266"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1266">1266</a></td> @@ -7455,11 +7455,11 @@ and <I>POD class</I></td> <td>Accessibility and function signatures</td> <td class="none" align="center">Unknown</td> </tr> - <tr id="1274"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1274">1274</a></td> - <td>CD4</td> + <tr class="open" id="1274"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1274">1274</a></td> + <td>drafting</td> <td>Common nonterminal for <I>expression</I> and <I>braced-init-list</I></td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr id="1275"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1275">1275</a></td> @@ -7515,11 +7515,11 @@ and <I>POD class</I></td> <td>Static data members of classes with typedef name for linkage purposes</td> <td align="center">Not resolved</td> </tr> - <tr id="1284"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1284">1284</a></td> - <td>CD4</td> + <tr class="open" id="1284"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1284">1284</a></td> + <td>drafting</td> <td>Should the lifetime of an array be independent of that of its elements?</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr class="open" id="1285"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1285">1285</a></td> @@ -7565,7 +7565,7 @@ and <I>POD class</I></td> </tr> <tr id="1292"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1292">1292</a></td> - <td>CD4</td> + <td>DR</td> <td>Dependent calls with <I>braced-init-list</I>s containing a pack expansion</td> <td class="none" align="center">Unknown</td> </tr> @@ -7585,7 +7585,7 @@ and <I>POD class</I></td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1295">1295</a></td> <td>CD3</td> <td>Binding a reference to an rvalue bit-field</td> - <td class="full" align="center">Clang 4</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="1296"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1296">1296</a></td> @@ -7605,11 +7605,11 @@ and <I>POD class</I></td> <td>Incorrect example in overload resolution</td> <td class="none" align="center">Unknown</td> </tr> - <tr id="1299"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1299">1299</a></td> - <td>DRWP</td> + <tr class="open" id="1299"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1299">1299</a></td> + <td>drafting</td> <td>“Temporary objects” vs “temporary expressions”</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr id="1300"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1300">1300</a></td> @@ -7666,8 +7666,8 @@ and <I>POD class</I></td> <td class="none" align="center">Unknown</td> </tr> <tr id="1309"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1309">1309</a></td> - <td>CD4</td> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1309">1309</a></td> + <td>ready</td> <td>Incorrect note regarding lookup of a member of the current instantiation</td> <td class="none" align="center">Unknown</td> </tr> @@ -7675,7 +7675,7 @@ and <I>POD class</I></td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1310">1310</a></td> <td>CD3</td> <td>What is an “acceptable lookup result?”</td> - <td class="full" align="center">Clang 5</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="1311"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1311">1311</a></td> @@ -7701,11 +7701,11 @@ and <I>POD class</I></td> <td>Pointer arithmetic within standard-layout objects</td> <td class="none" align="center">Unknown</td> </tr> - <tr id="1315"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1315">1315</a></td> - <td>CD4</td> + <tr class="open" id="1315"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1315">1315</a></td> + <td>drafting</td> <td>Restrictions on non-type template arguments in partial specializations</td> - <td class="partial" align="center">Partial</td> + <td align="center">Not resolved</td> </tr> <tr id="1316"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1316">1316</a></td> @@ -7795,7 +7795,7 @@ and <I>POD class</I></td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1330">1330</a></td> <td>CD3</td> <td>Delayed instantiation of <TT>noexcept</TT> specifiers</td> - <td class="full" align="center">Clang 4 (C++11 onwards)</td> + <td class="none" align="center">Unknown</td> </tr> <tr class="open" id="1331"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1331">1331</a></td> @@ -7841,7 +7841,7 @@ and <I>POD class</I></td> </tr> <tr id="1338"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1338">1338</a></td> - <td>CD4</td> + <td>DR</td> <td>Aliasing and allocation functions</td> <td class="none" align="center">Unknown</td> </tr> @@ -7857,11 +7857,11 @@ and <I>POD class</I></td> <td>Complete type in member pointer expressions</td> <td class="none" align="center">Unknown</td> </tr> - <tr id="1341"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1341">1341</a></td> - <td>NAD</td> + <tr class="open" id="1341"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1341">1341</a></td> + <td>drafting</td> <td>Bit-field initializers</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr class="open" id="1342"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1342">1342</a></td> @@ -7869,11 +7869,11 @@ and <I>POD class</I></td> <td>Order of initialization with multiple declarators</td> <td align="center">Not resolved</td> </tr> - <tr id="1343"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1343">1343</a></td> - <td>C++17</td> + <tr class="open" id="1343"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1343">1343</a></td> + <td>drafting</td> <td>Sequencing of non-class initialization</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr id="1344"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1344">1344</a></td> @@ -7897,7 +7897,7 @@ and <I>POD class</I></td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1347">1347</a></td> <td>CD3</td> <td>Consistency of <TT>auto</TT> in multiple-declarator declarations</td> - <td class="full" align="center">Yes</td> + <td class="none" align="center">Unknown</td> </tr> <tr class="open" id="1348"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1348">1348</a></td> @@ -7919,7 +7919,7 @@ and <I>POD class</I></td> </tr> <tr id="1351"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1351">1351</a></td> - <td>CD4</td> + <td>DR</td> <td>Problems with implicitly-declared <I>exception-specification</I>s</td> <td class="none" align="center">Unknown</td> </tr> @@ -7949,7 +7949,7 @@ and <I>POD class</I></td> </tr> <tr id="1356"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1356">1356</a></td> - <td>CD4</td> + <td>DR</td> <td>Exception specifications of copy assignment operators with virtual bases</td> <td class="none" align="center">Unknown</td> </tr> @@ -7969,7 +7969,7 @@ and <I>POD class</I></td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1359">1359</a></td> <td>CD3</td> <td><TT>constexpr</TT> union constructors</td> - <td class="full" align="center">Clang 3.5</td> + <td class="none" align="center">Unknown</td> </tr> <tr class="open" id="1360"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1360">1360</a></td> @@ -8143,7 +8143,7 @@ and <I>POD class</I></td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1388">1388</a></td> <td>CD3</td> <td>Missing non-deduced context following a function parameter pack</td> - <td class="full" align="center">Clang 4</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="1389"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1389">1389</a></td> @@ -8157,11 +8157,11 @@ and <I>POD class</I></td> <td>Dependency of alias template specializations</td> <td align="center">Not resolved</td> </tr> - <tr id="1391"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1391">1391</a></td> - <td>CD4</td> + <tr class="open" id="1391"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1391">1391</a></td> + <td>drafting</td> <td>Conversions to parameter types with non-deduced template arguments</td> - <td class="partial" align="center">Partial</td> + <td align="center">Not resolved</td> </tr> <tr id="1392"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1392">1392</a></td> @@ -8181,11 +8181,11 @@ and <I>POD class</I></td> <td>Incomplete types as parameters of deleted functions</td> <td class="none" align="center">Unknown</td> </tr> - <tr id="1395"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1395">1395</a></td> - <td>C++17</td> + <tr class="open" id="1395"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1395">1395</a></td> + <td>drafting</td> <td>Partial ordering of variadic templates reconsidered</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr class="open" id="1396"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1396">1396</a></td> @@ -8195,7 +8195,7 @@ and <I>POD class</I></td> </tr> <tr id="1397"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1397">1397</a></td> - <td>CD4</td> + <td>DR</td> <td>Class completeness in non-static data member initializers</td> <td class="none" align="center">Unknown</td> </tr> @@ -8209,7 +8209,7 @@ and <I>POD class</I></td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1399">1399</a></td> <td>CD3</td> <td>Deduction with multiple function parameter packs</td> - <td class="full" align="center">Duplicate of <a href="#1388">1388</a></td> + <td class="none" align="center">Unknown</td> </tr> <tr id="1400"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1400">1400</a></td> @@ -8365,7 +8365,7 @@ and <I>POD class</I></td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1425">1425</a></td> <td>CD3</td> <td>Base-class subobjects of standard-layout structs</td> - <td class="na" align="center">N/A (ABI constraint)</td> + <td class="none" align="center">Unknown</td> </tr> <tr class="open" id="1426"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1426">1426</a></td> @@ -8489,7 +8489,7 @@ and <I>POD class</I></td> </tr> <tr id="1446"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1446">1446</a></td> - <td>CD4</td> + <td>DR</td> <td>Member function with no <I>ref-qualifier</I> and non-member function with rvalue reference</td> <td class="none" align="center">Unknown</td> </tr> @@ -8603,7 +8603,7 @@ and <I>POD class</I></td> </tr> <tr id="1465"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1465">1465</a></td> - <td>CD4</td> + <td>DR</td> <td><TT>noexcept</TT> and <TT>std::bad_array_new_length</TT></td> <td class="none" align="center">Unknown</td> </tr> @@ -8615,7 +8615,7 @@ and <I>POD class</I></td> </tr> <tr id="1467"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1467">1467</a></td> - <td>CD4</td> + <td>DR</td> <td>List-initialization of aggregate from same-type object</td> <td class="full" align="center">Clang 3.7 (C++11 onwards)</td> </tr> @@ -8717,7 +8717,7 @@ and <I>POD class</I></td> </tr> <tr id="1484"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1484">1484</a></td> - <td>CD4</td> + <td>DR</td> <td>Unused local classes of function templates</td> <td class="none" align="center">Unknown</td> </tr> @@ -8753,7 +8753,7 @@ and <I>POD class</I></td> </tr> <tr id="1490"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1490">1490</a></td> - <td>CD4</td> + <td>DR</td> <td>List-initialization from a string literal</td> <td class="full" align="center">Clang 3.7 (C++11 onwards)</td> </tr> @@ -8765,7 +8765,7 @@ and <I>POD class</I></td> </tr> <tr id="1492"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1492">1492</a></td> - <td>CD4</td> + <td>DR</td> <td>Exception specifications on template destructors</td> <td class="none" align="center">Unknown</td> </tr> @@ -8785,13 +8785,13 @@ and <I>POD class</I></td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1495">1495</a></td> <td>CD3</td> <td>Partial specialization of variadic class template</td> - <td class="full" align="center">Clang 4</td> + <td class="none" align="center">Unknown</td> </tr> - <tr id="1496"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1496">1496</a></td> - <td>CD4</td> + <tr class="open" id="1496"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1496">1496</a></td> + <td>drafting</td> <td>Triviality with deleted and missing default constructors</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr id="1497"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1497">1497</a></td> @@ -8887,7 +8887,7 @@ and <I>POD class</I></td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1512">1512</a></td> <td>CD3</td> <td>Pointer comparison vs qualification conversions</td> - <td class="full" align="center">Clang 4</td> + <td class="none" align="center">Unknown</td> </tr> <tr class="open" id="1513"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1513">1513</a></td> @@ -8919,11 +8919,11 @@ and <I>POD class</I></td> <td>Unclear/missing description of behavior during construction/destruction</td> <td align="center">Not resolved</td> </tr> - <tr id="1518"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1518">1518</a></td> - <td>CD4</td> + <tr class="open" id="1518"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1518">1518</a></td> + <td>drafting</td> <td>Explicit default constructors and copy-list-initialization</td> - <td class="full" align="center">Clang 4</td> + <td align="center">Not resolved</td> </tr> <tr id="1519"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1519">1519</a></td> @@ -8949,11 +8949,11 @@ and <I>POD class</I></td> <td>Access checking for <TT>initializer_list</TT> array initialization</td> <td class="none" align="center">Unknown</td> </tr> - <tr id="1523"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1523">1523</a></td> - <td>DRWP</td> + <tr class="open" id="1523"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1523">1523</a></td> + <td>drafting</td> <td>Point of declaration in range-based <TT>for</TT></td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr class="open" id="1524"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1524">1524</a></td> @@ -9125,7 +9125,7 @@ and <I>POD class</I></td> </tr> <tr id="1552"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1552">1552</a></td> - <td>CD4</td> + <td>DR</td> <td><I>exception-specification</I>s and defaulted special member functions</td> <td class="none" align="center">Unknown</td> </tr> @@ -9161,7 +9161,7 @@ and <I>POD class</I></td> </tr> <tr id="1558"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1558">1558</a></td> - <td>CD4</td> + <td>DR</td> <td>Unused arguments in alias template specializations</td> <td class="none" align="center">Unknown</td> </tr> @@ -9201,11 +9201,11 @@ and <I>POD class</I></td> <td>Template argument deduction from an initializer list</td> <td class="none" align="center">Unknown</td> </tr> - <tr id="1565"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1565">1565</a></td> - <td>NAD</td> + <tr class="open" id="1565"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1565">1565</a></td> + <td>drafting</td> <td>Copy elision and lifetime of <TT>initializer_list</TT> underlying array</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr id="1566"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1566">1566</a></td> @@ -9239,21 +9239,21 @@ and <I>POD class</I></td> </tr> <tr id="1571"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1571">1571</a></td> - <td>CD4</td> + <td>DR</td> <td>cv-qualification for indirect reference binding via conversion function</td> <td class="none" align="center">Unknown</td> </tr> <tr id="1572"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1572">1572</a></td> - <td>CD4</td> + <td>DR</td> <td>Incorrect example for rvalue reference binding via conversion function</td> <td class="none" align="center">Unknown</td> </tr> <tr id="1573"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1573">1573</a></td> - <td>CD4</td> + <td>DR</td> <td>Inherited constructor characteristics</td> - <td class="full" align="center">Clang 3.9</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="1574"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1574">1574</a></td> @@ -9289,7 +9289,7 @@ and <I>POD class</I></td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1579">1579</a></td> <td>C++14</td> <td>Return by converting move constructor</td> - <td class="full" align="center">Clang 3.9</td> + <td class="none" align="center">Unknown</td> </tr> <tr class="open" id="1580"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1580">1580</a></td> @@ -9305,7 +9305,7 @@ and <I>POD class</I></td> </tr> <tr class="open" id="1582"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1582">1582</a></td> - <td>drafting</td> + <td>open</td> <td>Template default arguments and deduction failure</td> <td align="center">Not resolved</td> </tr> @@ -9317,7 +9317,7 @@ and <I>POD class</I></td> </tr> <tr class="open" id="1584"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1584">1584</a></td> - <td>drafting</td> + <td>open</td> <td>Deducing function types from cv-qualified types</td> <td align="center">Not resolved</td> </tr> @@ -9347,7 +9347,7 @@ and <I>POD class</I></td> </tr> <tr id="1589"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1589">1589</a></td> - <td>CD4</td> + <td>DR</td> <td>Ambiguous ranking of list-initialization sequences</td> <td class="full" align="center">Clang 3.7 (C++11 onwards)</td> </tr> @@ -9359,7 +9359,7 @@ and <I>POD class</I></td> </tr> <tr id="1591"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1591">1591</a></td> - <td>CD4</td> + <td>DR</td> <td>Deducing array bound and element type from initializer list</td> <td class="none" align="center">Unknown</td> </tr> @@ -9389,7 +9389,7 @@ and <I>POD class</I></td> </tr> <tr id="1596"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1596">1596</a></td> - <td>CD4</td> + <td>DR</td> <td>Non-array objects as <TT>array[1]</TT></td> <td class="none" align="center">Unknown</td> </tr> @@ -9413,7 +9413,7 @@ and <I>POD class</I></td> </tr> <tr id="1600"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1600">1600</a></td> - <td>CD4</td> + <td>DR</td> <td>Erroneous reference initialization in example</td> <td class="none" align="center">Unknown</td> </tr> @@ -9431,7 +9431,7 @@ and <I>POD class</I></td> </tr> <tr id="1603"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1603">1603</a></td> - <td>CD4</td> + <td>DR</td> <td>Errors resulting from giving unnamed namespaces internal linkage</td> <td class="none" align="center">Unknown</td> </tr> @@ -9481,7 +9481,7 @@ and <I>POD class</I></td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1611">1611</a></td> <td>C++14</td> <td>Deleted default constructor for abstract class</td> - <td class="full" align="center">Duplicate of <a href="#1658">1658</a></td> + <td class="none" align="center">Unknown</td> </tr> <tr id="1612"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1612">1612</a></td> @@ -9497,13 +9497,13 @@ and <I>POD class</I></td> </tr> <tr id="1614"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1614">1614</a></td> - <td>CD4</td> + <td>DR</td> <td>Address of pure virtual function vs odr-use</td> <td class="none" align="center">Unknown</td> </tr> <tr id="1615"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1615">1615</a></td> - <td>CD4</td> + <td>DR</td> <td>Alignment of types, variables, and members</td> <td class="none" align="center">Unknown</td> </tr> @@ -9543,11 +9543,11 @@ and <I>POD class</I></td> <td>Member initializers in anonymous unions</td> <td align="center">Not resolved</td> </tr> - <tr id="1622"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1622">1622</a></td> - <td>C++17</td> + <tr class="open" id="1622"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1622">1622</a></td> + <td>drafting</td> <td>Empty aggregate initializer for union</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr class="open" id="1623"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1623">1623</a></td> @@ -9593,15 +9593,15 @@ and <I>POD class</I></td> </tr> <tr id="1630"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1630">1630</a></td> - <td>CD4</td> + <td>DR</td> <td>Multiple default constructor templates</td> <td class="none" align="center">Unknown</td> </tr> <tr id="1631"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1631">1631</a></td> - <td>CD4</td> + <td>DR</td> <td>Incorrect overload resolution for single-element <I>initializer-list</I></td> - <td class="full" align="center">Clang 3.7</td> + <td class="full" align="center">Clang 3.7 (C++11 onwards)</td> </tr> <tr class="open" id="1632"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1632">1632</a></td> @@ -9611,7 +9611,7 @@ and <I>POD class</I></td> </tr> <tr id="1633"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1633">1633</a></td> - <td>CD4</td> + <td>DR</td> <td>Copy-initialization in member initialization</td> <td class="none" align="center">Unknown</td> </tr> @@ -9639,15 +9639,15 @@ and <I>POD class</I></td> <td>Recursion in <TT>constexpr</TT> template default constructor</td> <td class="none" align="center">Unknown</td> </tr> - <tr id="1638"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1638">1638</a></td> - <td>CD4</td> + <tr class="open" id="1638"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1638">1638</a></td> + <td>drafting</td> <td>Declaring an explicit specialization of a scoped enumeration</td> - <td class="full" align="center">Yes</td> + <td align="center">Not resolved</td> </tr> <tr id="1639"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1639">1639</a></td> - <td>CD4</td> + <td>DR</td> <td><I>exception-specification</I>s and pointer/pointer-to-member expressions</td> <td class="none" align="center">Unknown</td> </tr> @@ -9681,11 +9681,11 @@ and <I>POD class</I></td> <td>Equivalent <I>exception-specification</I>s in function template declarations</td> <td align="center">Not resolved</td> </tr> - <tr id="1645"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1645">1645</a></td> - <td>CD4</td> + <tr class="open" id="1645"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1645">1645</a></td> + <td>drafting</td> <td>Identical inheriting constructors via default arguments</td> - <td class="full" align="center">Clang 3.9</td> + <td align="center">Not resolved</td> </tr> <tr class="open" id="1646"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1646">1646</a></td> @@ -9724,16 +9724,16 @@ and <I>POD class</I></td> <td align="center">Not resolved</td> </tr> <tr id="1652"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1652">1652</a></td> - <td>CD4</td> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1652">1652</a></td> + <td>ready</td> <td>Object addresses in <TT>constexpr</TT> expressions</td> <td class="none" align="center">Unknown</td> </tr> - <tr id="1653"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1653">1653</a></td> - <td>CD4</td> + <tr class="open" id="1653"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1653">1653</a></td> + <td>drafting</td> <td>Removing deprecated increment of <TT>bool</TT></td> - <td class="full" align="center">Clang 4 (C++17 onwards)</td> + <td align="center">Not resolved</td> </tr> <tr id="1654"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1654">1654</a></td> @@ -9755,7 +9755,7 @@ and <I>POD class</I></td> </tr> <tr id="1657"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1657">1657</a></td> - <td>CD4</td> + <td>accepted</td> <td>Attributes for namespaces and enumerators</td> <td class="none" align="center">Unknown</td> </tr> @@ -9763,7 +9763,7 @@ and <I>POD class</I></td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1658">1658</a></td> <td>C++14</td> <td>Deleted default constructor for abstract class via destructor</td> - <td class="full" align="center">Clang 5</td> + <td class="none" align="center">Unknown</td> </tr> <tr class="open" id="1659"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1659">1659</a></td> @@ -9777,11 +9777,11 @@ and <I>POD class</I></td> <td><I>member-declaration</I> requirements and unnamed bit-fields</td> <td class="none" align="center">Unknown</td> </tr> - <tr id="1661"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1661">1661</a></td> - <td>NAD</td> + <tr class="open" id="1661"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1661">1661</a></td> + <td>concurrency</td> <td>Preservation of infinite loops</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr id="1662"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1662">1662</a></td> @@ -9845,9 +9845,9 @@ and <I>POD class</I></td> </tr> <tr id="1672"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1672">1672</a></td> - <td>CD4</td> + <td>DR</td> <td>Layout compatibility with multiple empty bases</td> - <td class="svn" align="center">Clang 7</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="1673"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1673">1673</a></td> @@ -9873,11 +9873,11 @@ and <I>POD class</I></td> <td><TT>auto</TT> return type for allocation and deallocation functions</td> <td align="center">Not resolved</td> </tr> - <tr id="1677"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1677">1677</a></td> - <td>C++17</td> + <tr class="open" id="1677"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1677">1677</a></td> + <td>drafting</td> <td>Constant initialization via aggregate initialization</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr id="1678"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1678">1678</a></td> @@ -9911,7 +9911,7 @@ and <I>POD class</I></td> </tr> <tr id="1683"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1683">1683</a></td> - <td>CD4</td> + <td>DRWP</td> <td>Incorrect example after <TT>constexpr</TT> changes</td> <td class="none" align="center">Unknown</td> </tr> @@ -9929,7 +9929,7 @@ and <I>POD class</I></td> </tr> <tr id="1686"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1686">1686</a></td> - <td>CD4</td> + <td>DR</td> <td>Which variables are “explicitly declared <TT>const</TT>?”</td> <td class="none" align="center">Unknown</td> </tr> @@ -9937,7 +9937,7 @@ and <I>POD class</I></td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1687">1687</a></td> <td>C++14</td> <td>Conversions of operands of built-in operators</td> - <td class="svn" align="center">Clang 7</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="1688"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1688">1688</a></td> @@ -9977,7 +9977,7 @@ and <I>POD class</I></td> </tr> <tr id="1694"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1694">1694</a></td> - <td>CD4</td> + <td>DR</td> <td>Restriction on reference to temporary as a constant expression</td> <td class="none" align="center">Unknown</td> </tr> @@ -9989,9 +9989,9 @@ and <I>POD class</I></td> </tr> <tr id="1696"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1696">1696</a></td> - <td>CD4</td> + <td>DR</td> <td>Temporary lifetime and non-static data member initializers</td> - <td class="svn" align="center">Clang 7</td> + <td class="none" align="center">Unknown</td> </tr> <tr class="open" id="1697"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1697">1697</a></td> @@ -10035,15 +10035,15 @@ and <I>POD class</I></td> <td>Language linkage of names of functions with internal linkage</td> <td class="none" align="center">Unknown</td> </tr> - <tr id="1704"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1704">1704</a></td> - <td>DRWP</td> + <tr class="open" id="1704"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1704">1704</a></td> + <td>drafting</td> <td>Type checking in explicit instantiation of variable templates</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr id="1705"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1705">1705</a></td> - <td>CD4</td> + <td>DR</td> <td>Unclear specification of “more specialized”</td> <td class="none" align="center">Unknown</td> </tr> @@ -10061,7 +10061,7 @@ and <I>POD class</I></td> </tr> <tr id="1708"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1708">1708</a></td> - <td>CD4</td> + <td>DR</td> <td>overly-strict requirements for names with C language linkage</td> <td class="none" align="center">Unknown</td> </tr> @@ -10071,11 +10071,11 @@ and <I>POD class</I></td> <td>Stringizing raw string literals containing newline</td> <td align="center">Not resolved</td> </tr> - <tr id="1710"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1710">1710</a></td> - <td>C++17</td> + <tr class="open" id="1710"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1710">1710</a></td> + <td>review</td> <td>Missing <TT>template</TT> keyword in <I>class-or-decltype</I></td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr class="open" id="1711"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1711">1711</a></td> @@ -10085,7 +10085,7 @@ and <I>POD class</I></td> </tr> <tr id="1712"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1712">1712</a></td> - <td>CD4</td> + <td>DR</td> <td><TT>constexpr</TT> variable template declarations</td> <td class="none" align="center">Unknown</td> </tr> @@ -10101,11 +10101,11 @@ and <I>POD class</I></td> <td>odr-use of <TT>this</TT> from a local class</td> <td class="none" align="center">Unknown</td> </tr> - <tr id="1715"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1715">1715</a></td> - <td>CD4</td> + <tr class="open" id="1715"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1715">1715</a></td> + <td>drafting</td> <td>Access and inherited constructor templates</td> - <td class="full" align="center">Clang 3.9</td> + <td align="center">Not resolved</td> </tr> <tr id="1716"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1716">1716</a></td> @@ -10127,7 +10127,7 @@ and <I>POD class</I></td> </tr> <tr id="1719"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1719">1719</a></td> - <td>CD4</td> + <td>DR</td> <td>Layout compatibility and cv-qualification revisited</td> <td class="none" align="center">Unknown</td> </tr> @@ -10143,11 +10143,11 @@ and <I>POD class</I></td> <td>Diagnosing ODR violations for static data members</td> <td align="center">Not resolved</td> </tr> - <tr id="1722"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1722">1722</a></td> - <td>CD4</td> + <tr class="open" id="1722"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1722">1722</a></td> + <td>drafting</td> <td>Should lambda to function pointer conversion function be <TT>noexcept</TT>?</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr class="open" id="1723"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1723">1723</a></td> @@ -10179,11 +10179,11 @@ and <I>POD class</I></td> <td>Type of a specialization of a variable template</td> <td class="none" align="center">Unknown</td> </tr> - <tr id="1728"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1728">1728</a></td> - <td>DRWP</td> + <tr class="open" id="1728"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1728">1728</a></td> + <td>drafting</td> <td>Type of an explicit instantiation of a variable template</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr class="open" id="1729"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1729">1729</a></td> @@ -10215,11 +10215,11 @@ and <I>POD class</I></td> <td>Return type and value for <TT>operator=</TT> with <I>ref-qualifier</I></td> <td align="center">Not resolved</td> </tr> - <tr id="1734"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1734">1734</a></td> - <td>CD4</td> + <tr class="open" id="1734"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1734">1734</a></td> + <td>drafting</td> <td>Nontrivial deleted copy functions</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr class="open" id="1735"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1735">1735</a></td> @@ -10227,11 +10227,11 @@ and <I>POD class</I></td> <td>Out-of-range literals in <I>user-defined-literal</I>s</td> <td align="center">Not resolved</td> </tr> - <tr id="1736"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1736">1736</a></td> - <td>CD4</td> + <tr class="open" id="1736"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1736">1736</a></td> + <td>drafting</td> <td>Inheriting constructor templates in a local class</td> - <td class="full" align="center">Clang 3.9</td> + <td align="center">Not resolved</td> </tr> <tr id="1737"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1737">1737</a></td> @@ -10269,15 +10269,15 @@ and <I>POD class</I></td> <td><I>using-declaration</I>s and scoped enumerators</td> <td align="center">Not resolved</td> </tr> - <tr id="1743"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1743">1743</a></td> - <td>NAD</td> + <tr class="open" id="1743"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1743">1743</a></td> + <td>open</td> <td><I>init-capture</I>s in nested lambdas</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr id="1744"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1744">1744</a></td> - <td>CD4</td> + <td>DR</td> <td>Unordered initialization for variable template specializations</td> <td class="none" align="center">Unknown</td> </tr> @@ -10301,7 +10301,7 @@ and <I>POD class</I></td> </tr> <tr id="1748"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1748">1748</a></td> - <td>CD4</td> + <td>DR</td> <td>Placement new with a null pointer</td> <td class="full" align="center">Clang 3.7</td> </tr> @@ -10313,25 +10313,25 @@ and <I>POD class</I></td> </tr> <tr id="1750"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1750">1750</a></td> - <td>CD4</td> + <td>DR</td> <td>“Argument” vs “parameter”</td> <td class="none" align="center">Unknown</td> </tr> <tr id="1751"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1751">1751</a></td> - <td>CD4</td> + <td>DR</td> <td>Non-trivial operations vs non-trivial initialization</td> <td class="none" align="center">Unknown</td> </tr> <tr id="1752"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1752">1752</a></td> - <td>CD4</td> + <td>DR</td> <td>Right-recursion in <I>mem-initializer-list</I></td> <td class="none" align="center">Unknown</td> </tr> <tr id="1753"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1753">1753</a></td> - <td>CD4</td> + <td>DR</td> <td><I>decltype-specifier</I> in <I>nested-name-specifier</I> of destructor</td> <td class="none" align="center">Unknown</td> </tr> @@ -10349,21 +10349,21 @@ and <I>POD class</I></td> </tr> <tr id="1756"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1756">1756</a></td> - <td>CD4</td> + <td>DR</td> <td>Direct-list-initialization of a non-class object</td> - <td class="full" align="center">Clang 3.7</td> + <td class="full" align="center">Clang 3.7 (C++11 onwards)</td> </tr> <tr id="1757"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1757">1757</a></td> - <td>CD4</td> + <td>DR</td> <td>Const integral subobjects</td> <td class="none" align="center">Unknown</td> </tr> <tr id="1758"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1758">1758</a></td> - <td>CD4</td> + <td>DR</td> <td>Explicit conversion in copy/move list initialization</td> - <td class="full" align="center">Clang 3.7</td> + <td class="full" align="center">Clang 3.7 (C++11 onwards)</td> </tr> <tr id="1759"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1759">1759</a></td> @@ -10409,7 +10409,7 @@ and <I>POD class</I></td> </tr> <tr id="1766"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1766">1766</a></td> - <td>CD4</td> + <td>DR</td> <td>Values outside the range of the values of an enumeration</td> <td class="none" align="center">Unknown</td> </tr> @@ -10457,7 +10457,7 @@ and <I>POD class</I></td> </tr> <tr id="1774"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1774">1774</a></td> - <td>CD4</td> + <td>DR</td> <td>Discrepancy between subobject destruction and stack unwinding</td> <td class="none" align="center">Unknown</td> </tr> @@ -10467,15 +10467,15 @@ and <I>POD class</I></td> <td>Undefined behavior of line splice in raw string literal</td> <td class="none" align="center">Unknown</td> </tr> - <tr id="1776"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1776">1776</a></td> - <td>CD4</td> + <tr class="open" id="1776"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1776">1776</a></td> + <td>drafting</td> <td>Replacement of class objects containing reference members</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr id="1777"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1777">1777</a></td> - <td>CD4</td> + <td>DR</td> <td>Empty pack expansion in <I>dynamic-exception-specification</I></td> <td class="none" align="center">Unknown</td> </tr> @@ -10487,13 +10487,13 @@ and <I>POD class</I></td> </tr> <tr id="1779"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1779">1779</a></td> - <td>CD4</td> + <td>DR</td> <td>Type dependency of <TT>__func__</TT></td> <td class="none" align="center">Unknown</td> </tr> <tr id="1780"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1780">1780</a></td> - <td>CD4</td> + <td>DR</td> <td>Explicit instantiation/specialization of generic lambda <TT>operator()</TT></td> <td class="none" align="center">Unknown</td> </tr> @@ -10505,7 +10505,7 @@ and <I>POD class</I></td> </tr> <tr id="1782"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1782">1782</a></td> - <td>CD4</td> + <td>DR</td> <td>Form of initialization for <TT>nullptr_t</TT> to <TT>bool</TT> conversion</td> <td class="none" align="center">Unknown</td> </tr> @@ -10515,17 +10515,17 @@ and <I>POD class</I></td> <td>Why are virtual destructors non-trivial?</td> <td class="none" align="center">Unknown</td> </tr> - <tr id="1784"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1784">1784</a></td> - <td>C++17</td> + <tr class="open" id="1784"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1784">1784</a></td> + <td>concurrency</td> <td>Concurrent execution during static local initialization</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> - <tr id="1785"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1785">1785</a></td> - <td>NAD</td> + <tr class="open" id="1785"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1785">1785</a></td> + <td>drafting</td> <td>Conflicting diagnostic requirements for template definitions</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr id="1786"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1786">1786</a></td> @@ -10541,7 +10541,7 @@ and <I>POD class</I></td> </tr> <tr id="1788"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1788">1788</a></td> - <td>CD4</td> + <td>DR</td> <td>Sized deallocation of array of non-class type</td> <td class="none" align="center">Unknown</td> </tr> @@ -10559,7 +10559,7 @@ and <I>POD class</I></td> </tr> <tr id="1791"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1791">1791</a></td> - <td>CD4</td> + <td>DR</td> <td>Incorrect restrictions on <I>cv-qualifier-seq</I> and <I>ref-qualifier</I></td> <td class="none" align="center">Unknown</td> </tr> @@ -10571,31 +10571,31 @@ and <I>POD class</I></td> </tr> <tr id="1793"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1793">1793</a></td> - <td>CD4</td> + <td>DR</td> <td><TT>thread_local</TT> in explicit specializations</td> <td class="none" align="center">Unknown</td> </tr> - <tr id="1794"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1794">1794</a></td> - <td>C++17</td> + <tr class="open" id="1794"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1794">1794</a></td> + <td>review</td> <td><TT>template</TT> keyword and alias templates</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr id="1795"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1795">1795</a></td> - <td>CD4</td> + <td>DR</td> <td>Disambiguating <I>original-namespace-definition</I> and <I>extension-namespace-definition</I></td> <td class="none" align="center">Unknown</td> </tr> <tr id="1796"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1796">1796</a></td> - <td>CD4</td> + <td>DR</td> <td>Is all-bits-zero for null characters a meaningful requirement?</td> <td class="none" align="center">Unknown</td> </tr> <tr id="1797"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1797">1797</a></td> - <td>CD4</td> + <td>DR</td> <td>Are all bit patterns of <TT>unsigned char</TT> distinct numbers?</td> <td class="none" align="center">Unknown</td> </tr> @@ -10607,13 +10607,13 @@ and <I>POD class</I></td> </tr> <tr id="1799"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1799">1799</a></td> - <td>CD4</td> + <td>DR</td> <td><TT>mutable</TT> and non-explicit const qualification</td> <td class="none" align="center">Unknown</td> </tr> <tr id="1800"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1800">1800</a></td> - <td>CD4</td> + <td>DR</td> <td>Pointer to member of nested anonymous union</td> <td class="none" align="center">Unknown</td> </tr> @@ -10625,7 +10625,7 @@ and <I>POD class</I></td> </tr> <tr id="1802"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1802">1802</a></td> - <td>CD4</td> + <td>DR</td> <td><TT>char16_t</TT> string literals and surrogate pairs</td> <td class="none" align="center">Unknown</td> </tr> @@ -10637,79 +10637,79 @@ and <I>POD class</I></td> </tr> <tr id="1804"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1804">1804</a></td> - <td>CD4</td> + <td>DR</td> <td>Partial specialization and friendship</td> <td class="none" align="center">Unknown</td> </tr> <tr id="1805"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1805">1805</a></td> - <td>CD4</td> + <td>DR</td> <td>Conversions of array operands in <I>conditional-expression</I>s</td> <td class="none" align="center">Unknown</td> </tr> <tr id="1806"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1806">1806</a></td> - <td>CD4</td> + <td>DR</td> <td>Virtual bases and move-assignment</td> <td class="none" align="center">Unknown</td> </tr> <tr id="1807"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1807">1807</a></td> - <td>CD4</td> + <td>DR</td> <td>Order of destruction of array elements after an exception</td> <td class="none" align="center">Unknown</td> </tr> <tr class="open" id="1808"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1808">1808</a></td> - <td>drafting</td> + <td>open</td> <td>Constructor templates vs default constructors</td> <td align="center">Not resolved</td> </tr> <tr id="1809"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1809">1809</a></td> - <td>CD4</td> + <td>DR</td> <td>Narrowing and template argument deduction</td> <td class="none" align="center">Unknown</td> </tr> <tr id="1810"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1810">1810</a></td> - <td>CD4</td> + <td>DR</td> <td>Invalid <I>ud-suffix</I>es</td> <td class="none" align="center">Unknown</td> </tr> <tr id="1811"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1811">1811</a></td> - <td>CD4</td> + <td>DR</td> <td>Lookup of deallocation function in a virtual destructor definition</td> <td class="none" align="center">Unknown</td> </tr> - <tr id="1812"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1812">1812</a></td> - <td>C++17</td> + <tr class="open" id="1812"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1812">1812</a></td> + <td>review</td> <td>Omission of <TT>template</TT> in a <I>typename-specifier</I></td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr id="1813"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1813">1813</a></td> - <td>CD4</td> + <td>DR</td> <td>Direct vs indirect bases in standard-layout classes</td> - <td class="svn" align="center">Clang 7</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="1814"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1814">1814</a></td> - <td>CD4</td> + <td>DR</td> <td>Default arguments in <I>lambda-expression</I>s</td> <td class="none" align="center">Unknown</td> </tr> <tr id="1815"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1815">1815</a></td> - <td>CD4</td> + <td>DR</td> <td>Lifetime extension in aggregate initialization</td> - <td class="none" align="center">No</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="1816"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1816">1816</a></td> - <td>CD4</td> + <td>DR</td> <td>Unclear specification of bit-field values</td> <td class="none" align="center">Unknown</td> </tr> @@ -10727,7 +10727,7 @@ and <I>POD class</I></td> </tr> <tr id="1819"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1819">1819</a></td> - <td>CD4</td> + <td>DR</td> <td>Acceptable scopes for definition of partial specialization</td> <td class="none" align="center">Unknown</td> </tr> @@ -10751,27 +10751,27 @@ and <I>POD class</I></td> </tr> <tr id="1823"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1823">1823</a></td> - <td>CD4</td> + <td>DR</td> <td>String literal uniqueness in inline functions</td> <td class="none" align="center">Unknown</td> </tr> <tr id="1824"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1824">1824</a></td> - <td>CD4</td> + <td>DR</td> <td>Completeness of return type vs point of instantiation</td> <td class="none" align="center">Unknown</td> </tr> - <tr id="1825"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1825">1825</a></td> - <td>C++17</td> + <tr class="open" id="1825"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1825">1825</a></td> + <td>drafting</td> <td>Partial ordering between variadic and non-variadic function templates</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> - <tr id="1826"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1826">1826</a></td> - <td>NAD</td> + <tr class="open" id="1826"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1826">1826</a></td> + <td>open</td> <td><TT>const</TT> floating-point in constant expressions</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr class="open" id="1827"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1827">1827</a></td> @@ -10793,7 +10793,7 @@ and <I>POD class</I></td> </tr> <tr id="1830"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1830">1830</a></td> - <td>CD4</td> + <td>DR</td> <td>Repeated specifiers</td> <td class="none" align="center">Unknown</td> </tr> @@ -10805,7 +10805,7 @@ and <I>POD class</I></td> </tr> <tr id="1832"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1832">1832</a></td> - <td>CD4</td> + <td>DR</td> <td>Casting to incomplete enumeration</td> <td class="none" align="center">Unknown</td> </tr> @@ -10817,7 +10817,7 @@ and <I>POD class</I></td> </tr> <tr id="1834"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1834">1834</a></td> - <td>CD4</td> + <td>DR</td> <td>Constant initialization binding a reference to an xvalue</td> <td class="none" align="center">Unknown</td> </tr> @@ -10827,11 +10827,11 @@ and <I>POD class</I></td> <td>Dependent member lookup before <TT><</TT></td> <td align="center">Not resolved</td> </tr> - <tr id="1836"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1836">1836</a></td> - <td>DRWP</td> + <tr class="open" id="1836"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1836">1836</a></td> + <td>drafting</td> <td>Use of class type being defined in <I>trailing-return-type</I></td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr class="open" id="1837"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1837">1837</a></td> @@ -10841,7 +10841,7 @@ and <I>POD class</I></td> </tr> <tr id="1838"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1838">1838</a></td> - <td>CD4</td> + <td>DR</td> <td>Definition via <I>unqualified-id</I> and <I>using-declaration</I></td> <td class="none" align="center">Unknown</td> </tr> @@ -10871,7 +10871,7 @@ and <I>POD class</I></td> </tr> <tr id="1843"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1843">1843</a></td> - <td>CD4</td> + <td>DR</td> <td>Bit-field in conditional operator with <TT>throw</TT> operand</td> <td class="none" align="center">Unknown</td> </tr> @@ -10889,19 +10889,19 @@ and <I>POD class</I></td> </tr> <tr id="1846"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1846">1846</a></td> - <td>CD4</td> + <td>DR</td> <td>Declaring explicitly-defaulted implicitly-deleted functions</td> <td class="none" align="center">Unknown</td> </tr> - <tr id="1847"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1847">1847</a></td> - <td>CD4</td> + <tr class="open" id="1847"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1847">1847</a></td> + <td>drafting</td> <td>Clarifying compatibility during partial ordering</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr id="1848"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1848">1848</a></td> - <td>CD4</td> + <td>DR</td> <td>Parenthesized constructor and destructor declarators</td> <td class="none" align="center">Unknown</td> </tr> @@ -10913,19 +10913,19 @@ and <I>POD class</I></td> </tr> <tr id="1850"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1850">1850</a></td> - <td>CD4</td> + <td>DR</td> <td>Differences between definition context and point of instantiation</td> <td class="none" align="center">Unknown</td> </tr> <tr id="1851"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1851">1851</a></td> - <td>CD4</td> + <td>DR</td> <td><TT>decltype(auto)</TT> in <I>new-expression</I>s</td> <td class="none" align="center">Unknown</td> </tr> <tr id="1852"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1852">1852</a></td> - <td>CD4</td> + <td>DR</td> <td>Wording issues regarding <TT>decltype(auto)</TT></td> <td class="none" align="center">Unknown</td> </tr> @@ -10961,7 +10961,7 @@ and <I>POD class</I></td> </tr> <tr id="1858"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1858">1858</a></td> - <td>CD4</td> + <td>DR</td> <td>Comparing pointers to union members</td> <td class="none" align="center">Unknown</td> </tr> @@ -10971,29 +10971,29 @@ and <I>POD class</I></td> <td>UTF-16 in <TT>char16_t</TT> string literals</td> <td align="center">Not resolved</td> </tr> - <tr id="1860"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1860">1860</a></td> - <td>C++17</td> + <tr class="open" id="1860"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1860">1860</a></td> + <td>drafting</td> <td>What is a “direct member?”</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> - <tr id="1861"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1861">1861</a></td> - <td>CD4</td> + <tr class="open" id="1861"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1861">1861</a></td> + <td>drafting</td> <td>Values of a bit-field</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> - <tr id="1862"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1862">1862</a></td> - <td>DR</td> + <tr class="open" id="1862"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1862">1862</a></td> + <td>drafting</td> <td>Determining “corresponding members” for friendship</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> - <tr id="1863"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1863">1863</a></td> - <td>CD4</td> + <tr class="open" id="1863"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1863">1863</a></td> + <td>drafting</td> <td>Requirements on thrown object type to support <TT>std::current_exception()</TT></td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr class="open" id="1864"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1864">1864</a></td> @@ -11003,13 +11003,13 @@ and <I>POD class</I></td> </tr> <tr id="1865"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1865">1865</a></td> - <td>CD4</td> + <td>DR</td> <td>Pointer arithmetic and multi-level qualification conversions</td> <td class="none" align="center">Unknown</td> </tr> <tr id="1866"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1866">1866</a></td> - <td>CD4</td> + <td>DR</td> <td>Initializing variant members with non-trivial destructors</td> <td class="none" align="center">Unknown</td> </tr> @@ -11033,7 +11033,7 @@ and <I>POD class</I></td> </tr> <tr id="1870"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1870">1870</a></td> - <td>CD4</td> + <td>DR</td> <td>Contradictory wording about definitions vs explicit specialization/instantiation</td> <td class="none" align="center">Unknown</td> </tr> @@ -11043,27 +11043,27 @@ and <I>POD class</I></td> <td>Non-identifier characters in <I>ud-suffix</I></td> <td align="center">Not resolved</td> </tr> - <tr id="1872"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1872">1872</a></td> - <td>CD4</td> + <tr class="open" id="1872"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1872">1872</a></td> + <td>drafting</td> <td>Instantiations of <TT>constexpr</TT> templates that cannot appear in constant expressions</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr id="1873"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1873">1873</a></td> - <td>CD4</td> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1873">1873</a></td> + <td>ready</td> <td>Protected member access from derived class friends</td> <td class="none" align="center">Unknown</td> </tr> <tr id="1874"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1874">1874</a></td> - <td>CD4</td> + <td>DR</td> <td>Type vs non-type template parameters with <TT>class</TT> keyword</td> <td class="none" align="center">Unknown</td> </tr> <tr id="1875"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1875">1875</a></td> - <td>CD4</td> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1875">1875</a></td> + <td>ready</td> <td>Reordering declarations in class scope</td> <td class="none" align="center">Unknown</td> </tr> @@ -11075,13 +11075,13 @@ and <I>POD class</I></td> </tr> <tr id="1877"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1877">1877</a></td> - <td>CD4</td> + <td>DR</td> <td>Return type deduction from <TT>return</TT> with no operand</td> <td class="none" align="center">Unknown</td> </tr> <tr id="1878"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1878">1878</a></td> - <td>CD4</td> + <td>DR</td> <td><TT>operator auto</TT> template</td> <td class="none" align="center">Unknown</td> </tr> @@ -11099,13 +11099,13 @@ and <I>POD class</I></td> </tr> <tr id="1881"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1881">1881</a></td> - <td>CD4</td> + <td>DR</td> <td>Standard-layout classes and unnamed bit-fields</td> - <td class="svn" align="center">Clang 7</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="1882"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1882">1882</a></td> - <td>CD4</td> + <td>DR</td> <td>Reserved names without library use</td> <td class="none" align="center">Unknown</td> </tr> @@ -11123,25 +11123,25 @@ and <I>POD class</I></td> </tr> <tr id="1885"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1885">1885</a></td> - <td>CD4</td> + <td>DR</td> <td>Return value of a function is underspecified</td> <td class="none" align="center">Unknown</td> </tr> <tr id="1886"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1886">1886</a></td> - <td>CD4</td> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1886">1886</a></td> + <td>tentatively ready</td> <td>Language linkage for <TT>main()</TT></td> <td class="none" align="center">Unknown</td> </tr> <tr id="1887"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1887">1887</a></td> - <td>CD4</td> + <td>DR</td> <td>Problems with <TT>::</TT> as <I>nested-name-specifier</I></td> <td class="none" align="center">Unknown</td> </tr> <tr id="1888"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1888">1888</a></td> - <td>CD4</td> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1888">1888</a></td> + <td>tentatively ready</td> <td>Implicitly-declared default constructors and <TT>explicit</TT></td> <td class="none" align="center">Unknown</td> </tr> @@ -11159,21 +11159,21 @@ and <I>POD class</I></td> </tr> <tr id="1891"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1891">1891</a></td> - <td>CD4</td> + <td>DR</td> <td>Move constructor/assignment for closure class</td> - <td class="full" align="center">Clang 4</td> + <td class="full" align="center">Clang 3.6</td> </tr> <tr id="1892"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1892">1892</a></td> - <td>CD4</td> + <td>DR</td> <td>Use of <TT>auto</TT> in function type</td> <td class="none" align="center">Unknown</td> </tr> - <tr id="1893"> + <tr class="open" id="1893"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1893">1893</a></td> - <td>tentatively ready</td> + <td>drafting</td> <td>Function-style cast with <I>braced-init-list</I>s and empty pack expansions</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr class="open" id="1894"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1894">1894</a></td> @@ -11181,11 +11181,11 @@ and <I>POD class</I></td> <td><I>typedef-name</I>s and <I>using-declaration</I>s</td> <td align="center">Not resolved</td> </tr> - <tr id="1895"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1895">1895</a></td> - <td>CD4</td> + <tr class="open" id="1895"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1895">1895</a></td> + <td>drafting</td> <td>Deleted conversions in conditional operator operands</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr class="open" id="1896"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1896">1896</a></td> @@ -11206,8 +11206,8 @@ and <I>POD class</I></td> <td align="center">Not resolved</td> </tr> <tr id="1899"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1899">1899</a></td> - <td>CD4</td> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1899">1899</a></td> + <td>tentatively ready</td> <td>Value-dependent constant expressions</td> <td class="none" align="center">Unknown</td> </tr> @@ -11225,15 +11225,15 @@ and <I>POD class</I></td> </tr> <tr id="1902"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1902">1902</a></td> - <td>CD4</td> + <td>DR</td> <td>What makes a conversion “otherwise ill-formed”?</td> <td class="full" align="center">Clang 3.7</td> </tr> - <tr id="1903"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1903">1903</a></td> - <td>CD4</td> + <tr class="open" id="1903"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1903">1903</a></td> + <td>open</td> <td>What declarations are introduced by a non-member <I>using-declaration</I>?</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr id="1904"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1904">1904</a></td> @@ -11249,13 +11249,13 @@ and <I>POD class</I></td> </tr> <tr class="open" id="1906"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1906">1906</a></td> - <td>review</td> + <td>drafting</td> <td>Name lookup in member <TT>friend</TT> declaration</td> <td align="center">Not resolved</td> </tr> <tr class="open" id="1907"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1907">1907</a></td> - <td>drafting</td> + <td>open</td> <td><I>using-declaration</I>s and default arguments</td> <td align="center">Not resolved</td> </tr> @@ -11267,19 +11267,19 @@ and <I>POD class</I></td> </tr> <tr id="1909"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1909">1909</a></td> - <td>CD4</td> + <td>DR</td> <td>Member class template with the same name as the class</td> <td class="full" align="center">Yes</td> </tr> - <tr id="1910"> + <tr class="open" id="1910"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1910">1910</a></td> - <td>tentatively ready</td> + <td>drafting</td> <td>“Shall” requirement applied to runtime behavior</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr id="1911"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1911">1911</a></td> - <td>CD4</td> + <td>DR</td> <td><TT>constexpr</TT> constructor with non-literal base class</td> <td class="none" align="center">Unknown</td> </tr> @@ -11308,8 +11308,8 @@ and <I>POD class</I></td> <td align="center">Not resolved</td> </tr> <tr id="1916"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1916">1916</a></td> - <td>CD4</td> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1916">1916</a></td> + <td>tentatively ready</td> <td>“Same cv-unqualified type”</td> <td class="none" align="center">Unknown</td> </tr> @@ -11332,8 +11332,8 @@ and <I>POD class</I></td> <td align="center">Not resolved</td> </tr> <tr id="1920"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1920">1920</a></td> - <td>CD4</td> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1920">1920</a></td> + <td>tentatively ready</td> <td>Qualification mismatch in <I>pseudo-destructor-name</I></td> <td class="none" align="center">Unknown</td> </tr> @@ -11344,8 +11344,8 @@ and <I>POD class</I></td> <td class="none" align="center">Unknown</td> </tr> <tr id="1922"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1922">1922</a></td> - <td>CD4</td> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1922">1922</a></td> + <td>tentatively ready</td> <td>Injected class template names and default arguments</td> <td class="none" align="center">Unknown</td> </tr> @@ -11357,19 +11357,19 @@ and <I>POD class</I></td> </tr> <tr class="open" id="1924"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1924">1924</a></td> - <td>review</td> + <td>drafting</td> <td>Definition of “literal” and kinds of literals</td> <td align="center">Not resolved</td> </tr> <tr id="1925"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1925">1925</a></td> - <td>CD4</td> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1925">1925</a></td> + <td>tentatively ready</td> <td>Bit-field prvalues</td> <td class="none" align="center">Unknown</td> </tr> <tr id="1926"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1926">1926</a></td> - <td>CD4</td> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1926">1926</a></td> + <td>tentatively ready</td> <td>Potential results of subscript operator</td> <td class="none" align="center">Unknown</td> </tr> @@ -11379,23 +11379,23 @@ and <I>POD class</I></td> <td>Lifetime of temporaries in <I>init-capture</I>s</td> <td class="none" align="center">Unknown</td> </tr> - <tr id="1928"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1928">1928</a></td> - <td>NAD</td> + <tr class="open" id="1928"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1928">1928</a></td> + <td>open</td> <td>Triviality of deleted special member functions</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr id="1929"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1929">1929</a></td> - <td>CD4</td> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1929">1929</a></td> + <td>tentatively ready</td> <td><TT>template</TT> keyword following namespace <I>nested-name-specifier</I></td> <td class="none" align="center">Unknown</td> </tr> - <tr id="1930"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1930">1930</a></td> - <td>CD4</td> + <tr class="open" id="1930"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1930">1930</a></td> + <td>review</td> <td><I>init-declarator-list</I> vs <I>member-declarator-list</I></td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr class="open" id="1931"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1931">1931</a></td> @@ -11403,11 +11403,11 @@ and <I>POD class</I></td> <td>Default-constructible and copy-assignable closure types</td> <td align="center">Not resolved</td> </tr> - <tr id="1932"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1932">1932</a></td> - <td>CD4</td> + <tr class="open" id="1932"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1932">1932</a></td> + <td>drafting</td> <td>Bit-field results of conditional operators</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr id="1933"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1933">1933</a></td> @@ -11453,19 +11453,19 @@ and <I>POD class</I></td> </tr> <tr id="1940"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1940">1940</a></td> - <td>CD4</td> + <td>DR</td> <td><TT>static_assert</TT> in anonymous unions</td> <td class="full" align="center">Yes</td> </tr> - <tr id="1941"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1941">1941</a></td> - <td>CD4</td> + <tr class="open" id="1941"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1941">1941</a></td> + <td>drafting</td> <td>SFINAE and inherited constructor default arguments</td> - <td class="full" align="center">Clang 3.9</td> + <td align="center">Not resolved</td> </tr> <tr id="1942"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1942">1942</a></td> - <td>CD4</td> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1942">1942</a></td> + <td>tentatively ready</td> <td>Incorrect reference to <I>trailing-return-type</I></td> <td class="none" align="center">Unknown</td> </tr> @@ -11487,11 +11487,11 @@ and <I>POD class</I></td> <td>Friend declarations naming members of class templates in non-templates</td> <td align="center">Not resolved</td> </tr> - <tr id="1946"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1946">1946</a></td> - <td>CD4</td> + <tr class="open" id="1946"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1946">1946</a></td> + <td>open</td> <td><I>exception-specification</I>s vs pointer dereference</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr id="1947"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1947">1947</a></td> @@ -11505,11 +11505,11 @@ and <I>POD class</I></td> <td><I>exception-specification</I> of replacement global <TT>new</TT></td> <td class="full" align="center">Yes</td> </tr> - <tr id="1949"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1949">1949</a></td> - <td>CD4</td> + <tr class="open" id="1949"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1949">1949</a></td> + <td>drafting</td> <td>“sequenced after” instead of “sequenced before”</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr id="1950"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1950">1950</a></td> @@ -11518,14 +11518,14 @@ and <I>POD class</I></td> <td class="none" align="center">Unknown</td> </tr> <tr id="1951"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1951">1951</a></td> - <td>CD4</td> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1951">1951</a></td> + <td>tentatively ready</td> <td>Cv-qualification and literal types</td> <td class="none" align="center">Unknown</td> </tr> <tr id="1952"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1952">1952</a></td> - <td>CD4</td> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1952">1952</a></td> + <td>tentatively ready</td> <td>Constant expressions and library undefined behavior</td> <td class="none" align="center">Unknown</td> </tr> @@ -11541,15 +11541,15 @@ and <I>POD class</I></td> <td><TT>typeid</TT> null dereference check in subexpressions</td> <td align="center">Not resolved</td> </tr> - <tr id="1955"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1955">1955</a></td> - <td>CD4</td> + <tr class="open" id="1955"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1955">1955</a></td> + <td>review</td> <td><TT>#elif</TT> with invalid controlling expression</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr id="1956"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1956">1956</a></td> - <td>CD4</td> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1956">1956</a></td> + <td>tentatively ready</td> <td>Reuse of storage of automatic variables</td> <td class="none" align="center">Unknown</td> </tr> @@ -11560,16 +11560,16 @@ and <I>POD class</I></td> <td align="center">Not resolved</td> </tr> <tr id="1958"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1958">1958</a></td> - <td>CD4</td> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1958">1958</a></td> + <td>tentatively ready</td> <td><TT>decltype(auto)</TT> with parenthesized initializer</td> <td class="none" align="center">Unknown</td> </tr> - <tr id="1959"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1959">1959</a></td> - <td>CD4</td> + <tr class="open" id="1959"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1959">1959</a></td> + <td>drafting</td> <td>Inadvertently inherited copy constructor</td> - <td class="full" align="center">Clang 3.9</td> + <td align="center">Not resolved</td> </tr> <tr id="1960"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1960">1960</a></td> @@ -11577,21 +11577,21 @@ and <I>POD class</I></td> <td>Visibility of entity named in class-scope <I>using-declaration</I></td> <td class="none" align="center">Unknown</td> </tr> - <tr id="1961"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1961">1961</a></td> - <td>C++17</td> + <tr class="open" id="1961"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1961">1961</a></td> + <td>concurrency</td> <td>Potentially-concurrent actions within a signal handler</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr class="open" id="1962"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1962">1962</a></td> - <td>drafting</td> + <td>open</td> <td>Type of <TT>__func__</TT></td> <td align="center">Not resolved</td> </tr> <tr id="1963"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1963">1963</a></td> - <td>CD4</td> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1963">1963</a></td> + <td>tentatively ready</td> <td>Implementation-defined identifier characters</td> <td class="none" align="center">Unknown</td> </tr> @@ -11603,19 +11603,19 @@ and <I>POD class</I></td> </tr> <tr class="open" id="1965"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1965">1965</a></td> - <td>drafting</td> + <td>open</td> <td>Explicit casts to reference types</td> <td align="center">Not resolved</td> </tr> <tr id="1966"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1966">1966</a></td> - <td>CD4</td> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1966">1966</a></td> + <td>tentatively ready</td> <td>Colon following enumeration <I>elaborated-type-specifier</I></td> <td class="none" align="center">Unknown</td> </tr> <tr id="1967"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1967">1967</a></td> - <td>CD4</td> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1967">1967</a></td> + <td>tentatively ready</td> <td>Temporary lifetime and move-elision</td> <td class="none" align="center">Unknown</td> </tr> @@ -11638,8 +11638,8 @@ and <I>POD class</I></td> <td class="none" align="center">Unknown</td> </tr> <tr id="1971"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1971">1971</a></td> - <td>CD4</td> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1971">1971</a></td> + <td>tentatively ready</td> <td>Unclear disambiguation of destructor and <TT>operator~</TT></td> <td class="none" align="center">Unknown</td> </tr> @@ -11661,11 +11661,11 @@ and <I>POD class</I></td> <td>Redundant specification of non-type <I>typename-specifier</I></td> <td align="center">Not resolved</td> </tr> - <tr id="1975"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1975">1975</a></td> - <td>CD4</td> + <tr class="open" id="1975"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1975">1975</a></td> + <td>drafting</td> <td>Permissible declarations for <I>exception-specification</I>s</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr id="1976"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1976">1976</a></td> @@ -11680,14 +11680,14 @@ and <I>POD class</I></td> <td align="center">Not resolved</td> </tr> <tr id="1978"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1978">1978</a></td> - <td>CD4</td> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1978">1978</a></td> + <td>tentatively ready</td> <td>Redundant description of explicit constructor use</td> <td class="none" align="center">Unknown</td> </tr> <tr class="open" id="1979"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1979">1979</a></td> - <td>drafting</td> + <td>open</td> <td>Alias template specialization in template member definition</td> <td align="center">Not resolved</td> </tr> @@ -11697,11 +11697,11 @@ and <I>POD class</I></td> <td>Equivalent but not functionally-equivalent redeclarations</td> <td align="center">Not resolved</td> </tr> - <tr id="1981"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1981">1981</a></td> - <td>CD4</td> + <tr class="open" id="1981"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1981">1981</a></td> + <td>drafting</td> <td>Implicit contextual conversions and <TT>explicit</TT></td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr id="1982"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1982">1982</a></td> @@ -11709,11 +11709,11 @@ and <I>POD class</I></td> <td>Deduction extending parameter pack</td> <td class="none" align="center">Unknown</td> </tr> - <tr id="1983"> + <tr class="open" id="1983"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1983">1983</a></td> - <td>tentatively ready</td> + <td>drafting</td> <td>Inappropriate use of <I>virt-specifier</I></td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr id="1984"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1984">1984</a></td> @@ -11727,11 +11727,11 @@ and <I>POD class</I></td> <td>Unknown bound array member with <I>brace-or-equal-initializer</I></td> <td class="none" align="center">Unknown</td> </tr> - <tr class="open" id="1986"> + <tr id="1986"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1986">1986</a></td> - <td>drafting</td> + <td>ready</td> <td>odr-use and delayed initialization</td> - <td align="center">Not resolved</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="1987"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1987">1987</a></td> @@ -11740,8 +11740,8 @@ and <I>POD class</I></td> <td class="none" align="center">Unknown</td> </tr> <tr id="1988"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1988">1988</a></td> - <td>CD4</td> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1988">1988</a></td> + <td>tentatively ready</td> <td>Ambiguity between dependent and non-dependent bases in implicit member access</td> <td class="none" align="center">Unknown</td> </tr> @@ -11751,27 +11751,27 @@ and <I>POD class</I></td> <td>Insufficient restrictions on parameters of postfix operators</td> <td align="center">Not resolved</td> </tr> - <tr id="1990"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1990">1990</a></td> - <td>CD4</td> + <tr class="open" id="1990"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1990">1990</a></td> + <td>drafting</td> <td>Ambiguity due to optional <I>decl-specifier-seq</I></td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> - <tr id="1991"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1991">1991</a></td> - <td>CD4</td> + <tr class="open" id="1991"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1991">1991</a></td> + <td>open</td> <td>Inheriting constructors vs default arguments</td> - <td class="full" align="center">Clang 3.9</td> + <td align="center">Not resolved</td> </tr> - <tr id="1992"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1992">1992</a></td> - <td>CD4</td> + <tr class="open" id="1992"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1992">1992</a></td> + <td>drafting</td> <td><TT>new (std::nothrow) int[N]</TT> can throw</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr class="open" id="1993"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1993">1993</a></td> - <td>drafting</td> + <td>open</td> <td>Use of <TT>template<></TT> defining member of explicit specialization</td> <td align="center">Not resolved</td> </tr> @@ -11781,15 +11781,15 @@ and <I>POD class</I></td> <td>Confusing wording regarding multiple <TT>template<></TT> prefixes</td> <td class="none" align="center">Duplicate of <a href="#529">529</a></td> </tr> - <tr id="1995"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1995">1995</a></td> - <td>CD4</td> + <tr class="open" id="1995"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1995">1995</a></td> + <td>open</td> <td><I>exception-specification</I>s and non-type template parameters</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr class="open" id="1996"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1996">1996</a></td> - <td>drafting</td> + <td>open</td> <td>Reference list-initialization ignores conversion functions</td> <td align="center">Not resolved</td> </tr> @@ -11806,22 +11806,22 @@ and <I>POD class</I></td> <td class="none" align="center">Unknown</td> </tr> <tr id="1999"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1999">1999</a></td> - <td>CD4</td> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1999">1999</a></td> + <td>tentatively ready</td> <td>Representation of source characters as universal-character-names</td> <td class="none" align="center">Unknown</td> </tr> - <tr id="2000"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2000">2000</a></td> - <td>CD4</td> + <tr class="open" id="2000"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2000">2000</a></td> + <td>drafting</td> <td><I>header-name</I> outside <TT>#include</TT> directive</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> - <tr id="2001"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2001">2001</a></td> - <td>CD4</td> + <tr class="open" id="2001"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2001">2001</a></td> + <td>drafting</td> <td><I>non-directive</I> is underspecified</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr class="open" id="2002"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2002">2002</a></td> @@ -11835,11 +11835,11 @@ and <I>POD class</I></td> <td>Zero-argument macros incorrectly specified</td> <td align="center">Not resolved</td> </tr> - <tr id="2004"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2004">2004</a></td> - <td>CD4</td> + <tr class="open" id="2004"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2004">2004</a></td> + <td>drafting</td> <td>Unions with mutable members in constant expressions</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr id="2005"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2005">2005</a></td> @@ -11847,11 +11847,11 @@ and <I>POD class</I></td> <td>Incorrect <TT>constexpr</TT> reference initialization requirements</td> <td class="none" align="center">Unknown</td> </tr> - <tr id="2006"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2006">2006</a></td> - <td>CD4</td> + <tr class="open" id="2006"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2006">2006</a></td> + <td>drafting</td> <td>Cv-qualified <TT>void</TT> types</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr class="open" id="2007"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2007">2007</a></td> @@ -11859,11 +11859,11 @@ and <I>POD class</I></td> <td>Argument-dependent lookup for <TT>operator=</TT></td> <td align="center">Not resolved</td> </tr> - <tr id="2008"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2008">2008</a></td> - <td>CD4</td> + <tr class="open" id="2008"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2008">2008</a></td> + <td>review</td> <td>Default <I>template-argument</I>s underspecified</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr class="open" id="2009"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2009">2009</a></td> @@ -11871,23 +11871,23 @@ and <I>POD class</I></td> <td>Unclear specification of class scope</td> <td align="center">Not resolved</td> </tr> - <tr id="2010"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2010">2010</a></td> - <td>CD4</td> + <tr class="open" id="2010"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2010">2010</a></td> + <td>open</td> <td><I>exception-specification</I>s and conversion operators</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> - <tr id="2011"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2011">2011</a></td> - <td>C++17</td> + <tr class="open" id="2011"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2011">2011</a></td> + <td>review</td> <td>Unclear effect of reference capture of reference</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> - <tr id="2012"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2012">2012</a></td> - <td>CD4</td> + <tr class="open" id="2012"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2012">2012</a></td> + <td>open</td> <td>Lifetime of references</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr class="open" id="2013"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2013">2013</a></td> @@ -11901,35 +11901,35 @@ and <I>POD class</I></td> <td>Unneeded deallocation signatures</td> <td class="none" align="center">Unknown</td> </tr> - <tr id="2015"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2015">2015</a></td> - <td>CD4</td> + <tr class="open" id="2015"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2015">2015</a></td> + <td>drafting</td> <td>odr-use of deleted virtual functions</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> - <tr id="2016"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2016">2016</a></td> - <td>CD4</td> + <tr class="open" id="2016"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2016">2016</a></td> + <td>drafting</td> <td>Confusing wording in description of conversion function</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> - <tr id="2017"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2017">2017</a></td> - <td>CD4</td> + <tr class="open" id="2017"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2017">2017</a></td> + <td>drafting</td> <td>Flowing off end is not equivalent to no-expression return</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr class="open" id="2018"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2018">2018</a></td> - <td>drafting</td> + <td>open</td> <td>Qualification conversion vs reference binding</td> <td align="center">Not resolved</td> </tr> - <tr id="2019"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2019">2019</a></td> - <td>CD4</td> + <tr class="open" id="2019"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2019">2019</a></td> + <td>drafting</td> <td>Member references omitted from description of storage duration</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr class="open" id="2020"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2020">2020</a></td> @@ -11943,41 +11943,41 @@ and <I>POD class</I></td> <td>Function template redeclaration via alias template</td> <td class="none" align="center">Unknown</td> </tr> - <tr id="2022"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2022">2022</a></td> - <td>CD4</td> + <tr class="open" id="2022"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2022">2022</a></td> + <td>drafting</td> <td>Copy elision in constant expressions</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr class="open" id="2023"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2023">2023</a></td> - <td>drafting</td> + <td>open</td> <td>Composite reference result type of conditional operator</td> <td align="center">Not resolved</td> </tr> - <tr id="2024"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2024">2024</a></td> - <td>CD4</td> + <tr class="open" id="2024"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2024">2024</a></td> + <td>open</td> <td>Dependent types and unexpanded parameter packs</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> - <tr id="2025"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2025">2025</a></td> - <td>dup</td> + <tr class="open" id="2025"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2025">2025</a></td> + <td>open</td> <td>Declaration matching via alias templates</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> - <tr id="2026"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2026">2026</a></td> - <td>CD4</td> + <tr class="open" id="2026"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2026">2026</a></td> + <td>drafting</td> <td>Zero-initialization and <TT>constexpr</TT></td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> - <tr id="2027"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2027">2027</a></td> - <td>CD4</td> + <tr class="open" id="2027"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2027">2027</a></td> + <td>drafting</td> <td>Unclear requirements for multiple <TT>alignas</TT> specifiers</td> - <td class="none" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr class="open" id="2028"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2028">2028</a></td> @@ -11997,1962 +11997,36 @@ and <I>POD class</I></td> <td>Access of injected-class-name with template arguments</td> <td class="none" align="center">Unknown</td> </tr> - <tr id="2031"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2031">2031</a></td> - <td>CD4</td> - <td>Missing incompatibility for <TT>&&</TT></td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2032"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2032">2032</a></td> - <td>CD4</td> - <td>Default <I>template-argument</I>s of variable templates</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2033"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2033">2033</a></td> - <td>CD4</td> - <td>Redundant restriction on partial specialization argument</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2034"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2034">2034</a></td> - <td>NAD</td> - <td>Deprecating <TT>uncaught_exception()</TT></td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2035"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2035">2035</a></td> - <td>CD3</td> - <td>Multi-section example is confusing</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2036"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2036">2036</a></td> - <td>NAD</td> - <td>Refactoring <I>parameters-and-qualifiers</I></td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2037"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2037">2037</a></td> - <td>drafting</td> - <td>Alias templates and template declaration matching</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2038"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2038">2038</a></td> - <td>CD4</td> - <td>Document C++14 incompatibility of new braced deduction rule</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2039"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2039">2039</a></td> - <td>CD4</td> - <td>Constant conversions to <TT>bool</TT></td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2040"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2040">2040</a></td> - <td>CD4</td> - <td><I>trailing-return-type</I> no longer ambiguous</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2041"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2041">2041</a></td> - <td>CD4</td> - <td>Namespace for explicit class template specialization</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2042"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2042">2042</a></td> - <td>drafting</td> - <td>Exceptions and deallocation functions</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2043"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2043">2043</a></td> - <td>drafting</td> - <td>Generalized template arguments and array-to-pointer decay</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2044"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2044">2044</a></td> - <td>CD4</td> - <td><TT>decltype(auto)</TT> and <TT>void</TT></td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2045"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2045">2045</a></td> - <td>drafting</td> - <td>“Identical” template parameter lists</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2046"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2046">2046</a></td> - <td>C++17</td> - <td>Incomplete thread specifications</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2047"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2047">2047</a></td> - <td>CD4</td> - <td>Coordinating “throws anything” specifications</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2048"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2048">2048</a></td> - <td>open</td> - <td>C-style casts that cast away constness vs <TT>static_cast</TT></td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2049"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2049">2049</a></td> - <td>drafting</td> - <td>List initializer in non-type template default argument</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2050"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2050">2050</a></td> - <td>NAD</td> - <td>Consolidate specification of linkage</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2051"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2051">2051</a></td> - <td>drafting</td> - <td>Simplifying alias rules</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2052"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2052">2052</a></td> - <td>CD4</td> - <td>Template argument deduction vs overloaded operators</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2053"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2053">2053</a></td> - <td>drafting</td> - <td><TT>auto</TT> in non-generic lambdas</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2054"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2054">2054</a></td> - <td>open</td> - <td>Missing description of class SFINAE</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2055"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2055">2055</a></td> - <td>drafting</td> - <td>Explicitly-specified non-deduced parameter packs</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2056"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2056">2056</a></td> - <td>drafting</td> - <td>Member function calls in partially-initialized class objects</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2057"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2057">2057</a></td> - <td>drafting</td> - <td>Template template arguments with default arguments</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2058"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2058">2058</a></td> - <td>drafting</td> - <td>More errors from internal-linkage namespaces</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2059"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2059">2059</a></td> - <td>tentatively ready</td> - <td>Linkage and deduced return types</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2060"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2060">2060</a></td> - <td>NAD</td> - <td>Deduced return type for explicit specialization</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2061"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2061">2061</a></td> - <td>CD4</td> - <td>Inline namespace after simplifications</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2062"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2062">2062</a></td> - <td>drafting</td> - <td>Class template redeclaration requirements</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2063"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2063">2063</a></td> - <td>CD4</td> - <td>Type/nontype hiding in class scope</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2064"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2064">2064</a></td> - <td>CD4</td> - <td>Conflicting specifications for dependent <I>decltype-specifier</I>s</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2065"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2065">2065</a></td> - <td>drafting</td> - <td>Current instantiation of a partial specialization</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2066"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2066">2066</a></td> - <td>CD4</td> - <td>Does type-dependent imply value-dependent?</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2067"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2067">2067</a></td> - <td>open</td> - <td>Generated variadic templates requiring empty pack</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2068"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2068">2068</a></td> - <td>CD4</td> - <td>When can/must a defaulted virtual destructor be defined?</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2069"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2069">2069</a></td> - <td>CD4</td> - <td>Do destructors have names?</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2070"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2070">2070</a></td> + <tr class="open" id="2031"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2031">2031</a></td> <td>drafting</td> - <td><I>using-declaration</I> with dependent <I>nested-name-specifier</I></td> - <td align="center">Not resolved</td> - </tr> - <tr id="2071"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2071">2071</a></td> - <td>CD4</td> - <td><TT>typedef</TT> with no declarator</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2072"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2072">2072</a></td> - <td>drafting</td> - <td>Default argument instantiation for member functions of templates</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2073"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2073">2073</a></td> - <td>drafting</td> - <td>Allocating memory for exception objects</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2074"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2074">2074</a></td> - <td>drafting</td> - <td>Type-dependence of local class of function template</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2075"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2075">2075</a></td> - <td>CD4</td> - <td>Passing short initializer lists to array reference parameters</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2076"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2076">2076</a></td> - <td>CD4</td> - <td>List-initialization of arguments for constructor parameters</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2077"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2077">2077</a></td> - <td>drafting</td> - <td>Overload resolution and invalid rvalue-reference initialization</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2078"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2078">2078</a></td> - <td>NAD</td> - <td>Name lookup of <I>mem-initilizer-id</I></td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2079"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2079">2079</a></td> - <td>CD4</td> - <td><TT>[[</TT> appearing in a <I>balanced-token-seq</I></td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2080"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2080">2080</a></td> - <td>drafting</td> - <td>Example with empty anonymous union member</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2081"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2081">2081</a></td> - <td>tentatively ready</td> - <td>Deduced return type in redeclaration or specialization of function template</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2082"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2082">2082</a></td> - <td>CD4</td> - <td>Referring to parameters in unevaluated operands of default arguments</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2083"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2083">2083</a></td> - <td>drafting</td> - <td>Incorrect cases of odr-use</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2084"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2084">2084</a></td> - <td>CD4</td> - <td>NSDMIs and deleted union default constructors</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2085"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2085">2085</a></td> - <td>CD4</td> - <td>Invalid example of adding special member function via default argument</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2086"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2086">2086</a></td> - <td>drafting</td> - <td>Reference odr-use vs implicit capture</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2087"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2087">2087</a></td> - <td>open</td> - <td>Left shift of negative value by zero bits</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2088"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2088">2088</a></td> - <td>tentatively ready</td> - <td>Late tiebreakers in partial ordering</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2089"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2089">2089</a></td> - <td>drafting</td> - <td>Restricting selection of builtin overloaded operators</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2090"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2090">2090</a></td> - <td>drafting</td> - <td>Dependency via non-dependent base class</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2091"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2091">2091</a></td> - <td>CD4</td> - <td>Deducing reference non-type template arguments</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2092"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2092">2092</a></td> - <td>tentatively ready</td> - <td>Deduction failure and overload resolution</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2093"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2093">2093</a></td> - <td>CD4</td> - <td>Qualification conversion for pointer-to-member handler matching</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2094"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2094">2094</a></td> - <td>C++17</td> - <td>Trivial copy/move constructor for class with volatile member</td> - <td class="full" align="center">Clang 5</td> - </tr> - <tr id="2095"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2095">2095</a></td> - <td>CD4</td> - <td>Capturing rvalue references to functions by copy</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2096"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2096">2096</a></td> - <td>CD4</td> - <td>Constraints on literal unions</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2097"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2097">2097</a></td> - <td>extension</td> - <td>Lambdas and <TT>noreturn</TT> attribute</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2098"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2098">2098</a></td> - <td>CD4</td> - <td>Is <TT>uncaught_exceptions()</TT> per-thread?</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2099"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2099">2099</a></td> - <td>CD4</td> - <td>Inferring the bound of an array static data member</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2100"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2100">2100</a></td> - <td>C++17</td> - <td>Value-dependent address of static data member of class template</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2101"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2101">2101</a></td> - <td>CD4</td> - <td>Incorrect description of type- and value-dependence</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2102"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2102">2102</a></td> - <td>drafting</td> - <td>Constructor checking in <I>new-expression</I></td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2103"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2103">2103</a></td> - <td>drafting</td> - <td>Lvalue-to-rvalue conversion is irrelevant in odr-use of a reference</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2104"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2104">2104</a></td> - <td>CD4</td> - <td>Internal-linkage <TT>constexpr</TT> references and ODR requirements</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2105"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2105">2105</a></td> - <td>open</td> - <td>When do the arguments for a parameter pack end?</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2106"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2106">2106</a></td> - <td>CD4</td> - <td>Unclear restrictions on use of function-type template arguments</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2107"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2107">2107</a></td> - <td>CD4</td> - <td>Lifetime of temporaries for default arguments in array copying</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2108"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2108">2108</a></td> - <td>drafting</td> - <td>Conversions to non-class prvalues in reference initialization</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2109"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2109">2109</a></td> - <td>CD4</td> - <td>Value dependence underspecified</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2110"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2110">2110</a></td> - <td>drafting</td> - <td>Overload resolution for base class conversion and reference/non-reference</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2111"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2111">2111</a></td> - <td>extension</td> - <td>Array temporaries in reference binding</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2112"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2112">2112</a></td> - <td>drafting</td> - <td><TT>new auto{x}</TT></td> - <td align="center">Not resolved</td> - </tr> - <tr id="2113"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2113">2113</a></td> - <td>CD4</td> - <td>Incompete specification of types for declarators</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2114"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2114">2114</a></td> - <td>CD3</td> - <td>Missing description of incompatibility from aggregate NSDMIs</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2115"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2115">2115</a></td> - <td>drafting</td> - <td>Order of implicit destruction vs release of automatic storage</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2116"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2116">2116</a></td> - <td>drafting</td> - <td>Direct or copy initialization for omitted aggregate initializers</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2117"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2117">2117</a></td> - <td>drafting</td> - <td>Explicit specializations and <TT>constexpr</TT> function templates</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2118"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2118">2118</a></td> - <td>open</td> - <td>Stateful metaprogramming via friend injection</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2119"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2119">2119</a></td> - <td>NAD</td> - <td>Disambiguation of multi-level covariant return type</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2120"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2120">2120</a></td> - <td>CD4</td> - <td>Array as first non-static data member in standard-layout class</td> - <td class="svn" align="center">Clang 7</td> - </tr> - <tr class="open" id="2121"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2121">2121</a></td> - <td>drafting</td> - <td>More flexible lambda syntax</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2122"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2122">2122</a></td> - <td>CD4</td> - <td>Glvalues of <TT>void</TT> type</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2123"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2123">2123</a></td> - <td>open</td> - <td>Omitted constant initialization of local static variables</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2124"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2124">2124</a></td> - <td>CD4</td> - <td>Signature of constructor template</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2125"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2125">2125</a></td> - <td>extension</td> - <td>Copy elision and comma operator</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2126"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2126">2126</a></td> - <td>drafting</td> - <td>Lifetime-extended temporaries in constant expressions</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2127"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2127">2127</a></td> - <td>drafting</td> - <td>Partial specialization and nullptr</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2128"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2128">2128</a></td> - <td>drafting</td> - <td>Imprecise rule for reference member initializer</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2129"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2129">2129</a></td> - <td>CD4</td> - <td>Non-object prvalues and constant expressions</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2130"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2130">2130</a></td> - <td>CD4</td> - <td>Over-aligned types in <I>new-expression</I>s</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2131"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2131">2131</a></td> - <td>drafting</td> - <td>Ambiguity with <I>opaque-enum-declaration</I></td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2132"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2132">2132</a></td> - <td>extension</td> - <td>Deprecated default generated copy constructors</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2133"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2133">2133</a></td> - <td>open</td> - <td>Converting <TT>std::nullptr_t</TT> to <TT>bool</TT></td> - <td align="center">Not resolved</td> - </tr> - <tr id="2134"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2134">2134</a></td> - <td>NAD</td> - <td>Objectless references to non-static member functions</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2135"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2135">2135</a></td> - <td>NAD</td> - <td><I>mem-initializer</I>s for virtual bases of abstract classes</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2136"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2136">2136</a></td> - <td>NAD</td> - <td>Argument-dependent lookup and initializer lists</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2137"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2137">2137</a></td> - <td>CD4</td> - <td>List-initialization from object of same type</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2138"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2138">2138</a></td> - <td>NAD</td> - <td>Explicit member specialization vs implicit instantiation</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2139"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2139">2139</a></td> - <td>NAD</td> - <td>Floating-point requirements for integer representation</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2140"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2140">2140</a></td> - <td>CD4</td> - <td>Lvalue-to-rvalue conversion of <TT>std::nullptr_t</TT></td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2141"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2141">2141</a></td> - <td>CD4</td> - <td>Ambiguity in <I>new-expression</I> with <I>elaborated-type-specifier</I></td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2142"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2142">2142</a></td> - <td>NAD</td> - <td>Missing definition of associated classes and namespaces</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2143"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2143">2143</a></td> - <td>C++17</td> - <td>Value-dependency via injected-class-name</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2144"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2144">2144</a></td> - <td>drafting</td> - <td>Function/variable declaration ambiguity</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2145"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2145">2145</a></td> - <td>CD4</td> - <td>Parenthesized declarator in function definition</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2146"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2146">2146</a></td> - <td>CD4</td> - <td>Scalar object vs memory location in definition of “unsequenced”</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2147"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2147">2147</a></td> - <td>CD4</td> - <td>Initializer-list arguments and pack deduction</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2148"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2148">2148</a></td> - <td>drafting</td> - <td>Thread storage duration and order of initialization</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2149"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2149">2149</a></td> - <td>drafting</td> - <td>Brace elision and array length deduction</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2150"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2150">2150</a></td> - <td>CD3</td> - <td>Initializer list array lifetime</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2151"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2151">2151</a></td> - <td>drafting</td> - <td>Exception object is not created</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2152"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2152">2152</a></td> - <td>NAD</td> - <td>Can an alternative token be used as a <I>ud-suffix</I>?</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2153"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2153">2153</a></td> - <td>CD4</td> - <td><I>pure-specifier</I> in friend declaration</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2154"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2154">2154</a></td> - <td>CD4</td> - <td>Ambiguity of <I>pure-specifier</I></td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2155"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2155">2155</a></td> - <td>C++17</td> - <td>Defining classes and enumerations via <I>using-declaration</I>s</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2156"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2156">2156</a></td> - <td>CD4</td> - <td>Definition of enumeration declared by <I>using-declaration</I></td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2157"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2157">2157</a></td> - <td>CD4</td> - <td>Further disambiguation of enumeration <I>elaborated-type-specifier</I></td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2158"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2158">2158</a></td> - <td>drafting</td> - <td>Polymorphic behavior during destruction</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2159"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2159">2159</a></td> - <td>NAD</td> - <td>Lambda capture and local <TT>thread_local</TT> variables</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2160"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2160">2160</a></td> - <td>open</td> - <td>Issues with partial ordering</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2161"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2161">2161</a></td> - <td>NAD</td> - <td>Explicit instantiation declaration and “preceding initialization”</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2162"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2162">2162</a></td> - <td>CD3</td> - <td>Capturing <TT>this</TT> by reference</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2163"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2163">2163</a></td> - <td>CD4</td> - <td>Labels in <TT>constexpr</TT> functions</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2164"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2164">2164</a></td> - <td>tentatively ready</td> - <td>Name hiding and <I>using-directive</I>s</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2165"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2165">2165</a></td> - <td>drafting</td> - <td>Namespaces, declarative regions, and translation units</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2166"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2166">2166</a></td> - <td>drafting</td> - <td>Unclear meaning of “undefined <TT>constexpr</TT> function”</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2167"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2167">2167</a></td> - <td>CD4</td> - <td>Non-member references with lifetimes within the current evaluation</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2168"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2168">2168</a></td> - <td>open</td> - <td>Narrowing conversions and +/- infinity</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2169"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2169">2169</a></td> - <td>extension</td> - <td>Narrowing conversions and overload resolution</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2170"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2170">2170</a></td> - <td>drafting</td> - <td>Unclear definition of odr-use for arrays</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2171"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2171">2171</a></td> - <td>CD4</td> - <td>Triviality of copy constructor with less-qualified parameter</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2172"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2172">2172</a></td> - <td>drafting</td> - <td>Multiple exceptions with one exception object</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2173"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2173">2173</a></td> - <td>open</td> - <td>Partial specialization with non-deduced contexts</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2174"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2174">2174</a></td> - <td>C++17</td> - <td>Unclear rules for friend definitions in templates</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2175"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2175">2175</a></td> - <td>CD4</td> - <td>Ambiguity with attribute in conversion operator declaration</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2176"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2176">2176</a></td> - <td>CD4</td> - <td>Destroying the returned object when a destructor throws</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2177"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2177">2177</a></td> - <td>DR</td> - <td>Placement <TT>operator delete</TT> and parameter copies</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2178"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2178">2178</a></td> - <td>NAD</td> - <td>Substitution of dependent template arguments in default template arguments</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2179"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2179">2179</a></td> - <td>drafting</td> - <td>Required diagnostic for partial specialization after first use</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2180"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2180">2180</a></td> - <td>CD4</td> - <td>Virtual bases in destructors and defaulted assignment operators</td> - <td class="full" align="center">Yes</td> - </tr> - <tr class="open" id="2181"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2181">2181</a></td> - <td>drafting</td> - <td>Normative requirements in an informative Annex</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2182"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2182">2182</a></td> - <td>drafting</td> - <td>Pointer arithmetic in array-like containers</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2183"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2183">2183</a></td> - <td>NAD</td> - <td>Problems in description of potential exceptions</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2184"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2184">2184</a></td> - <td>CD4</td> - <td>Missing C compatibility entry for decrement of <TT>bool</TT></td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2185"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2185">2185</a></td> - <td>open</td> - <td>Cv-qualified numeric types</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2186"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2186">2186</a></td> - <td>drafting</td> - <td>Unclear point that “preceding initialization” must precede</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2187"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2187">2187</a></td> - <td>open</td> - <td>Protected members and access via <I>qualified-id</I></td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2188"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2188">2188</a></td> - <td>open</td> - <td><I>empty-declaration</I> ambiguity</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2189"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2189">2189</a></td> - <td>open</td> - <td>Surrogate call template</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2190"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2190">2190</a></td> - <td>open</td> - <td>Insufficient specification of <TT>__has_include</TT></td> - <td align="center">Not resolved</td> - </tr> - <tr id="2191"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2191">2191</a></td> - <td>C++17</td> - <td>Incorrect result for <TT>noexcept(typeid(v))</TT></td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2192"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2192">2192</a></td> - <td>open</td> - <td>Constant expressions and order-of-eval undefined behavior</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2193"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2193">2193</a></td> - <td>NAD</td> - <td><TT>numeric_limits<int>::radix</TT> and <TT>digits</TT></td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2194"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2194">2194</a></td> - <td>review</td> - <td>Impossible case in list initialization</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2195"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2195">2195</a></td> - <td>open</td> - <td>Unsolicited reading of trailing volatile members</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2196"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2196">2196</a></td> - <td>C++17</td> - <td>Zero-initialization with virtual base classes</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2197"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2197">2197</a></td> - <td>review</td> - <td>Overload resolution and deleted special member functions</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2198"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2198">2198</a></td> - <td>C++17</td> - <td>Linkage of enumerators</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2199"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2199">2199</a></td> - <td>drafting</td> - <td>Typedefs and tags</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2200"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2200">2200</a></td> - <td>NAD</td> - <td>Conversions in template argument deduction</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2201"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2201">2201</a></td> - <td>C++17</td> - <td>Cv-qualification of array types</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2202"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2202">2202</a></td> - <td>open</td> - <td>When does default argument instantiation occur?</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2203"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2203">2203</a></td> - <td>drafting</td> - <td>Defaulted copy/move constructors and UDCs</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2204"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2204">2204</a></td> - <td>NAD</td> - <td>Naming delegated constructors</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2205"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2205">2205</a></td> - <td>C++17</td> - <td>Restrictions on use of <TT>alignas</TT></td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2206"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2206">2206</a></td> - <td>C++17</td> - <td>Composite type of object and function pointers</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2207"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2207">2207</a></td> - <td>drafting</td> - <td>Alignment of allocation function return value</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2208"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2208">2208</a></td> - <td>NAD</td> - <td><I>static_assert-declaration</I> does not declare a member</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2209"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2209">2209</a></td> - <td>NAD</td> - <td>Destruction of constructed array elements</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2210"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2210">2210</a></td> - <td>NAD</td> - <td>Principal/target constructor confusion</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2211"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2211">2211</a></td> - <td>C++17</td> - <td>Hiding by lambda captures and parameters</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2212"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2212">2212</a></td> - <td>open</td> - <td>Typedef changing linkage after use</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2213"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2213">2213</a></td> - <td>drafting</td> - <td>Forward declaration of partial specializations</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2214"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2214">2214</a></td> - <td>C++17</td> - <td>Missing requirement on representation of integer values</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2215"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2215">2215</a></td> - <td>review</td> - <td>Redundant description of language linkage in function call</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2216"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2216">2216</a></td> - <td>NAD</td> - <td>Exception specifications in unevaluated contexts</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2217"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2217">2217</a></td> - <td>NAD</td> - <td><TT>constexpr</TT> constructors for non-literal types</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2218"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2218">2218</a></td> - <td>C++17</td> - <td>Ambiguity and namespace aliases</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2219"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2219">2219</a></td> - <td>open</td> - <td>Dynamically-unreachable handlers</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2220"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2220">2220</a></td> - <td>C++17</td> - <td>Hiding index variable in range-based <TT>for</TT></td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2221"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2221">2221</a></td> - <td>review</td> - <td>Copying volatile objects</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2222"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2222">2222</a></td> - <td>drafting</td> - <td>Additional contexts where instantiation is not required</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2223"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2223">2223</a></td> - <td>drafting</td> - <td>Multiple <TT>alignas</TT> specifiers</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2224"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2224">2224</a></td> - <td>C++17</td> - <td>Member subobjects and base-class casts</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2225"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2225">2225</a></td> - <td>NAD</td> - <td><TT>reinterpret_cast</TT> to same floating-point type</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2226"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2226">2226</a></td> - <td>tentatively ready</td> - <td>Xvalues vs lvalues in conditional expressions</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2227"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2227">2227</a></td> - <td>tentatively ready</td> - <td>Destructor access and default member initializers</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2228"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2228">2228</a></td> - <td>drafting</td> - <td>Ambiguity resolution for cast to function type</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2229"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2229">2229</a></td> - <td>tentatively ready</td> - <td>Volatile unnamed bit-fields</td> - <td class="svn" align="center">Clang 7</td> - </tr> - <tr id="2230"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2230">2230</a></td> - <td>NAD</td> - <td>Linkage of <TT>extern "C"</TT> function in unnamed namespace</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2231"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2231">2231</a></td> - <td>NAD</td> - <td>Class member access to static data member template</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2232"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2232">2232</a></td> - <td>open</td> - <td><TT>thread_local</TT> anonymous unions</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2233"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2233">2233</a></td> - <td>tentatively ready</td> - <td>Function parameter packs following default arguments</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2234"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2234">2234</a></td> - <td>tentatively ready</td> - <td>Missing rules for <I>simple-template-id</I> as <I>class-name</I></td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2235"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2235">2235</a></td> - <td>tentatively ready</td> - <td>Partial ordering and non-dependent types</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2236"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2236">2236</a></td> - <td>drafting</td> - <td>When is an alias template specialization dependent?</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2237"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2237">2237</a></td> - <td>tentatively ready</td> - <td>Can a <I>template-id</I> name a constructor?</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2238"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2238">2238</a></td> - <td>NAD</td> - <td>Contradictory alignment requirements for allocation</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2239"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2239">2239</a></td> - <td>NAD</td> - <td>Sized deallocation with a trivial destructor</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2240"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2240">2240</a></td> - <td>open</td> - <td><TT>this</TT> is not odr-used in a constant expression</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2241"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2241">2241</a></td> - <td>open</td> - <td>Overload resolution is not invoked with a single function</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2242"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2242">2242</a></td> - <td>drafting</td> - <td>ODR violation with constant initialization possibly omitted</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2243"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2243">2243</a></td> - <td>drafting</td> - <td>Incorrect use of implicit conversion sequence</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2244"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2244">2244</a></td> - <td>open</td> - <td>Base class access in aggregate initialization</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2245"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2245">2245</a></td> - <td>open</td> - <td>Point of instantiation of incomplete class template</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2246"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2246">2246</a></td> - <td>open</td> - <td>Access of indirect virtual base class constructors</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2247"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2247">2247</a></td> - <td>C++17</td> - <td>Lambda capture and variable argument list</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2248"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2248">2248</a></td> - <td>C++17</td> - <td>Problems with sized delete</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2249"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2249">2249</a></td> - <td>tentatively ready</td> - <td><I>identifier</I>s and <I>id-expression</I>s</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2250"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2250">2250</a></td> - <td>open</td> - <td>Implicit instantiation, destruction, and TUs</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2251"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2251">2251</a></td> - <td>C++17</td> - <td>Unreachable enumeration list-initialization</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2252"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2252">2252</a></td> - <td>open</td> - <td>Enumeration list-initialization from the same type</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2253"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2253">2253</a></td> - <td>DRWP</td> - <td>Unnamed bit-fields and zero-initialization</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2254"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2254">2254</a></td> - <td>tentatively ready</td> - <td>Standard-layout classes and bit-fields</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2255"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2255">2255</a></td> - <td>tentatively ready</td> - <td>Instantiated static data member templates</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2256"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2256">2256</a></td> - <td>open</td> - <td>Lifetime of trivially-destructible objects</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2257"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2257">2257</a></td> - <td>open</td> - <td>Lifetime extension of references vs exceptions</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2258"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2258">2258</a></td> - <td>open</td> - <td>Storage deallocation during period of destruction</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2259"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2259">2259</a></td> - <td>C++17</td> - <td>Unclear context describing ambiguity</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2260"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2260">2260</a></td> - <td>tentatively ready</td> - <td>Explicit specializations of deleted member functions</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2261"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2261">2261</a></td> - <td>open</td> - <td>Explicit instantiation of in-class <TT>friend</TT> definition</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2262"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2262">2262</a></td> - <td>C++17</td> - <td>Attributes for <I>asm-definition</I></td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2263"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2263">2263</a></td> - <td>open</td> - <td>Default argument instantiation for <TT>friend</TT>s</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2264"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2264">2264</a></td> - <td>open</td> - <td>Memberwise copying with indeterminate value</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2265"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2265">2265</a></td> - <td>open</td> - <td>Delayed pack expansion and member redeclarations</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2266"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2266">2266</a></td> - <td>open</td> - <td>Has dependent type vs is type-dependent</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2267"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2267">2267</a></td> - <td>open</td> - <td>Copy-initialization of temporary in reference direct-initialization</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2268"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2268">2268</a></td> - <td>C++17</td> - <td>Unions with mutable members in constant expressions revisited</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2269"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2269">2269</a></td> - <td>dup</td> - <td>Additional recursive references in aggregate DMIs</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2270"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2270">2270</a></td> - <td>extension</td> - <td>Non-inline functions and explicit instantiation declarations</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2271"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2271">2271</a></td> - <td>C++17</td> - <td>Aliasing <TT>this</TT></td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2272"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2272">2272</a></td> - <td>C++17</td> - <td>Implicit initialization of aggregate members of reference type</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2273"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2273">2273</a></td> - <td>DRWP</td> - <td>Inheriting constructors vs implicit default constructor</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2274"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2274">2274</a></td> - <td>NAD</td> - <td>Generic lambda capture vs constexpr if</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2275"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2275">2275</a></td> - <td>drafting</td> - <td>Type-dependence of function template</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2276"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2276">2276</a></td> - <td>C++17</td> - <td>Dependent <TT>noexcept</TT> and function type-dependence</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2277"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2277">2277</a></td> - <td>DRWP</td> - <td>Ambiguity inheriting constructors with default arguments</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2278"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2278">2278</a></td> - <td>open</td> - <td>Copy elision in constant expressions reconsidered</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2279"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2279">2279</a></td> - <td>NAD</td> - <td>Multiple <I>attribute-specifier</I>s in one <I>attribute-list</I></td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2280"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2280">2280</a></td> - <td>review</td> - <td>Matching a usual deallocation function with placement new</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2281"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2281">2281</a></td> - <td>open</td> - <td>Consistency of aligned <TT>operator delete</TT> replacement</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2282"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2282">2282</a></td> - <td>drafting</td> - <td>Consistency with mismatched aligned/non-over-aligned allocation/deallocation functions</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2283"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2283">2283</a></td> - <td>drafting</td> - <td>Missing complete type requirements</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2284"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2284">2284</a></td> - <td>open</td> - <td>Sequencing of <I>braced-init-list</I> arguments</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2285"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2285">2285</a></td> - <td>tentatively ready</td> - <td>Issues with structured bindings</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2286"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2286">2286</a></td> - <td>NAD</td> - <td>Assignment evaluation order</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2287"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2287">2287</a></td> - <td>DRWP</td> - <td>Pointer-interconvertibility in non-standard-layout unions</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2288"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2288">2288</a></td> - <td>NAD</td> - <td>Contradictory optionality in <I>simple-declaration</I></td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2289"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2289">2289</a></td> - <td>drafting</td> - <td>Uniqueness of decomposition declaration names</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2290"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2290">2290</a></td> - <td>DRWP</td> - <td>Unclear specification for overload resolution and deleted special member functions</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2291"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2291">2291</a></td> - <td>dup</td> - <td>Implicit conversion sequences in non-call contexts</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2292"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2292">2292</a></td> - <td>drafting</td> - <td><I>simple-template-id</I> is ambiguous between <I>class-name</I> and <I>type-name</I></td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2293"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2293">2293</a></td> - <td>drafting</td> - <td>Requirements for <I>simple-template-id</I> used as a <I>class-name</I></td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2294"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2294">2294</a></td> - <td>drafting</td> - <td>Dependent <TT>auto</TT> static data members</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2295"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2295">2295</a></td> - <td>extension</td> - <td>Aggregates with deleted defaulted constructors</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2296"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2296">2296</a></td> - <td>extension</td> - <td>Are default argument instantiation failures in the “immediate context”?</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2297"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2297">2297</a></td> - <td>review</td> - <td>Unclear specification of atomic operations</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2298"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2298">2298</a></td> - <td>concurrency</td> - <td>Actions and expression evaluation</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2299"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2299">2299</a></td> - <td>tentatively ready</td> - <td><TT>constexpr</TT> vararg functions</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2300"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2300">2300</a></td> - <td>drafting</td> - <td>Lambdas in multiple definitions</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2301"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2301">2301</a></td> - <td>open</td> - <td>Value-initialization and constexpr constructor evaluation</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2302"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2302">2302</a></td> - <td>NAD</td> - <td>Address comparison between different member subobjects</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2303"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2303">2303</a></td> - <td>open</td> - <td>Partial ordering and recursive variadic inheritance</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2304"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2304">2304</a></td> - <td>NAD</td> - <td>Incomplete type vs overload resolution</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2305"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2305">2305</a></td> - <td>DR</td> - <td>Explicit instantiation of constexpr or inline variable template</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2306"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2306">2306</a></td> - <td>open</td> - <td>Nested friend templates of class templates</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2307"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2307">2307</a></td> - <td>DR</td> - <td>Unclear definition of “equivalent to a nontype template parameter”</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2308"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2308">2308</a></td> - <td>open</td> - <td>Structured bindings and lambda capture</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2309"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2309">2309</a></td> - <td>drafting</td> - <td>Restrictions on nested statements within <TT>constexpr</TT> functions</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2310"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2310">2310</a></td> - <td>open</td> - <td>Type completeness and derived-to-base pointer conversions</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2311"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2311">2311</a></td> - <td>open</td> - <td>Missed case for guaranteed copy elision</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2312"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2312">2312</a></td> - <td>drafting</td> - <td>Structured bindings and <TT>mutable</TT></td> - <td align="center">Not resolved</td> - </tr> - <tr id="2313"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2313">2313</a></td> - <td>DR</td> - <td>Redeclaration of structured binding reference variables</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2314"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2314">2314</a></td> - <td>dup</td> - <td>Structured bindings and lambda capture</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr id="2315"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2315">2315</a></td> - <td>DR</td> - <td>What is the “corresponding special member” of a variant member?</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2316"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2316">2316</a></td> - <td>drafting</td> - <td>Simplifying class conversions in conditional expressions</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2317"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2317">2317</a></td> - <td>open</td> - <td>Self-referential default member initializers</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2318"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2318">2318</a></td> - <td>drafting</td> - <td>Nondeduced contexts in deduction from a <I>braced-init-list</I></td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2319"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2319">2319</a></td> - <td>drafting</td> - <td>Nested brace initialization from same type</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2320"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2320">2320</a></td> - <td>extension</td> - <td><TT>constexpr if</TT> and boolean conversions</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2321"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2321">2321</a></td> - <td>drafting</td> - <td>Conditional operator and cv-qualified class prvalues</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2322"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2322">2322</a></td> - <td>drafting</td> - <td>Substitution failure and lexical order</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2323"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2323">2323</a></td> - <td>drafting</td> - <td>Expunge POD</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2324"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2324">2324</a></td> - <td>drafting</td> - <td>Size of base class subobject</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2325"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2325">2325</a></td> - <td>drafting</td> - <td><TT>std::launder</TT> and reuse of character buffers</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2326"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2326">2326</a></td> - <td>dup</td> - <td>Type deduction with initializer list containing ambiguous functions</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2327"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2327">2327</a></td> - <td>drafting</td> - <td>Copy elision for direct-initialization with a conversion function</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2328"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2328">2328</a></td> - <td>open</td> - <td>Unclear presentation style of template argument deduction rules</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2329"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2329">2329</a></td> - <td>drafting</td> - <td>Virtual base classes and generated assignment operators</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2330"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2330">2330</a></td> - <td>drafting</td> - <td>Missing references to variable templates</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2331"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2331">2331</a></td> - <td>drafting</td> - <td>Redundancy in description of class scope</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2332"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2332">2332</a></td> - <td>drafting</td> - <td><I>template-name</I> as <I>simple-type-name</I> vs injected-class-name</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2333"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2333">2333</a></td> - <td>drafting</td> - <td>Escape sequences in UTF-8 character literals</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2334"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2334">2334</a></td> - <td>open</td> - <td>Creation of objects by <TT>typeid</TT></td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2335"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2335">2335</a></td> - <td>open</td> - <td>Deduced return types vs member types</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2336"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2336">2336</a></td> - <td>drafting</td> - <td>Destructor characteristics vs potentially-constructed subobjects</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2337"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2337">2337</a></td> - <td>open</td> - <td>Incorrect implication of logic ladder for conversion sequence tiebreakers</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2338"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2338">2338</a></td> - <td>DR</td> - <td>Undefined behavior converting to short enums with fixed underlying types</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2339"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2339">2339</a></td> - <td>drafting</td> - <td>Underspecified template arguments in structured bindings</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2340"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2340">2340</a></td> - <td>open</td> - <td>Reference collapsing and structured bindings</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2341"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2341">2341</a></td> - <td>extension</td> - <td>Structured bindings with static storage duration</td> - <td align="center">Not resolved</td> - </tr> - <tr id="2342"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2342">2342</a></td> - <td>DR</td> - <td>Reference <TT>reinterpret_cast</TT> and pointer-interconvertibility</td> - <td class="none" align="center">Unknown</td> - </tr> - <tr class="open" id="2343"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2343">2343</a></td> - <td>open</td> - <td><TT>void*</TT> non-type template parameters</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2344"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2344">2344</a></td> - <td>open</td> - <td>Redeclaration of names in <I>init-statement</I>s</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2345"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2345">2345</a></td> - <td>open</td> - <td>Jumping across initializers in <I>init-statement</I>s and <I>condition</I>s</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2346"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2346">2346</a></td> - <td>open</td> - <td>Local variables in default arguments</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2347"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2347">2347</a></td> - <td>open</td> - <td>Passing short scoped enumerations to ellipsis</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2348"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2348">2348</a></td> - <td>open</td> - <td>Non-templated <TT>constexpr if</TT></td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2349"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2349">2349</a></td> - <td>open</td> - <td>Class/enumeration names vs conditions</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2350"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2350">2350</a></td> - <td>open</td> - <td>Forwarding references and deduction guides</td> - <td align="center">Not resolved</td> - </tr> - <tr class="open" id="2351"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2351">2351</a></td> - <td>open</td> - <td><TT>void{}</TT></td> + <td>Missing incompatibility for <TT>&&</TT></td> <td align="center">Not resolved</td> </tr> - <tr class="open" id="2352"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2352">2352</a></td> + <tr class="open" id="2032"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2032">2032</a></td> <td>open</td> - <td>Similar types and reference binding</td> + <td>Default <I>template-argument</I>s of variable templates</td> <td align="center">Not resolved</td> </tr> - <tr class="open" id="2353"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2353">2353</a></td> + <tr class="open" id="2033"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2033">2033</a></td> <td>open</td> - <td>Potential results of a member access expression for a static data member</td> + <td>Redundant restriction on partial specialization argument</td> <td align="center">Not resolved</td> </tr> - <tr class="open" id="2354"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2354">2354</a></td> + <tr class="open" id="2034"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2034">2034</a></td> <td>open</td> - <td>Extended alignment and object representation</td> + <td>Deprecating <TT>uncaught_exception()</TT></td> <td align="center">Not resolved</td> </tr> - <tr class="open" id="2355"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2355">2355</a></td> + <tr class="open" id="2035"> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2035">2035</a></td> <td>open</td> - <td>Deducing <I>noexcept-specifier</I>s</td> + <td>Multi-section example is confusing</td> <td align="center">Not resolved</td> </tr> - <tr id="2356"> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2356">2356</a></td> - <td>tentatively ready</td> - <td>Base class copy and move constructors should not be inherited</td> - <td class="none" align="center">Unknown</td> - </tr> </table> </div> diff --git a/gnu/llvm/tools/clang/www/cxx_status.html b/gnu/llvm/tools/clang/www/cxx_status.html index dbbda572d9d..3ceff5f6dc0 100644 --- a/gnu/llvm/tools/clang/www/cxx_status.html +++ b/gnu/llvm/tools/clang/www/cxx_status.html @@ -1,8 +1,9 @@ -<!DOCTYPE html> +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" + "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> - <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> - <title>Clang - C++17, C++14, C++11 and C++98 Status</title> + <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> + <title>Clang - C++1z, C++14, C++11 and C++98 Status</title> <link type="text/css" rel="stylesheet" href="menu.css"> <link type="text/css" rel="stylesheet" href="content.css"> <style type="text/css"> @@ -11,10 +12,8 @@ .svn { background-color: #FFFF99 } .full { background-color: #CCFF99 } .na { background-color: #DDDDDD } - :target { background-color: #FFFFBB; outline: #DDDD55 solid thin; } + span:target { background-color: #FFFFBB; outline: #DDDD55 solid thin; } th { background-color: #FFDDAA } - td { vertical-align: middle } - tt { white-space: nowrap } </style> </head> <body> @@ -26,13 +25,13 @@ <!--*************************************************************************--> <h1>C++ Support in Clang</h1> <!--*************************************************************************--> -<p>Last updated: $Date: 2019/01/27 16:43:08 $</p> +<p>Last updated: $Date: 2016/09/03 22:46:56 $</p> -<p>Clang fully implements all published ISO C++ standards (<a -href="#cxx98">C++98 / C++03</a>, <a -href="#cxx11">C++11</a>, and <a -href="#cxx14">C++14</a>), and most of the upcoming <a -href="#cxx17">C++17</a> standard. +<p>Clang fully implements all published ISO C++ standards including <a +href="#cxx11">C++11</a>, as well as the upcoming <a +href="#cxx14">C++14</a> standard, and some parts of the fledgling <a +href="#cxx17">C++1z</a> standard, +and is considered a production-quality C++ compiler. <p>The Clang community is continually striving to improve C++ standards compliance between releases by submitting and tracking <a @@ -55,17 +54,21 @@ each language mode.</p> <h2 id="cxx11">C++11 implementation status</h2> -<p>Clang 3.3 and later implement all of the <a - href="http://www.iso.org/standard/50372.html">ISO - C++ 2011 standard</a>. + <p>Clang 3.3 and later implement all of the <a + href="http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=50372">ISO + C++ 2011 standard</a>. The following table describes the Clang version + in which each feature became available.</p> <p>By default, Clang builds C++ code according to the C++98 standard, with many C++11 features accepted as extensions. You can use Clang in C++11 mode with the <code>-std=c++11</code> option. Clang's C++11 mode can be used -with <a href="http://libcxx.llvm.org/">libc++</a> or with gcc's libstdc++. - -<details> -<summary>List of features and minimum Clang version with support</summary> +with <a href="http://libcxx.llvm.org/">libc++</a> or with gcc's libstdc++, but +patches are needed to make <a href="libstdc++4.4-clang0x.patch">libstdc++-4.4</a> +work with Clang in C++11 mode. Patches are also needed to make +<a href="libstdc++4.6-clang11.patch">libstdc++-4.6</a> +and <a href="libstdc++4.7-clang11.patch">libstdc++-4.7</a> work with Clang +releases prior to version 3.2 in C++11 mode. <tt>thread_local</tt> support +currently requires the C++ runtime library from g++-4.8 or later.</p> <table width="689" border="1" cellspacing="0"> <tr> @@ -134,15 +137,10 @@ with <a href="http://libcxx.llvm.org/">libc++</a> or with gcc's libstdc++. <td class="full" align="center">Clang 2.9</td> </tr> <tr> - <td rowspan="2">Lambda expressions</td> + <td>Lambda expressions</td> <td><a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2927.pdf">N2927</a></td> <td class="full" align="center">Clang 3.1</td> </tr> - <tr> - <!-- from Albuquerque 2017 --> - <td><a href="http://wg21.link/p0588r1">P0588R1</a> (<a href="#dr">DR</a>)</td> - <td class="none" align="center">No</td> - </tr> <tr> <td>Declared type of an expression</td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2343.pdf">N2343</a></td> @@ -200,15 +198,10 @@ with <a href="http://libcxx.llvm.org/">libc++</a> or with gcc's libstdc++. <td class="full" align="center">Clang 3.3 <a href="#n2761">(1)</a></td> </tr> <tr> - <td rowspan="2">Generalized constant expressions</td> + <td>Generalized constant expressions</td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2235.pdf">N2235</a></td> <td class="full" align="center">Clang 3.1</td> </tr> - <tr> - <!-- from Albuquerque 2017 --> - <td><a href="http://wg21.link/p0859r0">P0859R0</a> (<a href="#dr">DR</a>)</td> - <td class="none" align="center">No</td> - </tr> <tr> <td>Alignment support</td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2341.pdf">N2341</a></td> @@ -230,15 +223,10 @@ with <a href="http://libcxx.llvm.org/">libc++</a> or with gcc's libstdc++. <td class="full" align="center">Clang 3.0</td> </tr> <tr> - <td rowspan="2">Inheriting constructors</td> + <td>Inheriting constructors</td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2540.htm">N2540</a></td> <td class="full" align="center">Clang 3.3</td> </tr> - <tr> - <!-- from Kona 2015 --> - <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0136r1.html">P0136R1</a> (<a href="#dr">DR</a>)</td> - <td class="full" align="center">Clang 3.9</td> - </tr> <tr> <td>Explicit conversion operators</td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2437.pdf">N2437</a></td> @@ -311,15 +299,10 @@ with <a href="http://libcxx.llvm.org/">libc++</a> or with gcc's libstdc++. <td class="full" align="center">Clang 2.9</td> </tr> <tr> - <td rowspan="2">Range-based for</td> + <td>Range-based for</td> <td><a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2930.html">N2930</a></td> <td class="full" align="center">Clang 3.0</td> </tr> - <tr> - <!-- from Jacksonville 2018 --> - <td><a href="http://wg21.link/p0962r1">P0962R1</a> (<a href="#dr">DR</a>)</td> - <td class="none" align="center">No</td> - </tr> <tr> <td>Explicit virtual overrides</td> <td><a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2928.htm">N2928</a> @@ -390,7 +373,7 @@ with <a href="http://libcxx.llvm.org/">libc++</a> or with gcc's libstdc++. <tr> <td>Thread-local storage</td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2659.htm">N2659</a></td> - <td class="full" align="center">Clang 3.3 <a href="#n2659">(5)</a></td> + <td class="full" align="center">Clang 3.3</td> </tr> <tr> <td>Dynamic initialization and destruction with concurrency</td> @@ -419,7 +402,7 @@ with <a href="http://libcxx.llvm.org/">libc++</a> or with gcc's libstdc++. <tr> <td>Extended integral types</td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1988.pdf">N1988</a></td> - <td class="na" align="center">N/A <a href="#n1988">(6)</a></td> + <td class="na" align="center">N/A <a href="#n1988">(5)</a></td> </tr> </table> @@ -432,30 +415,24 @@ such as Clang that does not provide garbage collection.</span><br> strong compare-exchanges.</span><br> <span id="n2664">(4): <code>memory_order_consume</code> is lowered to <code>memory_order_acquire</code>.</span><br> -<span id="n2659">(5): <code>thread_local</code> support -requires a C++ runtime library providing <code>__cxa_thread_atexit</code>, such -as <a href="http://libcxxabi.llvm.org">libc++abi</a> 3.6 or later, -or libsupc++ 4.8 or later.</span><br> -<span id="n1988">(6): No compiler changes are required for an implementation +<span id="n1988">(5): No compiler changes are required for an implementation such as Clang that does not provide any extended integer types. <code>__int128</code> is not treated as an extended integer type, because changing <code>intmax_t</code> would be an ABI-incompatible change.</span> </p> -</details> <h2 id="cxx14">C++14 implementation status</h2> -<p>Clang 3.4 and later implement all of the <a - href="http://www.iso.org/standard/64029.html">ISO - C++ 2014 standard</a>. +<p>Clang 3.4 and later implement all of the Draft International Standard (see <a +href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3797.pdf">most +recent publicly available draft</a>) +of the upcoming C++14 language standard. The following table describes the +Clang version in which each feature became available.</p> <p>You can use Clang in C++14 mode with the <code>-std=c++14</code> option (use <code>-std=c++1y</code> in Clang 3.4 and earlier).</p> -<details> -<summary>List of features and minimum Clang version with support</summary> - <table width="689" border="1" cellspacing="0"> <tr> <th>Language Feature</th> @@ -524,12 +501,12 @@ change.</span> <tr> <td>C++ Sized Deallocation</td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3778.html">N3778</a></td> - <td class="full" align="center">Clang 3.4 <a href="#n3778">(7)</a></td> + <td class="full" align="center">Clang 3.4 <a href="#n3778">(6)</a></td> </tr> </table> <p> -<span id="n3778">(7): In Clang 3.7 and later, sized deallocation is only enabled +<span id="n3778">(6): In Clang 3.7 and later, sized deallocation is only enabled if the user passes the <code>-fsized-deallocation</code> flag. The user must supply definitions of the sized deallocation functions, either by providing them explicitly or by using a C++ standard library that does. <code>libstdc++</code> @@ -537,26 +514,27 @@ added these functions in version 5.0, and <code>libc++</code> added them in version 3.7. </span> </p> -</details> -<h2 id="cxx17">C++17 implementation status</h2> +<h2 id="cxx17">C++1z implementation status</h2> -<p>Clang 5 and later implement all the features of the -<a href="https://www.iso.org/standard/68564.html">ISO C++ 2017 standard</a>. +<p>Clang has <b>highly experimental</b> support for some proposed features of +the C++ standard following C++14, +provisionally named C++1z. The following table describes which C++1z features +have been implemented in Clang and in which Clang version they became +available.</p> -<p>You can use Clang in C++17 mode with the <code>-std=c++17</code> option -(use <code>-std=c++1z</code> in Clang 4 and earlier).</p> +<p>Note that support for these features may change or be removed without notice, +as the draft C++1z standard evolves.</p> -<details open> -<summary>List of features and minimum Clang version with support</summary> +<p>You can use Clang in C++1z mode with the <code>-std=c++1z</code> option.</p> <table width="689" border="1" cellspacing="0"> <tr> <th>Language Feature</th> - <th>C++17 Proposal</th> + <th>C++1z Proposal</th> <th>Available in Clang?</th> </tr> - <!-- Issaquah 2014 papers --> + <!-- Issaquah papers --> <tr> <td><tt>static_assert</tt> with no message</td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3928.pdf">N3928</a></td> @@ -570,7 +548,7 @@ version 3.7. </tr> <!-- <tr> - <td rowspan="2">Terse range-based for loops (removed from C++17)</td> + <td rowspan="2">Terse range-based for loops (removed from C++1z)</td> <td rowspan="2"><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3994.htm">N3994</a></td> <td class="none" align="center">Clang 3.5: Yes</td> </tr> @@ -586,18 +564,14 @@ version 3.7. <tr> <td>New <tt>auto</tt> rules for direct-list-initialization <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3922.html">N3922</a></td> - <td class="full" align="center">Clang 3.8 <a href="#n3922">(8)</a></td> + <td class="svn" align="center">Clang 3.8 <a href="#n3922">(7)</a></td> </tr> <!-- Urbana papers --> <tr> - <td rowspan="2">Fold expressions</td> + <td>Fold expressions</td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4295.html">N4295</a></td> <td class="full" align="center">Clang 3.6</td> </tr> - <tr> <!-- from Jacksonville --> - <td><a href="http://wg21.link/p0036r0">P0036R0</a></td> - <td class="full" align="center">Clang 3.9</td> - </tr> <tr> <td><tt>u8</tt> character literals</td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4267.html">N4267</a></td> @@ -622,389 +596,49 @@ version 3.7. <tr> <td>Remove deprecated <tt>register</tt> storage class</td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0001r1.html">P0001R1</a></td> - <td class="full" align="center">Clang 3.8</td> + <td class="svn" align="center">Clang 3.8</td> </tr> <tr> <td>Remove deprecated <tt>bool</tt> increment</td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0002r1.html">P0002R1</a></td> - <td class="full" align="center">Clang 3.8</td> + <td class="svn" align="center">Clang 3.8</td> </tr> <tr> <td>Make exception specifications part of the type system</td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0012r1.html">P0012R1</a></td> - <td class="full" align="center">Clang 4</td> + <td class="none" align="center">No</td> </tr> <tr> <td><tt>__has_include</tt> in preprocessor conditionals</td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0061.html">P0061R1</a></td> <td class="full" align="center">Yes</td> </tr> - <!-- Jacksonville papers --> - <tr> - <td><tt>[[fallthrough]]</tt> attribute</td> - <td><a href="http://wg21.link/p0188r1">P0188R1</a></td> - <td class="full" align="center">Clang 3.9</td> - </tr> - <tr> - <td><tt>[[nodiscard]]</tt> attribute</td> - <td><a href="http://wg21.link/p0189r1">P0189R1</a></td> - <td class="full" align="center">Clang 3.9</td> - </tr> - <tr> - <td><tt>[[maybe_unused]]</tt> attribute</td> - <td><a href="http://wg21.link/p0212r1">P0212R1</a></td> - <td class="full" align="center">Clang 3.9</td> - </tr> - <tr> - <td>Aggregate initialization of classes with base classes</td> - <td><a href="http://wg21.link/p0017r1">P0017R1</a></td> - <td class="full" align="center">Clang 3.9</td> - </tr> - <tr> - <td><tt>constexpr</tt> lambda expressions</td> - <td><a href="http://wg21.link/p0170r1">P0170R1</a></td> - <td class="full" align="center">Clang 5</td> - </tr> - <tr> - <td>Differing <tt>begin</tt> and <tt>end</tt> types in range-based <tt>for</tt></td> - <td><a href="http://wg21.link/p0184r0">P0184R0</a></td> - <td class="full" align="center">Clang 3.9</td> - </tr> - <tr> - <td>Lambda capture of <tt>*this</tt></td> - <td><a href="http://wg21.link/p0018r3">P0018R3</a></td> - <td class="full" align="center">Clang 3.9</td> - </tr> - <tr> - <td>Direct-list-initialization of <tt>enum</tt>s</td> - <td><a href="http://wg21.link/p0138r2">P0138R2</a></td> - <td class="full" align="center">Clang 3.9</td> - </tr> - <tr> - <td>Hexadecimal floating-point literals</td> - <td><a href="http://wg21.link/p0245r1">P0245R1</a></td> - <td class="full" align="center">Yes</td> - </tr> - <!-- Oulu papers --> - <tr> - <td>Using attribute namespaces without repetition</td> - <td><a href="http://wg21.link/p0028r4">P0028R4</a></td> - <td class="full" align="center">Clang 3.9</td> - </tr> - <tr> - <td>Dynamic memory allocation for over-aligned data</td> - <td><a href="http://wg21.link/p0035r4">P0035R4</a></td> - <td class="full" align="center">Clang 4</td> - </tr> - <tr> - <td rowspan="4">Template argument deduction for class templates</td> - <td><a href="http://wg21.link/p0091r3">P0091R3</a></td> - <td rowspan="2" class="full" align="center">Clang 5</td> - </tr> - <tr> <!-- from Issaquah --> - <td><a href="http://wg21.link/p0512r0">P0512R0</a></td> - </tr> - <tr> - <!-- from Kona 2017 --> - <td><a href="http://wg21.link/p0620r1">P0620R0</a> (<a href="#dr">DR</a>)</td> - <td class="svn" align="center">Clang 7</td> - </tr> - <tr> - <!-- from Toronto 2017 --> - <td><a href="http://wg21.link/p0702r1">P0702R1</a> (<a href="#dr">DR</a>)</td> - <td class="full" align="center">Clang 6</td> - </tr> - <tr> - <td>Non-type template parameters with <tt>auto</tt> type</td> - <td><a href="http://wg21.link/p0127r2">P0127R2</a></td> - <td class="full" align="center">Clang 4</td> - </tr> - <tr> - <td>Guaranteed copy elision</td> - <td><a href="http://wg21.link/p0135r1">P0135R1</a></td> - <td class="full" align="center">Clang 4</td> - </tr> - <tr> - <td rowspan=2>Stricter expression evaluation order</td> - <td><a href="http://wg21.link/p0145r3">P0145R3</a></td> - <td class="full" align="center" rowspan=2>Clang 4 <a href="#p0145">(9)</a></td> - </tr> - <tr> - <td><a href="http://wg21.link/p0400r0">P0400R0</a></td> - </tr> - <tr> - <td>Requirement to ignore unknown attributes</td> - <td><a href="http://wg21.link/p0283r2">P0283R2</a></td> - <td class="full" align="center">Yes</td> - </tr> - <tr> - <td><tt>constexpr</tt> <em>if-statement</em>s</td> - <td><a href="http://wg21.link/p0292r2">P0292R2</a></td> - <td class="full" align="center">Clang 3.9</td> - </tr> - <tr> - <td>Inline variables</td> - <td><a href="http://wg21.link/p0386r2">P0386R2</a></td> - <td class="full" align="center">Clang 3.9</td> - </tr> - <tr> - <td rowspan="3">Structured bindings</td> - <td><a href="http://wg21.link/p0217r3">P0217R3</a></td> - <td class="full" align="center">Clang 4</td> - </tr> - <tr> - <!-- from Jacksonville 2018 --> - <td><a href="http://wg21.link/p0961r1">P0961R1</a> (<a href="#dr">DR</a>)</td> - <td class="none" align="center">No</td> - </tr> - <tr> - <!-- from Jacksonville 2018 --> - <td><a href="http://wg21.link/p0969r0">P0969R0</a> (<a href="#dr">DR</a>)</td> - <td class="none" align="center">No</td> - </tr> - <tr> - <td>Separate variable and condition for <tt>if</tt> and <tt>switch</tt></td> - <td><a href="http://wg21.link/p0305r1">P0305R1</a></td> - <td class="full" align="center">Clang 3.9</td> - </tr> - <!-- Issaquah 2016 papers --> - <tr> - <td>Matching template template parameters to compatible arguments</td> - <td><a href="http://wg21.link/p0522r0">P0522R0</a></td> - <td class="partial" align="center">Partial <a href="#p0522">(10)</a></td> - </tr> - <tr> - <td>Removing deprecated dynamic exception specifications</td> - <td><a href="http://wg21.link/p0003r5">P0003R5</a></td> - <td class="full" align="center">Clang 4</td> - </tr> - <tr> - <td>Pack expansions in <em>using-declarations</em></td> - <td><a href="http://wg21.link/p0195r2">P0195R2</a></td> - <td class="full" align="center">Clang 4</td> - </tr> </table> <p> -<span id="n3922">(8): This is a backwards-incompatible change that is applied to +<span id="n3922">(7): This is a backwards-incompatible change that is applied to all language versions that allow type deduction from <tt>auto</tt> (per the request of the C++ committee). In Clang 3.7, a warning is emitted for all cases that would change meaning. -</span><br> -<span id="p0145">(9): Under the MS ABI, function parameters are destroyed from -left to right in the callee. As a result, function parameters in calls to -<tt>operator<<</tt>, <tt>operator>></tt>, <tt>operator->*</tt>, -<tt>operator&&</tt>, <tt>operator||</tt>, and <tt>operator,</tt> -functions using expression syntax are no longer guaranteed to be destroyed in -reverse construction order in that ABI. -</span><br> -<span id="p0522">(10): Despite being the resolution to a Defect Report, this -feature is disabled by default in all language versions, and can be enabled -explicitly with the flag <tt>-frelaxed-template-template-args</tt> in Clang 4 -onwards. -The change to the standard lacks a corresponding change for template partial -ordering, resulting in ambiguity errors for reasonable and previously-valid -code. This issue is expected to be rectified soon. </span> </p> -</details> - -<h2 id="cxx20">C++2a implementation status</h2> - -<p>Clang has <b>experimental</b> support for some proposed features of -the C++ standard following C++17, provisionally named C++2a. -Note that support for these features may change or be removed without notice, -as the draft C++2a standard evolves. - -<p>You can use Clang in C++2a mode with the <code>-std=c++2a</code> option.</p> - -<details open> -<summary>List of features and minimum Clang version with support</summary> - -<table width="689" border="1" cellspacing="0"> - <tr> - <th>Language Feature</th> - <th>C++2a Proposal</th> - <th>Available in Clang?</th> - </tr> - <!-- Toronto 2017 papers --> - <tr> - <td>Default member initializers for bit-fields</td> - <td><a href="http://wg21.link/p0683r1">P0683R1</a></td> - <td class="full" align="center">Clang 6</td> - </tr> - <tr> - <td><tt>const&</tt>-qualified pointers to members</td> - <td><a href="http://wg21.link/p0704r1">P0704R1</a></td> - <td class="full" align="center">Clang 6</td> - </tr> - <tr> - <td>Allow <i>lambda-capture</i> <tt>[=, this]</tt></td> - <td><a href="http://wg21.link/p0409r2">P0409R2</a></td> - <td class="full" align="center">Clang 6</td> - </tr> - <tr> - <td rowspan="2"><tt>__VA_OPT__</tt> for preprocessor comma elision</td> - <td><a href="http://wg21.link/p0306r4">P0306R4</a></td> - <td class="full" align="center">Clang 6</td> - </tr> - <tr> <!-- from Rapperswil --> - <td><a href="http://wg21.link/p1042r1">P1042R1</a></td> - <td class="partial" align="center">Partial</td> - </tr> - <tr> - <td>Designated initializers</td> - <td><a href="http://wg21.link/p0329r4">P0329R4</a></td> - <td class="partial" align="center">Partial (extension)</td> - </tr> - <tr> - <td><i>template-parameter-list</i> for generic lambdas</td> - <td><a href="http://wg21.link/p0428r2">P0428R2</a></td> - <td class="none" align="center">No</td> - </tr> - <tr id="p0734"> - <td rowspan="2">Concepts</td> - <td><a href="http://wg21.link/p0734r0">P0734R0</a></td> - <td rowspan="2" class="none" align="center">No</td> - </tr> - <tr> <!-- from Albuquerque --> - <td><a href="http://wg21.link/p0857r0">P0857R0</a></td> - </tr> - <!-- Albuquerque papers --> - <tr> - <td>Range-based for statements with initializer</td> - <td><a href="http://wg21.link/p0614r1">P0614R1</a></td> - <td class="none" align="center">No</td> - </tr> - <tr> - <td>ADL and function templates that are not visible</td> - <td><a href="http://wg21.link/p0846r0">P0846R0</a></td> - <td class="none" align="center">No</td> - </tr> - <tr> - <td><tt>const</tt> mismatch with defaulted copy constructor</td> - <td><a href="http://wg21.link/p0641r2">P0641R2</a></td> - <td class="none" align="center">No</td> - </tr> - <tr> - <td rowspan="3">Consistent comparison (<tt>operator<=></tt>)</td> - <td><a href="http://wg21.link/p0515r3">P0515R3</a></td> - <td rowspan="3" class="partial" align="center">Partial</td> - </tr> - <tr> <!-- from Jacksonville --> - <td><a href="http://wg21.link/p0905r1">P0905R1</a></td> - </tr> - <tr> <!-- from Rapperswil --> - <td><a href="http://wg21.link/p1120r0">P1120R0</a></td> - </tr> - <tr> - <td>Access checking on specializations</td> - <td><a href="http://wg21.link/p0692r1">P0692R1</a></td> - <td class="partial" align="center">Partial</td> - </tr> - <tr> - <td>Default constructible and assignable stateless lambdas</td> - <td><a href="http://wg21.link/p0624r2">P0624R2</a></td> - <td class="none" align="center">No</td> - </tr> - <tr> - <td>Lambdas in unevaluated contexts</td> - <td><a href="http://wg21.link/p0315r4">P0315R4</a></td> - <td class="none" align="center">No</td> - </tr> - <!-- Jacksonville papers --> - <tr> - <td><tt>[[no_unique_address]]</tt> attribute</td> - <td><a href="http://wg21.link/p0840r2">P0840R2</a></td> - <td class="none" align="center">No</td> - </tr> - <tr> - <td><tt>[[likely]]</tt> and <tt>[[unlikely]]</tt> attributes</td> - <td><a href="http://wg21.link/p0479r5">P0479R5</a></td> - <td class="none" align="center">No</td> - </tr> - <tr> - <td><tt>typename</tt> optional in more contexts</td> - <td><a href="http://wg21.link/p0634r3">P0634R3</a></td> - <td class="none" align="center">No</td> - </tr> - <tr> - <td>Pack expansion in lambda <i>init-capture</i></td> - <td><a href="http://wg21.link/p0780r2">P0780R2</a></td> - <td class="none" align="center">No</td> - </tr> - <!-- Rapperswil papers --> - <tr> - <td>Class types as non-type template parameters</td> - <td><a href="http://wg21.link/p0732r2">P0732R2</a></td> - <td class="none" align="center">No</td> - </tr> - <tr> - <td>Destroying operator delete</td> - <td><a href="http://wg21.link/p0722r3">P0722R3</a></td> - <td class="full" align="center">Clang 6</td> - </tr> - <tr> - <td>Virtual function calls in constant expressions</td> - <td><a href="http://wg21.link/p1064r0">P1064R0</a></td> - <td class="none" align="center">No</td> - </tr> - <tr> - <td>Prohibit aggregates with user-declared constructors</td> - <td><a href="http://wg21.link/p1008r1">P1008R1</a></td> - <td class="none" align="center">No</td> - </tr> - <tr> - <td>Contracts</td> - <td><a href="http://wg21.link/p0542r5">P0542R5</a></td> - <td class="none" align="center">No</td> - </tr> - <tr> - <td>Feature test macros</td> - <td><a href="http://wg21.link/p0941r2">P0941R2</a></td> - <td class="full" align="center"><a href="#sd6">(see below)</a></td> - </tr> - <tr> - <td><tt>explicit(bool)</tt></td> - <td><a href="http://wg21.link/p0892r2">P0892R2</a></td> - <td class="none" align="center">No</td> - </tr> -</table> -</details> - -<h2 id="dr">Defect reports</h2> - -<p>Clang generally aims to implement resolutions to Defect Reports (bug fixes -against prior standards) retroactively, in all prior standard versions where -the fix is meaningful. Significant Defect Report changes to language features -after the publication of the relevant standard are marked (DR) in the above -table.</p> - -<p>Clang also has a test suite for conformance to resolutions for issues on the -<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_toc.html">C++ core issues list</a>, -most of which are considered Defect Reports. -<a href="cxx_dr_status.html">Implementation status for C++ core issues</a> based on -that test suite is tracked on a separate page.</p> <h2 id="ts">Technical specifications and standing documents</h2> <p>ISO C++ also publishes a number of documents describing additional language -and library features that are not part of standard C++.</p> - -<details open> -<summary>List of features and minimum Clang version with support</summary> +and library features that are not part of standard C++. The following table +describes which language features have been implemented in Clang and in which +Clang version they became available:</p> <table width="689" border="1" cellspacing="0"> <tr> <th>Document</th> <th>Latest draft</th> - <th>Compiler flag</th> <th>Available in Clang?</th> </tr> - <tr id="sd6"> - <td rowspan="5">SD-6: SG10 feature test recommendations</td> - <td rowspan="5"><a href="http://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations">SD-6</a></td> - <td rowspan="5">N/A</td> + <tr> + <td rowspan="2">SD-6: SG10 feature test recommendations</td> + <td rowspan="2"><a href="http://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations">SD-6</a></td> <td class="full" align="center"> Clang 3.4 (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3745">N3745</a>)</br> </td> @@ -1014,31 +648,16 @@ and library features that are not part of standard C++.</p> Clang 3.6 (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4200">N4200</a>)</a> </td> </tr> - <tr> - <td class="full" align="center"> - Clang 4 (<a href="http://wg21.link/p0096r3">P0096R3</a>)</a> - </td> - </tr> - <tr> - <td class="full" align="center"> - Clang 5 (<a href="http://wg21.link/p0096r4">P0096R4</a>)</a> - </td> - </tr> - <tr> - <td class="svn" align="center"> - Clang 7 (<a href="http://wg21.link/p0096r5">P0096R5</a>)</a> - </td> - </tr> <!-- FIXME: Implement latest recommendations. <tr> <td class="svn" align="center"> - SVN (<a href="http://wg21.link/p0096r3">P0096R3</a>)</a> + SVN (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0096r0">P0096R0</a>)</a> </td> </tr> --> <!-- No compiler support is known to be needed for: * Concurrency TS - * Parallelism TS (v1, v2) + * Parallelism TS * Ranges TS * Networking TS * File System TS @@ -1046,48 +665,24 @@ and library features that are not part of standard C++.</p> <tr> <td>[TS] Concepts</td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0121r0.pdf">P0121R0</a></td> - <td></td> - <td class="na" align="center">Superseded by <a href="#p0734">P0734R0</a></td> - </tr> - <tr> - <!-- track unimplemented Coroutines features: p0913r1 p0914r1 --> - <td>[DRAFT TS] Coroutines</td> - <td><a href="https://isocpp.org/files/papers/N4663.pdf">N4663</a></td> - <td><tt>-fcoroutines-ts<br>-stdlib=libc++</tt></td> - <td class="full" align="center">Clang 5</td> + <td class="none" align="center">No</td> </tr> <tr> <td>[TS] Library Fundamentals, Version 1 (invocation type traits)</td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4480.html">N4480</a></td> - <td>N/A</td> <td class="none" align="center">No</td> </tr> <tr> - <td>[TS] Library Fundamentals, Version 2 (<tt>source_location</tt>)</td> - <td><a href="http://wg21.link/n4617">N4617</a></td> - <td>N/A</td> - <td class="none" align="center">No</td> - </tr> - <tr> - <td>[TS] Modules</td> - <td><a href="http://wg21.link/n4720">N4720</a></td> - <td><tt>-fmodules-ts</tt></td> - <td class="none" align="center">WIP</td> - </tr> - <tr> - <td>[DRAFT TS] Reflection</td> - <td><a href="http://wg21.link/n4746">N4746</a></td> - <td></td> + <td>[DRAFT TS] Library Fundamentals, Version 2 (<tt>source_location</tt>)</td> + <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4529.html">N4529</a></td> <td class="none" align="center">No</td> </tr> <tr> <td>[TS] Transactional Memory</td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4514.pdf">N4514</a></td> - <td></td> <td class="none" align="center">No</td> </tr> </table> -</details> </div> </body> diff --git a/gnu/llvm/tools/clang/www/make_cxx_dr_status b/gnu/llvm/tools/clang/www/make_cxx_dr_status index a6f616acc25..4d847b8306c 100755 --- a/gnu/llvm/tools/clang/www/make_cxx_dr_status +++ b/gnu/llvm/tools/clang/www/make_cxx_dr_status @@ -79,7 +79,7 @@ print >> out_file, '''\ <!--*************************************************************************--> <h1>C++ Defect Report Support in Clang</h1> <!--*************************************************************************--> -<p>Last updated: $Date: 2019/01/27 16:43:08 $</p> +<p>Last updated: $Date: 2016/09/03 22:46:56 $</p> <h2 id="cxxdr">C++ defect report implementation status</h2> @@ -99,22 +99,13 @@ def availability(issue): if status.endswith(' c++11'): status = status[:-6] avail_suffix = ' (C++11 onwards)' - elif status.endswith(' c++14'): - status = status[:-6] - avail_suffix = ' (C++14 onwards)' - elif status.endswith(' c++17'): - status = status[:-6] - avail_suffix = ' (C++17 onwards)' if status == 'unknown': avail = 'Unknown' avail_style = ' class="none"' - elif status == '8': + elif status == '3.9': avail = 'SVN' avail_style = ' class="svn"' - elif status == '7': - avail = 'Clang 7' - avail_style = ' class="svn"' - elif re.match('^[0-9]+\.?[0-9]*', status): + elif status.startswith('3.'): avail = 'Clang %s' % status avail_style = ' class="full"' elif status == 'yes': @@ -129,12 +120,6 @@ def availability(issue): elif status == 'na': avail = 'N/A' avail_style = ' class="na"' - elif status == 'na lib': - avail = 'N/A (Library DR)' - avail_style = ' class="na"' - elif status == 'na abi': - avail = 'N/A (ABI constraint)' - avail_style = ' class="na"' elif status.startswith('sup '): dup = status.split(' ', 1)[1] avail = 'Superseded by <a href="#%s">%s</a>' % (dup, dup) @@ -176,7 +161,7 @@ for dr in drs: <td%s align="center">%s</td> </tr>''' % (row_style, dr.issue, dr.url, dr.issue, dr.status, dr.title, avail_style, avail) -for status, num in sorted(count.items()): +for status, num in count.items(): print "%s: %s" % (status, num) print >> out_file, '''\ diff --git a/gnu/llvm/unittests/ExecutionEngine/Orc/CompileOnDemandLayerTest.cpp b/gnu/llvm/unittests/ExecutionEngine/Orc/CompileOnDemandLayerTest.cpp index a1f864bae01..a27e649b616 100644 --- a/gnu/llvm/unittests/ExecutionEngine/Orc/CompileOnDemandLayerTest.cpp +++ b/gnu/llvm/unittests/ExecutionEngine/Orc/CompileOnDemandLayerTest.cpp @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h" #include "OrcTestCommon.h" +#include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h" #include "gtest/gtest.h" using namespace llvm; @@ -18,67 +18,58 @@ namespace { class DummyCallbackManager : public orc::JITCompileCallbackManager { public: - DummyCallbackManager(ExecutionSession &ES) - : JITCompileCallbackManager(ES, 0) {} - + DummyCallbackManager() : JITCompileCallbackManager(0) { } public: - Error grow() override { llvm_unreachable("not implemented"); } + void grow() override { llvm_unreachable("not implemented"); } }; class DummyStubsManager : public orc::IndirectStubsManager { public: - Error createStub(StringRef StubName, JITTargetAddress InitAddr, - JITSymbolFlags Flags) override { + std::error_code createStub(StringRef StubName, TargetAddress InitAddr, + JITSymbolFlags Flags) override { llvm_unreachable("Not implemented"); } - Error createStubs(const StubInitsMap &StubInits) override { + std::error_code createStubs(const StubInitsMap &StubInits) override { llvm_unreachable("Not implemented"); } - JITEvaluatedSymbol findStub(StringRef Name, bool ExportedStubsOnly) override { + JITSymbol findStub(StringRef Name, bool ExportedStubsOnly) override { llvm_unreachable("Not implemented"); } - JITEvaluatedSymbol findPointer(StringRef Name) override { + JITSymbol findPointer(StringRef Name) override { llvm_unreachable("Not implemented"); } - Error updatePointer(StringRef Name, JITTargetAddress NewAddr) override { + std::error_code updatePointer(StringRef Name, + TargetAddress NewAddr) override { llvm_unreachable("Not implemented"); } }; TEST(CompileOnDemandLayerTest, FindSymbol) { - MockBaseLayer<int, std::shared_ptr<Module>> TestBaseLayer; - TestBaseLayer.findSymbolImpl = - [](const std::string &Name, bool) { - if (Name == "foo") - return JITSymbol(1, JITSymbolFlags::Exported); - return JITSymbol(nullptr); - }; - - - ExecutionSession ES(std::make_shared<SymbolStringPool>()); - DummyCallbackManager CallbackMgr(ES); - - auto GetResolver = - [](orc::VModuleKey) -> std::shared_ptr<llvm::orc::SymbolResolver> { - llvm_unreachable("Should never be called"); - }; - - auto SetResolver = [](orc::VModuleKey, std::shared_ptr<orc::SymbolResolver>) { - llvm_unreachable("Should never be called"); - }; - - llvm::orc::CompileOnDemandLayer<decltype(TestBaseLayer)> COD( - ES, TestBaseLayer, GetResolver, SetResolver, - [](Function &F) { return std::set<Function *>{&F}; }, CallbackMgr, - [] { return llvm::make_unique<DummyStubsManager>(); }, true); + auto MockBaseLayer = + createMockBaseLayer<int>(DoNothingAndReturn<int>(0), + DoNothingAndReturn<void>(), + [](const std::string &Name, bool) { + if (Name == "foo") + return JITSymbol(1, JITSymbolFlags::Exported); + return JITSymbol(nullptr); + }, + DoNothingAndReturn<JITSymbol>(nullptr)); + + typedef decltype(MockBaseLayer) MockBaseLayerT; + DummyCallbackManager CallbackMgr; + + llvm::orc::CompileOnDemandLayer<MockBaseLayerT> COD( + MockBaseLayer, [](Function &F) { return std::set<Function *>{&F}; }, + CallbackMgr, [] { return llvm::make_unique<DummyStubsManager>(); }, true); auto Sym = COD.findSymbol("foo", true); - EXPECT_TRUE(!!Sym) << "CompileOnDemand::findSymbol should call findSymbol in " - "the base layer."; + EXPECT_TRUE(!!Sym) + << "CompileOnDemand::findSymbol should call findSymbol in the base layer."; } + } diff --git a/gnu/llvm/unittests/IR/TypeBuilderTest.cpp b/gnu/llvm/unittests/IR/TypeBuilderTest.cpp index 9ba776543d9..b7b3e45e35e 100644 --- a/gnu/llvm/unittests/IR/TypeBuilderTest.cpp +++ b/gnu/llvm/unittests/IR/TypeBuilderTest.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "llvm/IR/TypeBuilder.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/IR/LLVMContext.h" #include "gtest/gtest.h" @@ -16,175 +17,141 @@ using namespace llvm; namespace { TEST(TypeBuilderTest, Void) { - LLVMContext Context; - EXPECT_EQ(Type::getVoidTy(Context), (TypeBuilder<void, true>::get(Context))); - EXPECT_EQ(Type::getVoidTy(Context), (TypeBuilder<void, false>::get(Context))); + EXPECT_EQ(Type::getVoidTy(getGlobalContext()), (TypeBuilder<void, true>::get(getGlobalContext()))); + EXPECT_EQ(Type::getVoidTy(getGlobalContext()), (TypeBuilder<void, false>::get(getGlobalContext()))); // Special cases for C compatibility: - EXPECT_EQ(Type::getInt8PtrTy(Context), - (TypeBuilder<void *, false>::get(Context))); - EXPECT_EQ(Type::getInt8PtrTy(Context), - (TypeBuilder<const void *, false>::get(Context))); - EXPECT_EQ(Type::getInt8PtrTy(Context), - (TypeBuilder<volatile void *, false>::get(Context))); - EXPECT_EQ(Type::getInt8PtrTy(Context), - (TypeBuilder<const volatile void *, false>::get(Context))); + EXPECT_EQ(Type::getInt8PtrTy(getGlobalContext()), + (TypeBuilder<void*, false>::get(getGlobalContext()))); + EXPECT_EQ(Type::getInt8PtrTy(getGlobalContext()), + (TypeBuilder<const void*, false>::get(getGlobalContext()))); + EXPECT_EQ(Type::getInt8PtrTy(getGlobalContext()), + (TypeBuilder<volatile void*, false>::get(getGlobalContext()))); + EXPECT_EQ(Type::getInt8PtrTy(getGlobalContext()), + (TypeBuilder<const volatile void*, false>::get( + getGlobalContext()))); } TEST(TypeBuilderTest, HostIntegers) { - LLVMContext Context; - EXPECT_EQ(Type::getInt8Ty(Context), - (TypeBuilder<int8_t, false>::get(Context))); - EXPECT_EQ(Type::getInt8Ty(Context), - (TypeBuilder<uint8_t, false>::get(Context))); - EXPECT_EQ(Type::getInt16Ty(Context), - (TypeBuilder<int16_t, false>::get(Context))); - EXPECT_EQ(Type::getInt16Ty(Context), - (TypeBuilder<uint16_t, false>::get(Context))); - EXPECT_EQ(Type::getInt32Ty(Context), - (TypeBuilder<int32_t, false>::get(Context))); - EXPECT_EQ(Type::getInt32Ty(Context), - (TypeBuilder<uint32_t, false>::get(Context))); - EXPECT_EQ(Type::getInt64Ty(Context), - (TypeBuilder<int64_t, false>::get(Context))); - EXPECT_EQ(Type::getInt64Ty(Context), - (TypeBuilder<uint64_t, false>::get(Context))); - - EXPECT_EQ(IntegerType::get(Context, sizeof(size_t) * CHAR_BIT), - (TypeBuilder<size_t, false>::get(Context))); - EXPECT_EQ(IntegerType::get(Context, sizeof(ptrdiff_t) * CHAR_BIT), - (TypeBuilder<ptrdiff_t, false>::get(Context))); + EXPECT_EQ(Type::getInt8Ty(getGlobalContext()), (TypeBuilder<int8_t, false>::get(getGlobalContext()))); + EXPECT_EQ(Type::getInt8Ty(getGlobalContext()), (TypeBuilder<uint8_t, false>::get(getGlobalContext()))); + EXPECT_EQ(Type::getInt16Ty(getGlobalContext()), (TypeBuilder<int16_t, false>::get(getGlobalContext()))); + EXPECT_EQ(Type::getInt16Ty(getGlobalContext()), (TypeBuilder<uint16_t, false>::get(getGlobalContext()))); + EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), (TypeBuilder<int32_t, false>::get(getGlobalContext()))); + EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), (TypeBuilder<uint32_t, false>::get(getGlobalContext()))); + EXPECT_EQ(Type::getInt64Ty(getGlobalContext()), (TypeBuilder<int64_t, false>::get(getGlobalContext()))); + EXPECT_EQ(Type::getInt64Ty(getGlobalContext()), (TypeBuilder<uint64_t, false>::get(getGlobalContext()))); + + EXPECT_EQ(IntegerType::get(getGlobalContext(), sizeof(size_t) * CHAR_BIT), + (TypeBuilder<size_t, false>::get(getGlobalContext()))); + EXPECT_EQ(IntegerType::get(getGlobalContext(), sizeof(ptrdiff_t) * CHAR_BIT), + (TypeBuilder<ptrdiff_t, false>::get(getGlobalContext()))); } TEST(TypeBuilderTest, CrossCompilableIntegers) { - LLVMContext Context; - EXPECT_EQ(IntegerType::get(Context, 1), - (TypeBuilder<types::i<1>, true>::get(Context))); - EXPECT_EQ(IntegerType::get(Context, 1), - (TypeBuilder<types::i<1>, false>::get(Context))); - EXPECT_EQ(IntegerType::get(Context, 72), - (TypeBuilder<types::i<72>, true>::get(Context))); - EXPECT_EQ(IntegerType::get(Context, 72), - (TypeBuilder<types::i<72>, false>::get(Context))); + EXPECT_EQ(IntegerType::get(getGlobalContext(), 1), (TypeBuilder<types::i<1>, true>::get(getGlobalContext()))); + EXPECT_EQ(IntegerType::get(getGlobalContext(), 1), (TypeBuilder<types::i<1>, false>::get(getGlobalContext()))); + EXPECT_EQ(IntegerType::get(getGlobalContext(), 72), (TypeBuilder<types::i<72>, true>::get(getGlobalContext()))); + EXPECT_EQ(IntegerType::get(getGlobalContext(), 72), (TypeBuilder<types::i<72>, false>::get(getGlobalContext()))); } TEST(TypeBuilderTest, Float) { - LLVMContext Context; - EXPECT_EQ(Type::getFloatTy(Context), - (TypeBuilder<float, false>::get(Context))); - EXPECT_EQ(Type::getDoubleTy(Context), - (TypeBuilder<double, false>::get(Context))); + EXPECT_EQ(Type::getFloatTy(getGlobalContext()), (TypeBuilder<float, false>::get(getGlobalContext()))); + EXPECT_EQ(Type::getDoubleTy(getGlobalContext()), (TypeBuilder<double, false>::get(getGlobalContext()))); // long double isn't supported yet. - EXPECT_EQ(Type::getFloatTy(Context), - (TypeBuilder<types::ieee_float, true>::get(Context))); - EXPECT_EQ(Type::getFloatTy(Context), - (TypeBuilder<types::ieee_float, false>::get(Context))); - EXPECT_EQ(Type::getDoubleTy(Context), - (TypeBuilder<types::ieee_double, true>::get(Context))); - EXPECT_EQ(Type::getDoubleTy(Context), - (TypeBuilder<types::ieee_double, false>::get(Context))); - EXPECT_EQ(Type::getX86_FP80Ty(Context), - (TypeBuilder<types::x86_fp80, true>::get(Context))); - EXPECT_EQ(Type::getX86_FP80Ty(Context), - (TypeBuilder<types::x86_fp80, false>::get(Context))); - EXPECT_EQ(Type::getFP128Ty(Context), - (TypeBuilder<types::fp128, true>::get(Context))); - EXPECT_EQ(Type::getFP128Ty(Context), - (TypeBuilder<types::fp128, false>::get(Context))); - EXPECT_EQ(Type::getPPC_FP128Ty(Context), - (TypeBuilder<types::ppc_fp128, true>::get(Context))); - EXPECT_EQ(Type::getPPC_FP128Ty(Context), - (TypeBuilder<types::ppc_fp128, false>::get(Context))); + EXPECT_EQ(Type::getFloatTy(getGlobalContext()), (TypeBuilder<types::ieee_float, true>::get(getGlobalContext()))); + EXPECT_EQ(Type::getFloatTy(getGlobalContext()), (TypeBuilder<types::ieee_float, false>::get(getGlobalContext()))); + EXPECT_EQ(Type::getDoubleTy(getGlobalContext()), (TypeBuilder<types::ieee_double, true>::get(getGlobalContext()))); + EXPECT_EQ(Type::getDoubleTy(getGlobalContext()), (TypeBuilder<types::ieee_double, false>::get(getGlobalContext()))); + EXPECT_EQ(Type::getX86_FP80Ty(getGlobalContext()), (TypeBuilder<types::x86_fp80, true>::get(getGlobalContext()))); + EXPECT_EQ(Type::getX86_FP80Ty(getGlobalContext()), (TypeBuilder<types::x86_fp80, false>::get(getGlobalContext()))); + EXPECT_EQ(Type::getFP128Ty(getGlobalContext()), (TypeBuilder<types::fp128, true>::get(getGlobalContext()))); + EXPECT_EQ(Type::getFP128Ty(getGlobalContext()), (TypeBuilder<types::fp128, false>::get(getGlobalContext()))); + EXPECT_EQ(Type::getPPC_FP128Ty(getGlobalContext()), (TypeBuilder<types::ppc_fp128, true>::get(getGlobalContext()))); + EXPECT_EQ(Type::getPPC_FP128Ty(getGlobalContext()), (TypeBuilder<types::ppc_fp128, false>::get(getGlobalContext()))); } TEST(TypeBuilderTest, Derived) { - LLVMContext Context; - EXPECT_EQ(PointerType::getUnqual(Type::getInt8PtrTy(Context)), - (TypeBuilder<int8_t **, false>::get(Context))); - EXPECT_EQ(ArrayType::get(Type::getInt8Ty(Context), 7), - (TypeBuilder<int8_t[7], false>::get(Context))); - EXPECT_EQ(ArrayType::get(Type::getInt8Ty(Context), 0), - (TypeBuilder<int8_t[], false>::get(Context))); - - EXPECT_EQ(PointerType::getUnqual(Type::getInt8PtrTy(Context)), - (TypeBuilder<types::i<8> **, false>::get(Context))); - EXPECT_EQ(ArrayType::get(Type::getInt8Ty(Context), 7), - (TypeBuilder<types::i<8>[7], false>::get(Context))); - EXPECT_EQ(ArrayType::get(Type::getInt8Ty(Context), 0), - (TypeBuilder<types::i<8>[], false>::get(Context))); - - EXPECT_EQ(PointerType::getUnqual(Type::getInt8PtrTy(Context)), - (TypeBuilder<types::i<8> **, true>::get(Context))); - EXPECT_EQ(ArrayType::get(Type::getInt8Ty(Context), 7), - (TypeBuilder<types::i<8>[7], true>::get(Context))); - EXPECT_EQ(ArrayType::get(Type::getInt8Ty(Context), 0), - (TypeBuilder<types::i<8>[], true>::get(Context))); - - EXPECT_EQ(Type::getInt8Ty(Context), - (TypeBuilder<const int8_t, false>::get(Context))); - EXPECT_EQ(Type::getInt8Ty(Context), - (TypeBuilder<volatile int8_t, false>::get(Context))); - EXPECT_EQ(Type::getInt8Ty(Context), - (TypeBuilder<const volatile int8_t, false>::get(Context))); - - EXPECT_EQ(Type::getInt8Ty(Context), - (TypeBuilder<const types::i<8>, false>::get(Context))); - EXPECT_EQ(Type::getInt8Ty(Context), - (TypeBuilder<volatile types::i<8>, false>::get(Context))); - EXPECT_EQ(Type::getInt8Ty(Context), - (TypeBuilder<const volatile types::i<8>, false>::get(Context))); - - EXPECT_EQ(Type::getInt8Ty(Context), - (TypeBuilder<const types::i<8>, true>::get(Context))); - EXPECT_EQ(Type::getInt8Ty(Context), - (TypeBuilder<volatile types::i<8>, true>::get(Context))); - EXPECT_EQ(Type::getInt8Ty(Context), - (TypeBuilder<const volatile types::i<8>, true>::get(Context))); - - EXPECT_EQ(Type::getInt8PtrTy(Context), - (TypeBuilder<const volatile int8_t *const volatile, false>::get( - Context))); + EXPECT_EQ(PointerType::getUnqual(Type::getInt8PtrTy(getGlobalContext())), + (TypeBuilder<int8_t**, false>::get(getGlobalContext()))); + EXPECT_EQ(ArrayType::get(Type::getInt8Ty(getGlobalContext()), 7), + (TypeBuilder<int8_t[7], false>::get(getGlobalContext()))); + EXPECT_EQ(ArrayType::get(Type::getInt8Ty(getGlobalContext()), 0), + (TypeBuilder<int8_t[], false>::get(getGlobalContext()))); + + EXPECT_EQ(PointerType::getUnqual(Type::getInt8PtrTy(getGlobalContext())), + (TypeBuilder<types::i<8>**, false>::get(getGlobalContext()))); + EXPECT_EQ(ArrayType::get(Type::getInt8Ty(getGlobalContext()), 7), + (TypeBuilder<types::i<8>[7], false>::get(getGlobalContext()))); + EXPECT_EQ(ArrayType::get(Type::getInt8Ty(getGlobalContext()), 0), + (TypeBuilder<types::i<8>[], false>::get(getGlobalContext()))); + + EXPECT_EQ(PointerType::getUnqual(Type::getInt8PtrTy(getGlobalContext())), + (TypeBuilder<types::i<8>**, true>::get(getGlobalContext()))); + EXPECT_EQ(ArrayType::get(Type::getInt8Ty(getGlobalContext()), 7), + (TypeBuilder<types::i<8>[7], true>::get(getGlobalContext()))); + EXPECT_EQ(ArrayType::get(Type::getInt8Ty(getGlobalContext()), 0), + (TypeBuilder<types::i<8>[], true>::get(getGlobalContext()))); + + + EXPECT_EQ(Type::getInt8Ty(getGlobalContext()), + (TypeBuilder<const int8_t, false>::get(getGlobalContext()))); + EXPECT_EQ(Type::getInt8Ty(getGlobalContext()), + (TypeBuilder<volatile int8_t, false>::get(getGlobalContext()))); + EXPECT_EQ(Type::getInt8Ty(getGlobalContext()), + (TypeBuilder<const volatile int8_t, false>::get(getGlobalContext()))); + + EXPECT_EQ(Type::getInt8Ty(getGlobalContext()), + (TypeBuilder<const types::i<8>, false>::get(getGlobalContext()))); + EXPECT_EQ(Type::getInt8Ty(getGlobalContext()), + (TypeBuilder<volatile types::i<8>, false>::get(getGlobalContext()))); + EXPECT_EQ(Type::getInt8Ty(getGlobalContext()), + (TypeBuilder<const volatile types::i<8>, false>::get(getGlobalContext()))); + + EXPECT_EQ(Type::getInt8Ty(getGlobalContext()), + (TypeBuilder<const types::i<8>, true>::get(getGlobalContext()))); + EXPECT_EQ(Type::getInt8Ty(getGlobalContext()), + (TypeBuilder<volatile types::i<8>, true>::get(getGlobalContext()))); + EXPECT_EQ(Type::getInt8Ty(getGlobalContext()), + (TypeBuilder<const volatile types::i<8>, true>::get(getGlobalContext()))); + + EXPECT_EQ(Type::getInt8PtrTy(getGlobalContext()), + (TypeBuilder<const volatile int8_t*const volatile, false>::get(getGlobalContext()))); } TEST(TypeBuilderTest, Functions) { - LLVMContext Context; std::vector<Type*> params; - EXPECT_EQ(FunctionType::get(Type::getVoidTy(Context), params, false), - (TypeBuilder<void(), true>::get(Context))); - EXPECT_EQ(FunctionType::get(Type::getInt8Ty(Context), params, true), - (TypeBuilder<int8_t(...), false>::get(Context))); - params.push_back(TypeBuilder<int32_t *, false>::get(Context)); - EXPECT_EQ(FunctionType::get(Type::getInt8Ty(Context), params, false), - (TypeBuilder<int8_t(const int32_t *), false>::get(Context))); - EXPECT_EQ(FunctionType::get(Type::getInt8Ty(Context), params, true), - (TypeBuilder<int8_t(const int32_t *, ...), false>::get(Context))); - params.push_back(TypeBuilder<char *, false>::get(Context)); - EXPECT_EQ(FunctionType::get(Type::getInt8Ty(Context), params, false), - (TypeBuilder<int8_t(int32_t *, void *), false>::get(Context))); - EXPECT_EQ(FunctionType::get(Type::getInt8Ty(Context), params, true), - (TypeBuilder<int8_t(int32_t *, char *, ...), false>::get(Context))); - params.push_back(TypeBuilder<char, false>::get(Context)); - EXPECT_EQ( - FunctionType::get(Type::getInt8Ty(Context), params, false), - (TypeBuilder<int8_t(int32_t *, void *, char), false>::get(Context))); - EXPECT_EQ( - FunctionType::get(Type::getInt8Ty(Context), params, true), - (TypeBuilder<int8_t(int32_t *, char *, char, ...), false>::get(Context))); - params.push_back(TypeBuilder<char, false>::get(Context)); - EXPECT_EQ(FunctionType::get(Type::getInt8Ty(Context), params, false), - (TypeBuilder<int8_t(int32_t *, void *, char, char), false>::get( - Context))); - EXPECT_EQ( - FunctionType::get(Type::getInt8Ty(Context), params, true), - (TypeBuilder<int8_t(int32_t *, char *, char, char, ...), false>::get( - Context))); - params.push_back(TypeBuilder<char, false>::get(Context)); - EXPECT_EQ( - FunctionType::get(Type::getInt8Ty(Context), params, false), - (TypeBuilder<int8_t(int32_t *, void *, char, char, char), false>::get( - Context))); - EXPECT_EQ(FunctionType::get(Type::getInt8Ty(Context), params, true), - (TypeBuilder<int8_t(int32_t *, char *, char, char, char, ...), - false>::get(Context))); + EXPECT_EQ(FunctionType::get(Type::getVoidTy(getGlobalContext()), params, false), + (TypeBuilder<void(), true>::get(getGlobalContext()))); + EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, true), + (TypeBuilder<int8_t(...), false>::get(getGlobalContext()))); + params.push_back(TypeBuilder<int32_t*, false>::get(getGlobalContext())); + EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, false), + (TypeBuilder<int8_t(const int32_t*), false>::get(getGlobalContext()))); + EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, true), + (TypeBuilder<int8_t(const int32_t*, ...), false>::get(getGlobalContext()))); + params.push_back(TypeBuilder<char*, false>::get(getGlobalContext())); + EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, false), + (TypeBuilder<int8_t(int32_t*, void*), false>::get(getGlobalContext()))); + EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, true), + (TypeBuilder<int8_t(int32_t*, char*, ...), false>::get(getGlobalContext()))); + params.push_back(TypeBuilder<char, false>::get(getGlobalContext())); + EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, false), + (TypeBuilder<int8_t(int32_t*, void*, char), false>::get(getGlobalContext()))); + EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, true), + (TypeBuilder<int8_t(int32_t*, char*, char, ...), false>::get(getGlobalContext()))); + params.push_back(TypeBuilder<char, false>::get(getGlobalContext())); + EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, false), + (TypeBuilder<int8_t(int32_t*, void*, char, char), false>::get(getGlobalContext()))); + EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, true), + (TypeBuilder<int8_t(int32_t*, char*, char, char, ...), + false>::get(getGlobalContext()))); + params.push_back(TypeBuilder<char, false>::get(getGlobalContext())); + EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, false), + (TypeBuilder<int8_t(int32_t*, void*, char, char, char), + false>::get(getGlobalContext()))); + EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, true), + (TypeBuilder<int8_t(int32_t*, char*, char, char, char, ...), + false>::get(getGlobalContext()))); } TEST(TypeBuilderTest, Context) { @@ -263,22 +230,24 @@ public: namespace { TEST(TypeBuilderTest, Extensions) { - LLVMContext Context; - EXPECT_EQ(PointerType::getUnqual( - StructType::get(TypeBuilder<int, false>::get(Context), - TypeBuilder<int *, false>::get(Context), - TypeBuilder<void *[], false>::get(Context))), - (TypeBuilder<MyType *, false>::get(Context))); EXPECT_EQ(PointerType::getUnqual(StructType::get( - TypeBuilder<types::i<32>, false>::get(Context), - TypeBuilder<types::i<32> *, false>::get(Context), - TypeBuilder<types::i<8> *[], false>::get(Context))), - (TypeBuilder<MyPortableType *, false>::get(Context))); + TypeBuilder<int, false>::get(getGlobalContext()), + TypeBuilder<int*, false>::get(getGlobalContext()), + TypeBuilder<void*[], false>::get(getGlobalContext()), + (void*)nullptr)), + (TypeBuilder<MyType*, false>::get(getGlobalContext()))); + EXPECT_EQ(PointerType::getUnqual(StructType::get( + TypeBuilder<types::i<32>, false>::get(getGlobalContext()), + TypeBuilder<types::i<32>*, false>::get(getGlobalContext()), + TypeBuilder<types::i<8>*[], false>::get(getGlobalContext()), + (void*)nullptr)), + (TypeBuilder<MyPortableType*, false>::get(getGlobalContext()))); EXPECT_EQ(PointerType::getUnqual(StructType::get( - TypeBuilder<types::i<32>, false>::get(Context), - TypeBuilder<types::i<32> *, false>::get(Context), - TypeBuilder<types::i<8> *[], false>::get(Context))), - (TypeBuilder<MyPortableType *, true>::get(Context))); + TypeBuilder<types::i<32>, false>::get(getGlobalContext()), + TypeBuilder<types::i<32>*, false>::get(getGlobalContext()), + TypeBuilder<types::i<8>*[], false>::get(getGlobalContext()), + (void*)nullptr)), + (TypeBuilder<MyPortableType*, true>::get(getGlobalContext()))); } } // anonymous namespace diff --git a/gnu/llvm/unittests/Transforms/Utils/Cloning.cpp b/gnu/llvm/unittests/Transforms/Utils/Cloning.cpp index 9a1ad19ebaa..25e322ee5a8 100644 --- a/gnu/llvm/unittests/Transforms/Utils/Cloning.cpp +++ b/gnu/llvm/unittests/Transforms/Utils/Cloning.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Transforms/Utils/Cloning.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/IR/Argument.h" @@ -41,18 +42,13 @@ protected: } void eraseClones() { - for (Value *V : Clones) - V->deleteValue(); - Clones.clear(); + DeleteContainerPointers(Clones); } void TearDown() override { eraseClones(); - for (Value *V : Orig) - V->deleteValue(); - Orig.clear(); - if (V) - V->deleteValue(); + DeleteContainerPointers(Orig); + delete V; } SmallPtrSet<Value *, 4> Orig; // Erase on exit @@ -167,8 +163,10 @@ TEST_F(CloneInstruction, Attributes) { Function *F2 = Function::Create(FT1, Function::ExternalLinkage); + Attribute::AttrKind AK[] = { Attribute::NoCapture }; + AttributeSet AS = AttributeSet::get(context, 0, AK); Argument *A = &*F1->arg_begin(); - A->addAttr(Attribute::NoCapture); + A->addAttr(AS); SmallVector<ReturnInst*, 4> Returns; ValueToValueMapTy VMap; @@ -204,151 +202,6 @@ TEST_F(CloneInstruction, CallingConvention) { delete F2; } -TEST_F(CloneInstruction, DuplicateInstructionsToSplit) { - Type *ArgTy1[] = {Type::getInt32PtrTy(context)}; - FunctionType *FT = FunctionType::get(Type::getVoidTy(context), ArgTy1, false); - V = new Argument(Type::getInt32Ty(context)); - - Function *F = Function::Create(FT, Function::ExternalLinkage); - - BasicBlock *BB1 = BasicBlock::Create(context, "", F); - IRBuilder<> Builder1(BB1); - - BasicBlock *BB2 = BasicBlock::Create(context, "", F); - IRBuilder<> Builder2(BB2); - - Builder1.CreateBr(BB2); - - Instruction *AddInst = cast<Instruction>(Builder2.CreateAdd(V, V)); - Instruction *MulInst = cast<Instruction>(Builder2.CreateMul(AddInst, V)); - Instruction *SubInst = cast<Instruction>(Builder2.CreateSub(MulInst, V)); - Builder2.CreateRetVoid(); - - ValueToValueMapTy Mapping; - - auto Split = DuplicateInstructionsInSplitBetween(BB2, BB1, SubInst, Mapping); - - EXPECT_TRUE(Split); - EXPECT_EQ(Mapping.size(), 2u); - EXPECT_TRUE(Mapping.find(AddInst) != Mapping.end()); - EXPECT_TRUE(Mapping.find(MulInst) != Mapping.end()); - - auto AddSplit = dyn_cast<Instruction>(Mapping[AddInst]); - EXPECT_TRUE(AddSplit); - EXPECT_EQ(AddSplit->getOperand(0), V); - EXPECT_EQ(AddSplit->getOperand(1), V); - EXPECT_EQ(AddSplit->getParent(), Split); - - auto MulSplit = dyn_cast<Instruction>(Mapping[MulInst]); - EXPECT_TRUE(MulSplit); - EXPECT_EQ(MulSplit->getOperand(0), AddSplit); - EXPECT_EQ(MulSplit->getOperand(1), V); - EXPECT_EQ(MulSplit->getParent(), Split); - - EXPECT_EQ(AddSplit->getNextNode(), MulSplit); - EXPECT_EQ(MulSplit->getNextNode(), Split->getTerminator()); - - delete F; -} - -TEST_F(CloneInstruction, DuplicateInstructionsToSplitBlocksEq1) { - Type *ArgTy1[] = {Type::getInt32PtrTy(context)}; - FunctionType *FT = FunctionType::get(Type::getVoidTy(context), ArgTy1, false); - V = new Argument(Type::getInt32Ty(context)); - - Function *F = Function::Create(FT, Function::ExternalLinkage); - - BasicBlock *BB1 = BasicBlock::Create(context, "", F); - IRBuilder<> Builder1(BB1); - - BasicBlock *BB2 = BasicBlock::Create(context, "", F); - IRBuilder<> Builder2(BB2); - - Builder1.CreateBr(BB2); - - Instruction *AddInst = cast<Instruction>(Builder2.CreateAdd(V, V)); - Instruction *MulInst = cast<Instruction>(Builder2.CreateMul(AddInst, V)); - Instruction *SubInst = cast<Instruction>(Builder2.CreateSub(MulInst, V)); - Builder2.CreateBr(BB2); - - ValueToValueMapTy Mapping; - - auto Split = DuplicateInstructionsInSplitBetween(BB2, BB2, BB2->getTerminator(), Mapping); - - EXPECT_TRUE(Split); - EXPECT_EQ(Mapping.size(), 3u); - EXPECT_TRUE(Mapping.find(AddInst) != Mapping.end()); - EXPECT_TRUE(Mapping.find(MulInst) != Mapping.end()); - EXPECT_TRUE(Mapping.find(SubInst) != Mapping.end()); - - auto AddSplit = dyn_cast<Instruction>(Mapping[AddInst]); - EXPECT_TRUE(AddSplit); - EXPECT_EQ(AddSplit->getOperand(0), V); - EXPECT_EQ(AddSplit->getOperand(1), V); - EXPECT_EQ(AddSplit->getParent(), Split); - - auto MulSplit = dyn_cast<Instruction>(Mapping[MulInst]); - EXPECT_TRUE(MulSplit); - EXPECT_EQ(MulSplit->getOperand(0), AddSplit); - EXPECT_EQ(MulSplit->getOperand(1), V); - EXPECT_EQ(MulSplit->getParent(), Split); - - auto SubSplit = dyn_cast<Instruction>(Mapping[SubInst]); - EXPECT_EQ(MulSplit->getNextNode(), SubSplit); - EXPECT_EQ(SubSplit->getNextNode(), Split->getTerminator()); - EXPECT_EQ(Split->getSingleSuccessor(), BB2); - EXPECT_EQ(BB2->getSingleSuccessor(), Split); - - delete F; -} - -TEST_F(CloneInstruction, DuplicateInstructionsToSplitBlocksEq2) { - Type *ArgTy1[] = {Type::getInt32PtrTy(context)}; - FunctionType *FT = FunctionType::get(Type::getVoidTy(context), ArgTy1, false); - V = new Argument(Type::getInt32Ty(context)); - - Function *F = Function::Create(FT, Function::ExternalLinkage); - - BasicBlock *BB1 = BasicBlock::Create(context, "", F); - IRBuilder<> Builder1(BB1); - - BasicBlock *BB2 = BasicBlock::Create(context, "", F); - IRBuilder<> Builder2(BB2); - - Builder1.CreateBr(BB2); - - Instruction *AddInst = cast<Instruction>(Builder2.CreateAdd(V, V)); - Instruction *MulInst = cast<Instruction>(Builder2.CreateMul(AddInst, V)); - Instruction *SubInst = cast<Instruction>(Builder2.CreateSub(MulInst, V)); - Builder2.CreateBr(BB2); - - ValueToValueMapTy Mapping; - - auto Split = DuplicateInstructionsInSplitBetween(BB2, BB2, SubInst, Mapping); - - EXPECT_TRUE(Split); - EXPECT_EQ(Mapping.size(), 2u); - EXPECT_TRUE(Mapping.find(AddInst) != Mapping.end()); - EXPECT_TRUE(Mapping.find(MulInst) != Mapping.end()); - - auto AddSplit = dyn_cast<Instruction>(Mapping[AddInst]); - EXPECT_TRUE(AddSplit); - EXPECT_EQ(AddSplit->getOperand(0), V); - EXPECT_EQ(AddSplit->getOperand(1), V); - EXPECT_EQ(AddSplit->getParent(), Split); - - auto MulSplit = dyn_cast<Instruction>(Mapping[MulInst]); - EXPECT_TRUE(MulSplit); - EXPECT_EQ(MulSplit->getOperand(0), AddSplit); - EXPECT_EQ(MulSplit->getOperand(1), V); - EXPECT_EQ(MulSplit->getParent(), Split); - EXPECT_EQ(MulSplit->getNextNode(), Split->getTerminator()); - EXPECT_EQ(Split->getSingleSuccessor(), BB2); - EXPECT_EQ(BB2->getSingleSuccessor(), Split); - - delete F; -} - class CloneFunc : public ::testing::Test { protected: void SetUp() override { @@ -379,14 +232,12 @@ protected: DITypeRefArray ParamTypes = DBuilder.getOrCreateTypeArray(None); DISubroutineType *FuncType = DBuilder.createSubroutineType(ParamTypes); - auto *CU = DBuilder.createCompileUnit(dwarf::DW_LANG_C99, - DBuilder.createFile("filename.c", - "/file/dir"), - "CloneFunc", false, "", 0); - - auto *Subprogram = - DBuilder.createFunction(CU, "f", "f", File, 4, FuncType, true, true, 3, - DINode::FlagZero, false); + auto *CU = + DBuilder.createCompileUnit(dwarf::DW_LANG_C99, "filename.c", + "/file/dir", "CloneFunc", false, "", 0); + + auto *Subprogram = DBuilder.createFunction( + CU, "f", "f", File, 4, FuncType, true, true, 3, 0, false); OldFunc->setSubprogram(Subprogram); // Function body @@ -399,48 +250,33 @@ protected: Value* AllocaContent = IBuilder.getInt32(1); Instruction* Store = IBuilder.CreateStore(AllocaContent, Alloca); IBuilder.SetCurrentDebugLocation(DebugLoc::get(5, 2, Subprogram)); + Instruction* Terminator = IBuilder.CreateRetVoid(); // Create a local variable around the alloca - auto *IntType = DBuilder.createBasicType("int", 32, dwarf::DW_ATE_signed); + auto *IntType = + DBuilder.createBasicType("int", 32, 0, dwarf::DW_ATE_signed); auto *E = DBuilder.createExpression(); auto *Variable = DBuilder.createAutoVariable(Subprogram, "x", File, 5, IntType, true); auto *DL = DILocation::get(Subprogram->getContext(), 5, 0, Subprogram); DBuilder.insertDeclare(Alloca, Variable, E, DL, Store); - DBuilder.insertDbgValueIntrinsic(AllocaContent, Variable, E, DL, Entry); - // Also create an inlined variable. - // Create a distinct struct type that we should not duplicate during - // cloning). - auto *StructType = DICompositeType::getDistinct( - C, dwarf::DW_TAG_structure_type, "some_struct", nullptr, 0, nullptr, - nullptr, 32, 32, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr); - auto *InlinedSP = - DBuilder.createFunction(CU, "inlined", "inlined", File, 8, FuncType, - true, true, 9, DINode::FlagZero, false); - auto *InlinedVar = - DBuilder.createAutoVariable(InlinedSP, "inlined", File, 5, StructType, true); - auto *Scope = DBuilder.createLexicalBlock( - DBuilder.createLexicalBlockFile(InlinedSP, File), File, 1, 1); - auto InlinedDL = - DebugLoc::get(9, 4, Scope, DebugLoc::get(5, 2, Subprogram)); - IBuilder.SetCurrentDebugLocation(InlinedDL); - DBuilder.insertDeclare(Alloca, InlinedVar, E, InlinedDL, Store); - IBuilder.CreateStore(IBuilder.getInt32(2), Alloca); - // Finalize the debug info. + DBuilder.insertDbgValueIntrinsic(AllocaContent, 0, Variable, E, DL, + Terminator); + // Finalize the debug info DBuilder.finalize(); - IBuilder.CreateRetVoid(); - // Create another, empty, compile unit. + + // Create another, empty, compile unit DIBuilder DBuilder2(*M); DBuilder2.createCompileUnit(dwarf::DW_LANG_C99, - DBuilder.createFile("extra.c", "/file/dir"), - "CloneFunc", false, "", 0); + "extra.c", "/file/dir", "CloneFunc", false, "", 0); DBuilder2.finalize(); } void CreateNewFunc() { ValueToValueMapTy VMap; - NewFunc = CloneFunction(OldFunc, VMap, nullptr); + NewFunc = CloneFunction(OldFunc, VMap, true, nullptr); + M->getFunctionList().push_back(NewFunc); } void SetupFinder() { @@ -463,9 +299,34 @@ TEST_F(CloneFunc, NewFunctionCreated) { // Test that a new subprogram entry was added and is pointing to the new // function, while the original subprogram still points to the old one. TEST_F(CloneFunc, Subprogram) { - EXPECT_FALSE(verifyModule(*M, &errs())); - EXPECT_EQ(3U, Finder->subprogram_count()); - EXPECT_NE(NewFunc->getSubprogram(), OldFunc->getSubprogram()); + EXPECT_FALSE(verifyModule(*M)); + + unsigned SubprogramCount = Finder->subprogram_count(); + EXPECT_EQ(2U, SubprogramCount); + + auto Iter = Finder->subprograms().begin(); + auto *Sub1 = cast<DISubprogram>(*Iter); + Iter++; + auto *Sub2 = cast<DISubprogram>(*Iter); + + EXPECT_TRUE( + (Sub1 == OldFunc->getSubprogram() && Sub2 == NewFunc->getSubprogram()) || + (Sub1 == NewFunc->getSubprogram() && Sub2 == OldFunc->getSubprogram())); +} + +// Test that the new subprogram entry was not added to the CU which doesn't +// contain the old subprogram entry. +TEST_F(CloneFunc, SubprogramInRightCU) { + EXPECT_FALSE(verifyModule(*M)); + + EXPECT_EQ(2U, Finder->compile_unit_count()); + + auto Iter = Finder->compile_units().begin(); + auto *CU1 = cast<DICompileUnit>(*Iter); + Iter++; + auto *CU2 = cast<DICompileUnit>(*Iter); + EXPECT_TRUE(CU1->getSubprograms().size() == 0 || + CU2->getSubprograms().size() == 0); } // Test that instructions in the old function still belong to it in the @@ -492,8 +353,8 @@ TEST_F(CloneFunc, InstructionOwnership) { EXPECT_EQ(OldDL.getCol(), NewDL.getCol()); // But that they belong to different functions - auto *OldSubprogram = cast<DISubprogram>(OldDL.getInlinedAtScope()); - auto *NewSubprogram = cast<DISubprogram>(NewDL.getInlinedAtScope()); + auto *OldSubprogram = cast<DISubprogram>(OldDL.getScope()); + auto *NewSubprogram = cast<DISubprogram>(NewDL.getScope()); EXPECT_EQ(OldFunc->getSubprogram(), OldSubprogram); EXPECT_EQ(NewFunc->getSubprogram(), NewSubprogram); } @@ -528,30 +389,22 @@ TEST_F(CloneFunc, DebugIntrinsics) { EXPECT_EQ(NewFunc, cast<AllocaInst>(NewIntrin->getAddress())-> getParent()->getParent()); - if (OldIntrin->getDebugLoc()->getInlinedAt()) { - // Inlined variable should refer to the same DILocalVariable as in the - // Old Function - EXPECT_EQ(OldIntrin->getVariable(), NewIntrin->getVariable()); - } else { - // Old variable must belong to the old function. - EXPECT_EQ(OldFunc->getSubprogram(), - cast<DISubprogram>(OldIntrin->getVariable()->getScope())); - // New variable must belong to the new function. - EXPECT_EQ(NewFunc->getSubprogram(), - cast<DISubprogram>(NewIntrin->getVariable()->getScope())); - } + // Old variable must belong to the old function + EXPECT_EQ(OldFunc->getSubprogram(), + cast<DISubprogram>(OldIntrin->getVariable()->getScope())); + // New variable must belong to the New function + EXPECT_EQ(NewFunc->getSubprogram(), + cast<DISubprogram>(NewIntrin->getVariable()->getScope())); } else if (DbgValueInst* OldIntrin = dyn_cast<DbgValueInst>(&OldI)) { DbgValueInst* NewIntrin = dyn_cast<DbgValueInst>(&NewI); EXPECT_TRUE(NewIntrin); - if (!OldIntrin->getDebugLoc()->getInlinedAt()) { - // Old variable must belong to the old function. - EXPECT_EQ(OldFunc->getSubprogram(), - cast<DISubprogram>(OldIntrin->getVariable()->getScope())); - // New variable must belong to the new function. - EXPECT_EQ(NewFunc->getSubprogram(), - cast<DISubprogram>(NewIntrin->getVariable()->getScope())); - } + // Old variable must belong to the old function + EXPECT_EQ(OldFunc->getSubprogram(), + cast<DISubprogram>(OldIntrin->getVariable()->getScope())); + // New variable must belong to the New function + EXPECT_EQ(NewFunc->getSubprogram(), + cast<DISubprogram>(NewIntrin->getVariable()->getScope())); } ++OldIter; @@ -570,16 +423,6 @@ protected: void SetupModule() { OldM = new Module("", C); } void CreateOldModule() { - auto *CD = OldM->getOrInsertComdat("comdat"); - CD->setSelectionKind(Comdat::ExactMatch); - - auto GV = new GlobalVariable( - *OldM, Type::getInt32Ty(C), false, GlobalValue::ExternalLinkage, - ConstantInt::get(Type::getInt32Ty(C), 1), "gv"); - GV->addMetadata(LLVMContext::MD_type, *MDNode::get(C, {})); - GV->setComdat(CD); - - DIBuilder DBuilder(*OldM); IRBuilder<> IBuilder(C); auto *FuncType = FunctionType::get(Type::getVoidTy(C), false); @@ -588,44 +431,12 @@ protected: auto *F = Function::Create(FuncType, GlobalValue::PrivateLinkage, "f", OldM); F->setPersonalityFn(PersFn); - F->setComdat(CD); - - // Create debug info - auto *File = DBuilder.createFile("filename.c", "/file/dir/"); - DITypeRefArray ParamTypes = DBuilder.getOrCreateTypeArray(None); - DISubroutineType *DFuncType = DBuilder.createSubroutineType(ParamTypes); - auto *CU = DBuilder.createCompileUnit(dwarf::DW_LANG_C99, - DBuilder.createFile("filename.c", - "/file/dir"), - "CloneModule", false, "", 0); - // Function DI - auto *Subprogram = - DBuilder.createFunction(CU, "f", "f", File, 4, DFuncType, true, true, 3, - DINode::FlagZero, false); - F->setSubprogram(Subprogram); - - // Create and assign DIGlobalVariableExpression to gv - auto GVExpression = DBuilder.createGlobalVariableExpression( - Subprogram, "gv", "gv", File, 1, DBuilder.createNullPtrType(), false); - GV->addDebugInfo(GVExpression); - - // DIGlobalVariableExpression not attached to any global variable - auto Expr = DBuilder.createExpression( - ArrayRef<uint64_t>{dwarf::DW_OP_constu, 42U, dwarf::DW_OP_stack_value}); - - DBuilder.createGlobalVariableExpression( - Subprogram, "unattached", "unattached", File, 1, - DBuilder.createNullPtrType(), false, Expr); - auto *Entry = BasicBlock::Create(C, "", F); IBuilder.SetInsertPoint(Entry); IBuilder.CreateRetVoid(); - - // Finalize the debug info - DBuilder.finalize(); } - void CreateNewModule() { NewM = llvm::CloneModule(*OldM).release(); } + void CreateNewModule() { NewM = llvm::CloneModule(OldM).release(); } LLVMContext C; Module *OldM; @@ -636,80 +447,4 @@ TEST_F(CloneModule, Verify) { EXPECT_FALSE(verifyModule(*NewM)); } -TEST_F(CloneModule, OldModuleUnchanged) { - DebugInfoFinder Finder; - Finder.processModule(*OldM); - EXPECT_EQ(1U, Finder.subprogram_count()); -} - -TEST_F(CloneModule, Subprogram) { - Function *NewF = NewM->getFunction("f"); - DISubprogram *SP = NewF->getSubprogram(); - EXPECT_TRUE(SP != nullptr); - EXPECT_EQ(SP->getName(), "f"); - EXPECT_EQ(SP->getFile()->getFilename(), "filename.c"); - EXPECT_EQ(SP->getLine(), (unsigned)4); -} - -TEST_F(CloneModule, GlobalMetadata) { - GlobalVariable *NewGV = NewM->getGlobalVariable("gv"); - EXPECT_NE(nullptr, NewGV->getMetadata(LLVMContext::MD_type)); -} - -TEST_F(CloneModule, GlobalDebugInfo) { - GlobalVariable *NewGV = NewM->getGlobalVariable("gv"); - EXPECT_TRUE(NewGV != nullptr); - - // Find debug info expression assigned to global - SmallVector<DIGlobalVariableExpression *, 1> GVs; - NewGV->getDebugInfo(GVs); - EXPECT_EQ(GVs.size(), 1U); - - DIGlobalVariableExpression *GVExpr = GVs[0]; - DIGlobalVariable *GV = GVExpr->getVariable(); - EXPECT_TRUE(GV != nullptr); - - EXPECT_EQ(GV->getName(), "gv"); - EXPECT_EQ(GV->getLine(), 1U); - - // Assert that the scope of the debug info attached to - // global variable matches the cloned function. - DISubprogram *SP = NewM->getFunction("f")->getSubprogram(); - EXPECT_TRUE(SP != nullptr); - EXPECT_EQ(GV->getScope(), SP); -} - -TEST_F(CloneModule, CompileUnit) { - // Find DICompileUnit listed in llvm.dbg.cu - auto *NMD = NewM->getNamedMetadata("llvm.dbg.cu"); - EXPECT_TRUE(NMD != nullptr); - EXPECT_EQ(NMD->getNumOperands(), 1U); - - DICompileUnit *CU = dyn_cast<llvm::DICompileUnit>(NMD->getOperand(0)); - EXPECT_TRUE(CU != nullptr); - - // Assert this CU is consistent with the cloned function debug info - DISubprogram *SP = NewM->getFunction("f")->getSubprogram(); - EXPECT_TRUE(SP != nullptr); - EXPECT_EQ(SP->getUnit(), CU); - - // Check globals listed in CU have the correct scope - DIGlobalVariableExpressionArray GlobalArray = CU->getGlobalVariables(); - EXPECT_EQ(GlobalArray.size(), 2U); - for (DIGlobalVariableExpression *GVExpr : GlobalArray) { - DIGlobalVariable *GV = GVExpr->getVariable(); - EXPECT_EQ(GV->getScope(), SP); - } -} - -TEST_F(CloneModule, Comdat) { - GlobalVariable *NewGV = NewM->getGlobalVariable("gv"); - auto *CD = NewGV->getComdat(); - ASSERT_NE(nullptr, CD); - EXPECT_EQ("comdat", CD->getName()); - EXPECT_EQ(Comdat::ExactMatch, CD->getSelectionKind()); - - Function *NewF = NewM->getFunction("f"); - EXPECT_EQ(CD, NewF->getComdat()); -} } diff --git a/gnu/llvm/unittests/Transforms/Utils/IntegerDivision.cpp b/gnu/llvm/unittests/Transforms/Utils/IntegerDivision.cpp index e337b9f547a..4cda2b4e589 100644 --- a/gnu/llvm/unittests/Transforms/Utils/IntegerDivision.cpp +++ b/gnu/llvm/unittests/Transforms/Utils/IntegerDivision.cpp @@ -21,7 +21,7 @@ namespace { TEST(IntegerDivision, SDiv) { - LLVMContext C; + LLVMContext &C(getGlobalContext()); Module M("test division", C); IRBuilder<> Builder(C); @@ -29,7 +29,7 @@ TEST(IntegerDivision, SDiv) { Function *F = Function::Create(FunctionType::get(Builder.getInt32Ty(), ArgTys, false), GlobalValue::ExternalLinkage, "F", &M); - assert(F->arg_size() == 2); + assert(F->getArgumentList().size() == 2); BasicBlock *BB = BasicBlock::Create(C, "", F); Builder.SetInsertPoint(BB); @@ -51,7 +51,7 @@ TEST(IntegerDivision, SDiv) { } TEST(IntegerDivision, UDiv) { - LLVMContext C; + LLVMContext &C(getGlobalContext()); Module M("test division", C); IRBuilder<> Builder(C); @@ -59,7 +59,7 @@ TEST(IntegerDivision, UDiv) { Function *F = Function::Create(FunctionType::get(Builder.getInt32Ty(), ArgTys, false), GlobalValue::ExternalLinkage, "F", &M); - assert(F->arg_size() == 2); + assert(F->getArgumentList().size() == 2); BasicBlock *BB = BasicBlock::Create(C, "", F); Builder.SetInsertPoint(BB); @@ -81,7 +81,7 @@ TEST(IntegerDivision, UDiv) { } TEST(IntegerDivision, SRem) { - LLVMContext C; + LLVMContext &C(getGlobalContext()); Module M("test remainder", C); IRBuilder<> Builder(C); @@ -89,7 +89,7 @@ TEST(IntegerDivision, SRem) { Function *F = Function::Create(FunctionType::get(Builder.getInt32Ty(), ArgTys, false), GlobalValue::ExternalLinkage, "F", &M); - assert(F->arg_size() == 2); + assert(F->getArgumentList().size() == 2); BasicBlock *BB = BasicBlock::Create(C, "", F); Builder.SetInsertPoint(BB); @@ -111,7 +111,7 @@ TEST(IntegerDivision, SRem) { } TEST(IntegerDivision, URem) { - LLVMContext C; + LLVMContext &C(getGlobalContext()); Module M("test remainder", C); IRBuilder<> Builder(C); @@ -119,7 +119,7 @@ TEST(IntegerDivision, URem) { Function *F = Function::Create(FunctionType::get(Builder.getInt32Ty(), ArgTys, false), GlobalValue::ExternalLinkage, "F", &M); - assert(F->arg_size() == 2); + assert(F->getArgumentList().size() == 2); BasicBlock *BB = BasicBlock::Create(C, "", F); Builder.SetInsertPoint(BB); @@ -142,7 +142,7 @@ TEST(IntegerDivision, URem) { TEST(IntegerDivision, SDiv64) { - LLVMContext C; + LLVMContext &C(getGlobalContext()); Module M("test division", C); IRBuilder<> Builder(C); @@ -150,7 +150,7 @@ TEST(IntegerDivision, SDiv64) { Function *F = Function::Create(FunctionType::get(Builder.getInt64Ty(), ArgTys, false), GlobalValue::ExternalLinkage, "F", &M); - assert(F->arg_size() == 2); + assert(F->getArgumentList().size() == 2); BasicBlock *BB = BasicBlock::Create(C, "", F); Builder.SetInsertPoint(BB); @@ -172,7 +172,7 @@ TEST(IntegerDivision, SDiv64) { } TEST(IntegerDivision, UDiv64) { - LLVMContext C; + LLVMContext &C(getGlobalContext()); Module M("test division", C); IRBuilder<> Builder(C); @@ -180,7 +180,7 @@ TEST(IntegerDivision, UDiv64) { Function *F = Function::Create(FunctionType::get(Builder.getInt64Ty(), ArgTys, false), GlobalValue::ExternalLinkage, "F", &M); - assert(F->arg_size() == 2); + assert(F->getArgumentList().size() == 2); BasicBlock *BB = BasicBlock::Create(C, "", F); Builder.SetInsertPoint(BB); @@ -202,7 +202,7 @@ TEST(IntegerDivision, UDiv64) { } TEST(IntegerDivision, SRem64) { - LLVMContext C; + LLVMContext &C(getGlobalContext()); Module M("test remainder", C); IRBuilder<> Builder(C); @@ -210,7 +210,7 @@ TEST(IntegerDivision, SRem64) { Function *F = Function::Create(FunctionType::get(Builder.getInt64Ty(), ArgTys, false), GlobalValue::ExternalLinkage, "F", &M); - assert(F->arg_size() == 2); + assert(F->getArgumentList().size() == 2); BasicBlock *BB = BasicBlock::Create(C, "", F); Builder.SetInsertPoint(BB); @@ -232,7 +232,7 @@ TEST(IntegerDivision, SRem64) { } TEST(IntegerDivision, URem64) { - LLVMContext C; + LLVMContext &C(getGlobalContext()); Module M("test remainder", C); IRBuilder<> Builder(C); @@ -240,7 +240,7 @@ TEST(IntegerDivision, URem64) { Function *F = Function::Create(FunctionType::get(Builder.getInt64Ty(), ArgTys, false), GlobalValue::ExternalLinkage, "F", &M); - assert(F->arg_size() == 2); + assert(F->getArgumentList().size() == 2); BasicBlock *BB = BasicBlock::Create(C, "", F); Builder.SetInsertPoint(BB); diff --git a/gnu/llvm/unittests/Transforms/Utils/Local.cpp b/gnu/llvm/unittests/Transforms/Utils/Local.cpp index 5850910403f..2ff56047555 100644 --- a/gnu/llvm/unittests/Transforms/Utils/Local.cpp +++ b/gnu/llvm/unittests/Transforms/Utils/Local.cpp @@ -8,21 +8,16 @@ //===----------------------------------------------------------------------===// #include "llvm/Transforms/Utils/Local.h" -#include "llvm/AsmParser/Parser.h" #include "llvm/IR/BasicBlock.h" -#include "llvm/IR/DIBuilder.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/Instructions.h" -#include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/LLVMContext.h" -#include "llvm/IR/Verifier.h" -#include "llvm/Support/SourceMgr.h" #include "gtest/gtest.h" using namespace llvm; TEST(Local, RecursivelyDeleteDeadPHINodes) { - LLVMContext C; + LLVMContext &C(getGlobalContext()); IRBuilder<> builder(C); @@ -65,7 +60,7 @@ TEST(Local, RecursivelyDeleteDeadPHINodes) { } TEST(Local, RemoveDuplicatePHINodes) { - LLVMContext C; + LLVMContext &C(getGlobalContext()); IRBuilder<> B(C); std::unique_ptr<Function> F( @@ -100,521 +95,3 @@ TEST(Local, RemoveDuplicatePHINodes) { EXPECT_TRUE(EliminateDuplicatePHINodes(BB)); EXPECT_EQ(3U, BB->size()); } - -static std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) { - SMDiagnostic Err; - std::unique_ptr<Module> Mod = parseAssemblyString(IR, Err, C); - if (!Mod) - Err.print("UtilsTests", errs()); - return Mod; -} - -TEST(Local, ReplaceDbgDeclare) { - LLVMContext C; - - // Original C source to get debug info for a local variable: - // void f() { int x; } - std::unique_ptr<Module> M = parseIR(C, - R"( - define void @f() !dbg !8 { - entry: - %x = alloca i32, align 4 - call void @llvm.dbg.declare(metadata i32* %x, metadata !11, metadata !DIExpression()), !dbg !13 - call void @llvm.dbg.declare(metadata i32* %x, metadata !11, metadata !DIExpression()), !dbg !13 - ret void, !dbg !14 - } - declare void @llvm.dbg.declare(metadata, metadata, metadata) - !llvm.dbg.cu = !{!0} - !llvm.module.flags = !{!3, !4} - !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 6.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) - !1 = !DIFile(filename: "t2.c", directory: "foo") - !2 = !{} - !3 = !{i32 2, !"Dwarf Version", i32 4} - !4 = !{i32 2, !"Debug Info Version", i32 3} - !8 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !9, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: false, unit: !0, retainedNodes: !2) - !9 = !DISubroutineType(types: !10) - !10 = !{null} - !11 = !DILocalVariable(name: "x", scope: !8, file: !1, line: 2, type: !12) - !12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) - !13 = !DILocation(line: 2, column: 7, scope: !8) - !14 = !DILocation(line: 3, column: 1, scope: !8) - )"); - auto *GV = M->getNamedValue("f"); - ASSERT_TRUE(GV); - auto *F = dyn_cast<Function>(GV); - ASSERT_TRUE(F); - Instruction *Inst = &F->front().front(); - auto *AI = dyn_cast<AllocaInst>(Inst); - ASSERT_TRUE(AI); - Inst = Inst->getNextNode()->getNextNode(); - ASSERT_TRUE(Inst); - auto *DII = dyn_cast<DbgDeclareInst>(Inst); - ASSERT_TRUE(DII); - Value *NewBase = Constant::getNullValue(Type::getInt32PtrTy(C)); - DIBuilder DIB(*M); - replaceDbgDeclare(AI, NewBase, DII, DIB, DIExpression::NoDeref, 0, - DIExpression::NoDeref); - - // There should be exactly two dbg.declares. - int Declares = 0; - for (const Instruction &I : F->front()) - if (isa<DbgDeclareInst>(I)) - Declares++; - EXPECT_EQ(2, Declares); -} - -/// Build the dominator tree for the function and run the Test. -static void runWithDomTree( - Module &M, StringRef FuncName, - function_ref<void(Function &F, DominatorTree *DT)> Test) { - auto *F = M.getFunction(FuncName); - ASSERT_NE(F, nullptr) << "Could not find " << FuncName; - // Compute the dominator tree for the function. - DominatorTree DT(*F); - Test(*F, &DT); -} - -TEST(Local, MergeBasicBlockIntoOnlyPred) { - LLVMContext C; - - std::unique_ptr<Module> M = parseIR(C, - R"( - define i32 @f(i8* %str) { - entry: - br label %bb2.i - bb2.i: ; preds = %bb4.i, %entry - br i1 false, label %bb4.i, label %base2flt.exit204 - bb4.i: ; preds = %bb2.i - br i1 false, label %base2flt.exit204, label %bb2.i - bb10.i196.bb7.i197_crit_edge: ; No predecessors! - br label %bb7.i197 - bb7.i197: ; preds = %bb10.i196.bb7.i197_crit_edge - %.reg2mem.0 = phi i32 [ %.reg2mem.0, %bb10.i196.bb7.i197_crit_edge ] - br i1 undef, label %base2flt.exit204, label %base2flt.exit204 - base2flt.exit204: ; preds = %bb7.i197, %bb7.i197, %bb2.i, %bb4.i - ret i32 0 - } - )"); - runWithDomTree( - *M, "f", [&](Function &F, DominatorTree *DT) { - for (Function::iterator I = F.begin(), E = F.end(); I != E;) { - BasicBlock *BB = &*I++; - BasicBlock *SinglePred = BB->getSinglePredecessor(); - if (!SinglePred || SinglePred == BB || BB->hasAddressTaken()) continue; - BranchInst *Term = dyn_cast<BranchInst>(SinglePred->getTerminator()); - if (Term && !Term->isConditional()) - MergeBasicBlockIntoOnlyPred(BB, DT); - } - EXPECT_TRUE(DT->verify()); - }); -} - -TEST(Local, ConstantFoldTerminator) { - LLVMContext C; - - std::unique_ptr<Module> M = parseIR(C, - R"( - define void @br_same_dest() { - entry: - br i1 false, label %bb0, label %bb0 - bb0: - ret void - } - - define void @br_different_dest() { - entry: - br i1 true, label %bb0, label %bb1 - bb0: - br label %exit - bb1: - br label %exit - exit: - ret void - } - - define void @switch_2_different_dest() { - entry: - switch i32 0, label %default [ i32 0, label %bb0 ] - default: - ret void - bb0: - ret void - } - define void @switch_2_different_dest_default() { - entry: - switch i32 1, label %default [ i32 0, label %bb0 ] - default: - ret void - bb0: - ret void - } - define void @switch_3_different_dest() { - entry: - switch i32 0, label %default [ i32 0, label %bb0 - i32 1, label %bb1 ] - default: - ret void - bb0: - ret void - bb1: - ret void - } - - define void @switch_variable_2_default_dest(i32 %arg) { - entry: - switch i32 %arg, label %default [ i32 0, label %default ] - default: - ret void - } - - define void @switch_constant_2_default_dest() { - entry: - switch i32 1, label %default [ i32 0, label %default ] - default: - ret void - } - - define void @switch_constant_3_repeated_dest() { - entry: - switch i32 0, label %default [ i32 0, label %bb0 - i32 1, label %bb0 ] - bb0: - ret void - default: - ret void - } - - define void @indirectbr() { - entry: - indirectbr i8* blockaddress(@indirectbr, %bb0), [label %bb0, label %bb1] - bb0: - ret void - bb1: - ret void - } - - define void @indirectbr_repeated() { - entry: - indirectbr i8* blockaddress(@indirectbr_repeated, %bb0), [label %bb0, label %bb0] - bb0: - ret void - } - - define void @indirectbr_unreachable() { - entry: - indirectbr i8* blockaddress(@indirectbr_unreachable, %bb0), [label %bb1] - bb0: - ret void - bb1: - ret void - } - )"); - - auto CFAllTerminators = [&](Function &F, DominatorTree *DT) { - DeferredDominance DDT(*DT); - for (Function::iterator I = F.begin(), E = F.end(); I != E;) { - BasicBlock *BB = &*I++; - ConstantFoldTerminator(BB, true, nullptr, &DDT); - } - - EXPECT_TRUE(DDT.flush().verify()); - }; - - runWithDomTree(*M, "br_same_dest", CFAllTerminators); - runWithDomTree(*M, "br_different_dest", CFAllTerminators); - runWithDomTree(*M, "switch_2_different_dest", CFAllTerminators); - runWithDomTree(*M, "switch_2_different_dest_default", CFAllTerminators); - runWithDomTree(*M, "switch_3_different_dest", CFAllTerminators); - runWithDomTree(*M, "switch_variable_2_default_dest", CFAllTerminators); - runWithDomTree(*M, "switch_constant_2_default_dest", CFAllTerminators); - runWithDomTree(*M, "switch_constant_3_repeated_dest", CFAllTerminators); - runWithDomTree(*M, "indirectbr", CFAllTerminators); - runWithDomTree(*M, "indirectbr_repeated", CFAllTerminators); - runWithDomTree(*M, "indirectbr_unreachable", CFAllTerminators); -} - -struct SalvageDebugInfoTest : ::testing::Test { - LLVMContext C; - std::unique_ptr<Module> M; - Function *F = nullptr; - - void SetUp() { - M = parseIR(C, - R"( - define void @f() !dbg !8 { - entry: - %x = add i32 0, 1 - %y = add i32 %x, 2 - call void @llvm.dbg.value(metadata i32 %x, metadata !11, metadata !DIExpression()), !dbg !13 - call void @llvm.dbg.value(metadata i32 %y, metadata !11, metadata !DIExpression()), !dbg !13 - ret void, !dbg !14 - } - declare void @llvm.dbg.value(metadata, metadata, metadata) - !llvm.dbg.cu = !{!0} - !llvm.module.flags = !{!3, !4} - !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 6.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) - !1 = !DIFile(filename: "t2.c", directory: "foo") - !2 = !{} - !3 = !{i32 2, !"Dwarf Version", i32 4} - !4 = !{i32 2, !"Debug Info Version", i32 3} - !8 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !9, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: false, unit: !0, retainedNodes: !2) - !9 = !DISubroutineType(types: !10) - !10 = !{null} - !11 = !DILocalVariable(name: "x", scope: !8, file: !1, line: 2, type: !12) - !12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) - !13 = !DILocation(line: 2, column: 7, scope: !8) - !14 = !DILocation(line: 3, column: 1, scope: !8) - )"); - - auto *GV = M->getNamedValue("f"); - ASSERT_TRUE(GV); - F = dyn_cast<Function>(GV); - ASSERT_TRUE(F); - } - - bool doesDebugValueDescribeX(const DbgValueInst &DI) { - const auto &CI = *cast<ConstantInt>(DI.getValue()); - if (CI.isZero()) - return DI.getExpression()->getElements().equals( - {dwarf::DW_OP_plus_uconst, 1, dwarf::DW_OP_stack_value}); - else if (CI.isOneValue()) - return DI.getExpression()->getElements().empty(); - return false; - } - - bool doesDebugValueDescribeY(const DbgValueInst &DI) { - const auto &CI = *cast<ConstantInt>(DI.getValue()); - if (CI.isZero()) - return DI.getExpression()->getElements().equals( - {dwarf::DW_OP_plus_uconst, 1, dwarf::DW_OP_plus_uconst, 2, - dwarf::DW_OP_stack_value}); - else if (CI.isOneValue()) - return DI.getExpression()->getElements().equals( - {dwarf::DW_OP_plus_uconst, 2, dwarf::DW_OP_stack_value}); - return false; - } - - void verifyDebugValuesAreSalvaged() { - // Check that the debug values for %x and %y are preserved. - bool FoundX = false; - bool FoundY = false; - for (const Instruction &I : F->front()) { - auto DI = dyn_cast<DbgValueInst>(&I); - if (!DI) { - // The function should only contain debug values and a terminator. - ASSERT_TRUE(isa<TerminatorInst>(&I)); - continue; - } - EXPECT_EQ(DI->getVariable()->getName(), "x"); - FoundX |= doesDebugValueDescribeX(*DI); - FoundY |= doesDebugValueDescribeY(*DI); - } - ASSERT_TRUE(FoundX); - ASSERT_TRUE(FoundY); - } -}; - -TEST_F(SalvageDebugInfoTest, RecursiveInstDeletion) { - Instruction *Inst = &F->front().front(); - Inst = Inst->getNextNode(); // Get %y = add ... - ASSERT_TRUE(Inst); - bool Deleted = RecursivelyDeleteTriviallyDeadInstructions(Inst); - ASSERT_TRUE(Deleted); - verifyDebugValuesAreSalvaged(); -} - -TEST_F(SalvageDebugInfoTest, RecursiveBlockSimplification) { - BasicBlock *BB = &F->front(); - ASSERT_TRUE(BB); - bool Deleted = SimplifyInstructionsInBlock(BB); - ASSERT_TRUE(Deleted); - verifyDebugValuesAreSalvaged(); -} - -TEST(Local, ReplaceAllDbgUsesWith) { - using namespace llvm::dwarf; - - LLVMContext Ctx; - - // Note: The datalayout simulates Darwin/x86_64. - std::unique_ptr<Module> M = parseIR(Ctx, - R"( - target datalayout = "e-m:o-i63:64-f80:128-n8:16:32:64-S128" - - declare i32 @escape(i32) - - define void @f() !dbg !6 { - entry: - %a = add i32 0, 1, !dbg !15 - call void @llvm.dbg.value(metadata i32 %a, metadata !9, metadata !DIExpression()), !dbg !15 - - %b = add i64 0, 1, !dbg !16 - call void @llvm.dbg.value(metadata i64 %b, metadata !11, metadata !DIExpression()), !dbg !16 - call void @llvm.dbg.value(metadata i64 %b, metadata !11, metadata !DIExpression(DW_OP_lit0, DW_OP_mul)), !dbg !16 - call void @llvm.dbg.value(metadata i64 %b, metadata !11, metadata !DIExpression(DW_OP_lit0, DW_OP_mul, DW_OP_stack_value)), !dbg !16 - call void @llvm.dbg.value(metadata i64 %b, metadata !11, metadata !DIExpression(DW_OP_LLVM_fragment, 0, 8)), !dbg !16 - call void @llvm.dbg.value(metadata i64 %b, metadata !11, metadata !DIExpression(DW_OP_lit0, DW_OP_mul, DW_OP_LLVM_fragment, 0, 8)), !dbg !16 - call void @llvm.dbg.value(metadata i64 %b, metadata !11, metadata !DIExpression(DW_OP_lit0, DW_OP_mul, DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 8)), !dbg !16 - - %c = inttoptr i64 0 to i64*, !dbg !17 - call void @llvm.dbg.declare(metadata i64* %c, metadata !13, metadata !DIExpression()), !dbg !17 - - %d = inttoptr i64 0 to i32*, !dbg !18 - call void @llvm.dbg.addr(metadata i32* %d, metadata !20, metadata !DIExpression()), !dbg !18 - - %e = add <2 x i16> zeroinitializer, zeroinitializer - call void @llvm.dbg.value(metadata <2 x i16> %e, metadata !14, metadata !DIExpression()), !dbg !18 - - %f = call i32 @escape(i32 0) - call void @llvm.dbg.value(metadata i32 %f, metadata !9, metadata !DIExpression()), !dbg !15 - - %barrier = call i32 @escape(i32 0) - - %g = call i32 @escape(i32 %f) - call void @llvm.dbg.value(metadata i32 %g, metadata !9, metadata !DIExpression()), !dbg !15 - - ret void, !dbg !19 - } - - declare void @llvm.dbg.addr(metadata, metadata, metadata) - declare void @llvm.dbg.declare(metadata, metadata, metadata) - declare void @llvm.dbg.value(metadata, metadata, metadata) - - !llvm.dbg.cu = !{!0} - !llvm.module.flags = !{!5} - - !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) - !1 = !DIFile(filename: "/Users/vsk/Desktop/foo.ll", directory: "/") - !2 = !{} - !5 = !{i32 2, !"Debug Info Version", i32 3} - !6 = distinct !DISubprogram(name: "f", linkageName: "f", scope: null, file: !1, line: 1, type: !7, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: true, unit: !0, retainedNodes: !8) - !7 = !DISubroutineType(types: !2) - !8 = !{!9, !11, !13, !14} - !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10) - !10 = !DIBasicType(name: "ty32", size: 32, encoding: DW_ATE_signed) - !11 = !DILocalVariable(name: "2", scope: !6, file: !1, line: 2, type: !12) - !12 = !DIBasicType(name: "ty64", size: 64, encoding: DW_ATE_signed) - !13 = !DILocalVariable(name: "3", scope: !6, file: !1, line: 3, type: !12) - !14 = !DILocalVariable(name: "4", scope: !6, file: !1, line: 4, type: !10) - !15 = !DILocation(line: 1, column: 1, scope: !6) - !16 = !DILocation(line: 2, column: 1, scope: !6) - !17 = !DILocation(line: 3, column: 1, scope: !6) - !18 = !DILocation(line: 4, column: 1, scope: !6) - !19 = !DILocation(line: 5, column: 1, scope: !6) - !20 = !DILocalVariable(name: "5", scope: !6, file: !1, line: 5, type: !10) - )"); - - bool BrokenDebugInfo = true; - verifyModule(*M, &errs(), &BrokenDebugInfo); - ASSERT_FALSE(BrokenDebugInfo); - - Function &F = *cast<Function>(M->getNamedValue("f")); - DominatorTree DT{F}; - - BasicBlock &BB = F.front(); - Instruction &A = BB.front(); - Instruction &B = *A.getNextNonDebugInstruction(); - Instruction &C = *B.getNextNonDebugInstruction(); - Instruction &D = *C.getNextNonDebugInstruction(); - Instruction &E = *D.getNextNonDebugInstruction(); - Instruction &F_ = *E.getNextNonDebugInstruction(); - Instruction &Barrier = *F_.getNextNonDebugInstruction(); - Instruction &G = *Barrier.getNextNonDebugInstruction(); - - // Simulate i32 <-> i64* conversion. Expect no updates: the datalayout says - // pointers are 64 bits, so the conversion would be lossy. - EXPECT_FALSE(replaceAllDbgUsesWith(A, C, C, DT)); - EXPECT_FALSE(replaceAllDbgUsesWith(C, A, A, DT)); - - // Simulate i32 <-> <2 x i16> conversion. This is unsupported. - EXPECT_FALSE(replaceAllDbgUsesWith(E, A, A, DT)); - EXPECT_FALSE(replaceAllDbgUsesWith(A, E, E, DT)); - - // Simulate i32* <-> i64* conversion. - EXPECT_TRUE(replaceAllDbgUsesWith(D, C, C, DT)); - - SmallVector<DbgInfoIntrinsic *, 2> CDbgVals; - findDbgUsers(CDbgVals, &C); - EXPECT_EQ(2U, CDbgVals.size()); - EXPECT_TRUE(any_of(CDbgVals, [](DbgInfoIntrinsic *DII) { - return isa<DbgAddrIntrinsic>(DII); - })); - EXPECT_TRUE(any_of(CDbgVals, [](DbgInfoIntrinsic *DII) { - return isa<DbgDeclareInst>(DII); - })); - - EXPECT_TRUE(replaceAllDbgUsesWith(C, D, D, DT)); - - SmallVector<DbgInfoIntrinsic *, 2> DDbgVals; - findDbgUsers(DDbgVals, &D); - EXPECT_EQ(2U, DDbgVals.size()); - EXPECT_TRUE(any_of(DDbgVals, [](DbgInfoIntrinsic *DII) { - return isa<DbgAddrIntrinsic>(DII); - })); - EXPECT_TRUE(any_of(DDbgVals, [](DbgInfoIntrinsic *DII) { - return isa<DbgDeclareInst>(DII); - })); - - // Introduce a use-before-def. Check that the dbg.value for %a is salvaged. - EXPECT_TRUE(replaceAllDbgUsesWith(A, F_, F_, DT)); - - auto *ADbgVal = cast<DbgValueInst>(A.getNextNode()); - EXPECT_EQ(ConstantInt::get(A.getType(), 0), ADbgVal->getVariableLocation()); - - // Introduce a use-before-def. Check that the dbg.values for %f are deleted. - EXPECT_TRUE(replaceAllDbgUsesWith(F_, G, G, DT)); - - SmallVector<DbgValueInst *, 1> FDbgVals; - findDbgValues(FDbgVals, &F); - EXPECT_EQ(0U, FDbgVals.size()); - - // Simulate i32 -> i64 conversion to test sign-extension. Here are some - // interesting cases to handle: - // 1) debug user has empty DIExpression - // 2) debug user has non-empty, non-stack-value'd DIExpression - // 3) debug user has non-empty, stack-value'd DIExpression - // 4-6) like (1-3), but with a fragment - EXPECT_TRUE(replaceAllDbgUsesWith(B, A, A, DT)); - - SmallVector<DbgValueInst *, 8> ADbgVals; - findDbgValues(ADbgVals, &A); - EXPECT_EQ(6U, ADbgVals.size()); - - // Check that %a has a dbg.value with a DIExpression matching \p Ops. - auto hasADbgVal = [&](ArrayRef<uint64_t> Ops) { - return any_of(ADbgVals, [&](DbgValueInst *DVI) { - assert(DVI->getVariable()->getName() == "2"); - return DVI->getExpression()->getElements() == Ops; - }); - }; - - // Case 1: The original expr is empty, so no deref is needed. - EXPECT_TRUE(hasADbgVal({DW_OP_dup, DW_OP_constu, 31, DW_OP_shr, DW_OP_lit0, - DW_OP_not, DW_OP_mul, DW_OP_or, DW_OP_stack_value})); - - // Case 2: Perform an address calculation with the original expr, deref it, - // then sign-extend the result. - EXPECT_TRUE(hasADbgVal({DW_OP_lit0, DW_OP_mul, DW_OP_deref, DW_OP_dup, - DW_OP_constu, 31, DW_OP_shr, DW_OP_lit0, DW_OP_not, - DW_OP_mul, DW_OP_or, DW_OP_stack_value})); - - // Case 3: Insert the sign-extension logic before the DW_OP_stack_value. - EXPECT_TRUE(hasADbgVal({DW_OP_lit0, DW_OP_mul, DW_OP_dup, DW_OP_constu, 31, - DW_OP_shr, DW_OP_lit0, DW_OP_not, DW_OP_mul, DW_OP_or, - DW_OP_stack_value})); - - // Cases 4-6: Just like cases 1-3, but preserve the fragment at the end. - EXPECT_TRUE(hasADbgVal({DW_OP_dup, DW_OP_constu, 31, DW_OP_shr, DW_OP_lit0, - DW_OP_not, DW_OP_mul, DW_OP_or, DW_OP_stack_value, - DW_OP_LLVM_fragment, 0, 8})); - EXPECT_TRUE( - hasADbgVal({DW_OP_lit0, DW_OP_mul, DW_OP_deref, DW_OP_dup, DW_OP_constu, - 31, DW_OP_shr, DW_OP_lit0, DW_OP_not, DW_OP_mul, DW_OP_or, - DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 8})); - EXPECT_TRUE(hasADbgVal({DW_OP_lit0, DW_OP_mul, DW_OP_dup, DW_OP_constu, 31, - DW_OP_shr, DW_OP_lit0, DW_OP_not, DW_OP_mul, DW_OP_or, - DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 8})); - - verifyModule(*M, &errs(), &BrokenDebugInfo); - ASSERT_FALSE(BrokenDebugInfo); -} |