Nemokake bug ing LLVM 8 nggunakake analyzer PVS-Studio

Nemokake bug ing LLVM 8 nggunakake analyzer PVS-Studio
Luwih saka rong taun kepungkur wiwit mriksa kode pungkasan proyek LLVM nggunakake analisa PVS-Studio. Priksa manawa analisa PVS-Studio isih dadi alat utama kanggo ngenali kesalahan lan kerentanan potensial. Kanggo nindakake iki, kita bakal mriksa lan nemokake kasalahan anyar ing release LLVM 8.0.0.

Artikel sing arep ditulis

Jujur, aku ora pengin nulis artikel iki. Ora menarik kanggo nulis babagan proyek sing wis dipriksa kaping pirang-pirang (1, 2, 3). Iku luwih apik kanggo nulis bab anyar, nanging aku ora duwe pilihan.

Saben-saben versi anyar LLVM dirilis utawa dianyari Analyzer Statis Clang, kita nampa pitakonan saka jinis ing ngisor iki ing mail kita:

Deleng, versi anyar Clang Static Analyzer wis sinau nemokake kesalahan anyar! Iku misale jek kula sing relevansi saka nggunakake PVS-Studio mudun. Clang nemokake luwih akeh kasalahan tinimbang sadurunge lan entuk kemampuan PVS-Studio. Apa sampeyan mikir babagan iki?

Kanggo iki aku tansah pengin mangsuli kaya:

Kita uga ora njagong! Kita wis nambah kemampuan analisa PVS-Studio kanthi signifikan. Dadi aja kuwatir, kita terus mimpin kaya sadurunge.

Sayange, iki jawaban sing ala. Ora ana buktine. Lan mulane aku nulis artikel iki saiki. Dadi, proyek LLVM wis dicenthang maneh lan macem-macem kesalahan wis ditemokake. Saiki aku bakal nduduhake sing katon menarik kanggo aku. Clang Static Analyzer ora bisa nemokake kesalahan kasebut (utawa pancen ora trep kanggo nindakake kanthi bantuan). Nanging kita bisa. Kajaba iku, aku nemokake lan nulis kabeh kesalahan kasebut ing wayah sore.

Nanging nulis artikel njupuk sawetara minggu. Aku mung ora bisa nggawa kabeh iki menyang teks :).

Miturut cara, yen sampeyan kasengsem karo teknologi apa sing digunakake ing penganalisis PVS-Studio kanggo ngenali kesalahan lan kerentanan potensial, mula aku saranake kenal karo iki. cathetan.

Diagnosa anyar lan lawas

Kaya sing wis dingerteni, udakara rong taun kepungkur proyek LLVM dicenthang maneh, lan kesalahan sing ditemokake didandani. Saiki artikel iki bakal nampilake akeh kesalahan anyar. Kenapa bug anyar ditemokake? Ana 3 alasan kanggo iki:

  1. Proyek LLVM berkembang, ngganti kode lawas lan nambah kode anyar. Alami, ana kesalahan anyar ing kode sing diowahi lan ditulis. Iki jelas nuduhake yen analisis statis kudu digunakake kanthi rutin, lan ora sok-sok. Artikel kita nuduhake kemampuan analisa PVS-Studio, nanging iki ora ana hubungane karo nambah kualitas kode lan nyuda biaya ndandani kesalahan. Gunakake analisa kode statis kanthi rutin!
  2. Kita ngrampungake lan nambah diagnostik sing wis ana. Mulane, analisa bisa ngenali kasalahan sing ora diweruhi nalika scan sadurunge.
  3. Diagnosa anyar wis muncul ing PVS-Studio sing ora ana 2 taun kepungkur. Aku mutusaké kanggo nyorot ing bagean kapisah kanggo cetha nuduhake pangembangan PVS-Studio.

Cacat sing diidentifikasi kanthi diagnostik sing ana 2 taun kepungkur

Fragmen N1: Salin-Tempel

static bool ShouldUpgradeX86Intrinsic(Function *F, StringRef Name) {
  if (Name == "addcarryx.u32" || // Added in 8.0
    ....
    Name == "avx512.mask.cvtps2pd.128" || // Added in 7.0
    Name == "avx512.mask.cvtps2pd.256" || // Added in 7.0
    Name == "avx512.cvtusi2sd" || // Added in 7.0
    Name.startswith("avx512.mask.permvar.") || // Added in 7.0     // <=
    Name.startswith("avx512.mask.permvar.") || // Added in 7.0     // <=
    Name == "sse2.pmulu.dq" || // Added in 7.0
    Name == "sse41.pmuldq" || // Added in 7.0
    Name == "avx2.pmulu.dq" || // Added in 7.0
  ....
}

PVS-Studio warning: V501 [CWE-570] Ana sub-ekspresi sing padha 'Name.startswith("avx512.mask.permvar.")' ing sisih kiwa lan ing sisih tengen '||' operator. AutoUpgrade.cpp 73

Dipriksa kaping pindho yen jeneng kasebut diwiwiti kanthi substring "avx512.mask.permvar.". Ing mriksa kapindho, padha temenan wanted kanggo nulis liyane, nanging lali kanggo mbenerake teks salinan.

Fragmen N2: Typo

enum CXNameRefFlags {
  CXNameRange_WantQualifier = 0x1,
  CXNameRange_WantTemplateArgs = 0x2,
  CXNameRange_WantSinglePiece = 0x4
};

void AnnotateTokensWorker::HandlePostPonedChildCursor(
    CXCursor Cursor, unsigned StartTokenIndex) {
  const auto flags = CXNameRange_WantQualifier | CXNameRange_WantQualifier;
  ....
}

Warning PVS-Studio: V501 Ana sub-ekspresi sing padha 'CXNameRange_WantQualifier' ing sisih kiwa lan tengen '|' operator. CIindex.cpp 7245

Amarga kesalahan ketik, konstanta jeneng sing padha digunakake kaping pindho CXNameRange_WantQualifier.

Fragmen N3: Kebingungan karo precedence operator

int PPCTTIImpl::getVectorInstrCost(unsigned Opcode, Type *Val, unsigned Index) {
  ....
  if (ISD == ISD::EXTRACT_VECTOR_ELT && Index == ST->isLittleEndian() ? 1 : 0)
    return 0;
  ....
}

PVS-Studio warning: V502 [CWE-783] Mbok operator '?:' dianggo ing cara sing beda saka samesthine. Operator '?:' nduweni prioritas luwih murah tinimbang operator '=='. PPCTargetTransformInfo.cpp 404

Miturut pendapatku, iki minangka kesalahan sing apik banget. Ya, aku ngerti aku duwe gagasan aneh babagan kaendahan :).

Saiki, miturut prioritas operator, ekspresi kasebut dievaluasi kaya ing ngisor iki:

(ISD == ISD::EXTRACT_VECTOR_ELT && (Index == ST->isLittleEndian())) ? 1 : 0

Saka sudut pandang praktis, kondisi kasebut ora ana gunane, amarga bisa dikurangi dadi:

(ISD == ISD::EXTRACT_VECTOR_ELT && Index == ST->isLittleEndian())

Iki minangka kesalahan sing jelas. Paling kamungkinan, dheweke pengin mbandhingake 0/1 karo variabel Index. Kanggo ndandani kode sampeyan kudu nambah kurung ing operator ternary:

if (ISD == ISD::EXTRACT_VECTOR_ELT && Index == (ST->isLittleEndian() ? 1 : 0))

Miturut cara, operator ternary banget mbebayani lan provokes kesalahan logis. Ati-ati banget lan aja srakah nganggo tanda kurung. Aku nyawang topik iki kanthi luwih rinci kene, ing bab "Ati-ati saka ?: Operator lan Lampirake ing kurung."

Fragmen N4, N5: Null pointer

Init *TGParser::ParseValue(Record *CurRec, RecTy *ItemType, IDParseMode Mode) {
  ....
  TypedInit *LHS = dyn_cast<TypedInit>(Result);
  ....
  LHS = dyn_cast<TypedInit>(
    UnOpInit::get(UnOpInit::CAST, LHS, StringRecTy::get())
      ->Fold(CurRec));
  if (!LHS) {
    Error(PasteLoc, Twine("can't cast '") + LHS->getAsString() +
                    "' to string");
    return nullptr;
  }
  ....
}

PVS-Studio warning: V522 [CWE-476] Dereferencing saka null pointer 'LHS' bisa uga dumadi. TGParser.cpp 2152

Yen pitunjuk LHS iku null, bebaya kudu ditanggepi. Nanging, tinimbang, pointer null sing padha iki bakal dibatalake: LHS->getAsString().

Iki minangka kahanan sing khas nalika kesalahan didhelikake ing panangan kesalahan, amarga ora ana sing nyoba. Analisa statis mriksa kabeh kode sing bisa digayuh, sanajan asring digunakake. Iki minangka conto sing apik banget babagan analisis statis nglengkapi teknik uji coba lan proteksi kesalahan liyane.

Kesalahan penanganan pointer sing padha RHS diijini ing kode ing ngisor iki: V522 [CWE-476] Dereferencing saka null pitunjuk 'RHS' bisa njupuk Panggonan. TGParser.cpp 2186

Fragmen N6: Nggunakake pointer sawise obah

static Expected<bool>
ExtractBlocks(....)
{
  ....
  std::unique_ptr<Module> ProgClone = CloneModule(BD.getProgram(), VMap);
  ....
  BD.setNewProgram(std::move(ProgClone));                                // <=
  MiscompiledFunctions.clear();

  for (unsigned i = 0, e = MisCompFunctions.size(); i != e; ++i) {
    Function *NewF = ProgClone->getFunction(MisCompFunctions[i].first);  // <=
    assert(NewF && "Function not found??");
    MiscompiledFunctions.push_back(NewF);
  }
  ....
}

PVS-Studio Warning: V522 [CWE-476] Dereferencing saka null pointer 'ProgClone' bisa uga dumadi. Salah kompilasi.cpp 601

Ing wiwitan pointer pinter ProgClone mandheg duwe obyek kasebut:

BD.setNewProgram(std::move(ProgClone));

Nyatane, saiki ProgClone punika null pointer. Mulane, dereferensi null pointer kudu kedadeyan ing ngisor iki:

Function *NewF = ProgClone->getFunction(MisCompFunctions[i].first);

Nanging, ing kasunyatan, iki ora bakal kelakon! Elinga yen loop ora bener dieksekusi.

Ing wiwitan wadhah Fungsi miscompiled diresiki:

MiscompiledFunctions.clear();

Sabanjure, ukuran wadhah iki digunakake ing kondisi loop:

for (unsigned i = 0, e = MisCompFunctions.size(); i != e; ++i) {

Iku gampang kanggo ndeleng sing daur ulang ora miwiti. Aku iki uga bug lan kode kudu ditulis beda.

Iku misale jek sing kita wis pinanggih sing podo misuwur saka kasalahan! Salah siji topeng liyane :).

Fragmen N7: Nggunakake pointer sawise obah

static Expected<bool> TestOptimizer(BugDriver &BD, std::unique_ptr<Module> Test,
                                    std::unique_ptr<Module> Safe) {
  outs() << "  Optimizing functions being tested: ";
  std::unique_ptr<Module> Optimized =
      BD.runPassesOn(Test.get(), BD.getPassesToRun());
  if (!Optimized) {
    errs() << " Error running this sequence of passes"
           << " on the input program!n";
    BD.setNewProgram(std::move(Test));                       // <=
    BD.EmitProgressBitcode(*Test, "pass-error", false);      // <=
    if (Error E = BD.debugOptimizerCrash())
      return std::move(E);
    return false;
  }
  ....
}

PVS-Studio warning: V522 [CWE-476] Dereferencing saka null pointer 'Test' bisa njupuk Panggonan. Salah kompilasi.cpp 709

Kahanan sing padha maneh. Kaping pisanan, isi obyek kasebut dipindhah, banjur digunakake kaya-kaya ora ana kedadeyan. Aku ndeleng kahanan iki luwih asring ing kode program sawise semantik gerakan muncul ing C ++. Iki sebabe aku seneng basa C++! Ana liyane lan liyane cara anyar kanggo njupuk sikil dhewe mati. Analisa PVS-Studio mesthi duwe karya :).

Fragmen N8: Null pointer

void FunctionDumper::dump(const PDBSymbolTypeFunctionArg &Symbol) {
  uint32_t TypeId = Symbol.getTypeId();
  auto Type = Symbol.getSession().getSymbolById(TypeId);
  if (Type)
    Printer << "<unknown-type>";
  else
    Type->dump(*this);
}

PVS-Studio warning: V522 [CWE-476] Dereferencing saka null pointer 'Tipe' bisa njupuk Panggonan. PrettyFunctionDumper.cpp 233

Saliyane panangan kesalahan, debugging fungsi printout biasane ora dites. Kita duwe kasus kaya ngono sadurunge. Fungsi kasebut nunggu pangguna, sing, tinimbang ngrampungake masalahe, bakal dipeksa kanggo ndandani.

Bener:

if (Type)
  Type->dump(*this);
else
  Printer << "<unknown-type>";

Fragmen N9: Null pointer

void SearchableTableEmitter::collectTableEntries(
    GenericTable &Table, const std::vector<Record *> &Items) {
  ....
  RecTy *Ty = resolveTypes(Field.RecType, TI->getType());
  if (!Ty)                                                              // <=
    PrintFatalError(Twine("Field '") + Field.Name + "' of table '" +
                    Table.Name + "' has incompatible type: " +
                    Ty->getAsString() + " vs. " +                       // <=
                    TI->getType()->getAsString());
   ....
}

PVS-Studio warning: V522 [CWE-476] Dereferencing saka null pointer 'Ty' bisa njupuk Panggonan. SearchableTableEmitter.cpp 614

Aku kabeh wis jelas lan ora mbutuhake panjelasan.

Fragmen N10: Typo

bool FormatTokenLexer::tryMergeCSharpNullConditionals() {
  ....
  auto &Identifier = *(Tokens.end() - 2);
  auto &Question = *(Tokens.end() - 1);
  ....
  Identifier->ColumnWidth += Question->ColumnWidth;
  Identifier->Type = Identifier->Type;                    // <=
  Tokens.erase(Tokens.end() - 1);
  return true;
}

PVS-Studio warning: V570 Variabel 'Identifier-> Type' ditugasake dhewe. FormatTokenLexer.cpp 249

Ora ana gunane nemtokake variabel kanggo awake dhewe. Paling kamungkinan, dheweke pengin nulis:

Identifier->Type = Question->Type;

Fragmen N11: Putus curiga

void SystemZOperand::print(raw_ostream &OS) const {
  switch (Kind) {
    break;
  case KindToken:
    OS << "Token:" << getToken();
    break;
  case KindReg:
    OS << "Reg:" << SystemZInstPrinter::getRegisterName(getReg());
    break;
  ....
}

PVS-Studio warning: V622 [CWE-478] Coba mriksa statement 'switch'. Bisa uga operator 'kasus' pisanan ilang. SystemZAsmParser.cpp 652

Ana operator banget curiga ing wiwitan break. Apa sampeyan lali nulis liyane ing kene?

Fragmen N12: Priksa pointer sawise dereferencing

InlineCost AMDGPUInliner::getInlineCost(CallSite CS) {
  Function *Callee = CS.getCalledFunction();
  Function *Caller = CS.getCaller();
  TargetTransformInfo &TTI = TTIWP->getTTI(*Callee);

  if (!Callee || Callee->isDeclaration())
    return llvm::InlineCost::getNever("undefined callee");
  ....
}

PVS-Studio warning: V595 [CWE-476] Pointer 'Callee' digunakake sadurunge diverifikasi marang nullptr. Priksa baris: 172, 174. AMDGPUInline.cpp 172

Pointer Callee ing wiwitan dereferenced ing wektu fungsi disebut njalukTTI.

Banjur dadi metu sing pointer iki kudu dicenthang kanggo podo nullptr:

if (!Callee || Callee->isDeclaration())

Nanging wis telat…

Fragmen N13 - N...: Priksa pointer sawise dereferencing

Kahanan sing dibahas ing fragmen kode sadurunge ora unik. Iku katon ing kene:

static Value *optimizeDoubleFP(CallInst *CI, IRBuilder<> &B,
                               bool isBinary, bool isPrecise = false) {
  ....
  Function *CalleeFn = CI->getCalledFunction();
  StringRef CalleeNm = CalleeFn->getName();                 // <=
  AttributeList CalleeAt = CalleeFn->getAttributes();
  if (CalleeFn && !CalleeFn->isIntrinsic()) {               // <=
  ....
}

PVS-Studio warning: V595 [CWE-476] Pointer 'CalleeFn' digunakake sadurunge diverifikasi marang nullptr. Priksa baris: 1079, 1081. SimplifyLibCalls.cpp 1079

Lan ing kene:

void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
                            const Decl *Tmpl, Decl *New,
                            LateInstantiatedAttrVec *LateAttrs,
                            LocalInstantiationScope *OuterMostScope) {
  ....
  NamedDecl *ND = dyn_cast<NamedDecl>(New);
  CXXRecordDecl *ThisContext =
    dyn_cast_or_null<CXXRecordDecl>(ND->getDeclContext());         // <=
  CXXThisScopeRAII ThisScope(*this, ThisContext, Qualifiers(),
                             ND && ND->isCXXInstanceMember());     // <=
  ....
}

PVS-Studio warning: V595 [CWE-476] Pointer 'ND' digunakake sadurunge diverifikasi marang nullptr. Priksa baris: 532, 534. SemaTemplateInstantiateDecl.cpp 532

Lan ing kene:

  • V595 [CWE-476] Pointer 'U' digunakake sadurunge diverifikasi marang nullptr. Priksa baris: 404, 407. DWARFormValue.cpp 404
  • V595 [CWE-476] Pointer 'ND' digunakake sadurunge diverifikasi marang nullptr. Priksa baris: 2149, 2151. SemaTemplateInstantiate.cpp 2149

Banjur aku dadi ora kasengsem sinau babagan peringatan kanthi nomer V595. Dadi aku ora ngerti yen ana kesalahan liyane sing padha kajaba sing kadhaptar ing kene. Paling kamungkinan ana.

Fragmen N17, N18: Shift curiga

static inline bool processLogicalImmediate(uint64_t Imm, unsigned RegSize,
                                           uint64_t &Encoding) {
  ....
  unsigned Size = RegSize;
  ....
  uint64_t NImms = ~(Size-1) << 1;
  ....
}

PVS-Studio warning: V629 [CWE-190] Coba priksa ekspresi '~(Ukuran - 1) << 1'. Pergeseran bit saka nilai 32-bit kanthi ekspansi sabanjure menyang jinis 64-bit. AArch64AddressingModes.h 260

Bisa uga dudu bug lan kode kasebut bisa digunakake kanthi bener. Nanging iki jelas papan sing curiga lan kudu dipriksa.

Ayo dadi ngomong variabel Size witjaksono kanggo 16, lan banjur penulis kode ngrancang kanggo njaluk iku ing variabel NImms regane:

1111111111111111111111111111111111111111111111111111111111100000

Nanging, ing kasunyatan, asil bakal:

0000000000000000000000000000000011111111111111111111111111100000

Kasunyatane, kabeh kalkulasi ditindakake nggunakake jinis 32-bit unsigned. Lan mung banjur, jinis unsigned 32-bit iki bakal ditambahi implisit kanggo uint64_t. Ing kasus iki, bit sing paling penting bakal dadi nol.

Sampeyan bisa ndandani kahanan kaya iki:

uint64_t NImms = ~static_cast<uint64_t>(Size-1) << 1;

Kahanan sing padha: V629 [CWE-190] Coba mriksa ekspresi 'Immr << 6'. Pergeseran bit saka nilai 32-bit kanthi ekspansi sabanjure menyang jinis 64-bit. AArch64AddressingModes.h 269

Fragmen N19: Kata kunci sing ilang liya?

void AMDGPUAsmParser::cvtDPP(MCInst &Inst, const OperandVector &Operands) {
  ....
  if (Op.isReg() && Op.Reg.RegNo == AMDGPU::VCC) {
    // VOP2b (v_add_u32, v_sub_u32 ...) dpp use "vcc" token.
    // Skip it.
    continue;
  } if (isRegOrImmWithInputMods(Desc, Inst.getNumOperands())) {    // <=
    Op.addRegWithFPInputModsOperands(Inst, 2);
  } else if (Op.isDPPCtrl()) {
    Op.addImmOperands(Inst, 1);
  } else if (Op.isImm()) {
    // Handle optional arguments
    OptionalIdx[Op.getImmTy()] = I;
  } else {
    llvm_unreachable("Invalid operand type");
  }
  ....
}

PVS-Studio warning: V646 [CWE-670] Coba mriksa logika aplikasi. Bisa uga tembung kunci 'liyane' ora ana. AMDGPUAsmParser.cpp 5655

Ora ana kesalahan ing kene. Wiwit banjur-blok saka pisanan if mungkasi karo terus, banjur ora masalah, ana tembung kunci liya utawa ora. Salah siji cara kode bakal bisa digunakake padha. Isih kantun liya ndadekake kode luwih cetha lan mbebayani. Yen ing tembe terus ilang, kode bakal miwiti bisa rampung beda. Ing mratelakake panemume iku luwih apik kanggo nambah liya.

Fragmen N20: Sekawan typo saka jinis sing padha

LLVM_DUMP_METHOD void Symbol::dump(raw_ostream &OS) const {
  std::string Result;
  if (isUndefined())
    Result += "(undef) ";
  if (isWeakDefined())
    Result += "(weak-def) ";
  if (isWeakReferenced())
    Result += "(weak-ref) ";
  if (isThreadLocalValue())
    Result += "(tlv) ";
  switch (Kind) {
  case SymbolKind::GlobalSymbol:
    Result + Name.str();                        // <=
    break;
  case SymbolKind::ObjectiveCClass:
    Result + "(ObjC Class) " + Name.str();      // <=
    break;
  case SymbolKind::ObjectiveCClassEHType:
    Result + "(ObjC Class EH) " + Name.str();   // <=
    break;
  case SymbolKind::ObjectiveCInstanceVariable:
    Result + "(ObjC IVar) " + Name.str();       // <=
    break;
  }
  OS << Result;
}

PVS-Studio bebaya:

  • V655 [CWE-480] Senar padha concatenated nanging ora digunakake. Coba mriksa ekspresi 'Hasil + Name.str()'. Simbol.cpp 32
  • V655 [CWE-480] Senar padha concatenated nanging ora digunakake. Coba mriksa ekspresi 'Hasil + "(Kelas ObjC)" + Name.str (). Simbol.cpp 35
  • V655 [CWE-480] Senar padha concatenated nanging ora digunakake. Coba mriksa ekspresi 'Asil + "(ObjC Class EH) " + Name.str()'. Simbol.cpp 38
  • V655 [CWE-480] Senar padha concatenated nanging ora digunakake. Coba mriksa ekspresi 'Asil + "(ObjC IVar)" + Name.str()'. Simbol.cpp 41

Ora sengaja, operator + digunakake tinimbang operator +=. Akibaté, desain sing ora ana makna.

Fragmen N21: Prilaku sing ora ditemtokake

static void getReqFeatures(std::map<StringRef, int> &FeaturesMap,
                           const std::vector<Record *> &ReqFeatures) {
  for (auto &R : ReqFeatures) {
    StringRef AsmCondString = R->getValueAsString("AssemblerCondString");

    SmallVector<StringRef, 4> Ops;
    SplitString(AsmCondString, Ops, ",");
    assert(!Ops.empty() && "AssemblerCondString cannot be empty");

    for (auto &Op : Ops) {
      assert(!Op.empty() && "Empty operator");
      if (FeaturesMap.find(Op) == FeaturesMap.end())
        FeaturesMap[Op] = FeaturesMap.size();
    }
  }
}

Coba golek dhewe kode mbebayani. Lan iki minangka gambar kanggo ngganggu perhatian supaya ora langsung ndeleng jawaban:

Nemokake bug ing LLVM 8 nggunakake analyzer PVS-Studio

PVS-Studio warning: V708 [CWE-758] construction mbebayani digunakake: 'FeaturesMap[Op] = FeaturesMap.size () ', ngendi 'FeaturesMap' iku kelas 'peta'. Iki bisa nyebabake prilaku sing ora ditemtokake. RISCVCompressInstEmitter.cpp 490

Garis masalah:

FeaturesMap[Op] = FeaturesMap.size();

Yen unsur Op ora ditemokake, banjur unsur anyar digawe ing peta lan nomer unsur ing peta iki ditulis ana. Iku mung dingerteni apa fungsi bakal disebut ukuran sadurunge utawa sawise nambah unsur anyar.

Fragmen N22-N24: Tugas bola-bali

Error MachOObjectFile::checkSymbolTable() const {
  ....
  } else {
    MachO::nlist STE = getSymbolTableEntry(SymDRI);
    NType = STE.n_type;                              // <=
    NType = STE.n_type;                              // <=
    NSect = STE.n_sect;
    NDesc = STE.n_desc;
    NStrx = STE.n_strx;
    NValue = STE.n_value;
  }
  ....
}

PVS-Studio warning: V519 [CWE-563] Variabel 'NType' diwenehi nilai kaping pindho kanthi berturut-turut. Mbok menawa iki salah. Priksa baris: 1663, 1664. MachOObjectFile.cpp 1664

Aku ora mikir ana kesalahan nyata ing kene. Mung tugas bola-bali sing ora perlu. Nanging isih blunder.

Semono uga:

  • V519 [CWE-563] Variabel 'B.NDesc' diwenehi nilai kaping pindho kanthi berturut-turut. Mbok menawa iki salah. Priksa baris: 1488, 1489. llvm-nm.cpp 1489
  • V519 [CWE-563] Variabel kasebut diwenehi nilai kaping pindho kanthi berturut-turut. Mbok menawa iki salah. Priksa baris: 59, 61. coff2yaml.cpp 61

Fragmen N25-N27: Reassignments liyane

Saiki ayo goleki versi reassignment sing rada beda.

bool Vectorizer::vectorizeLoadChain(
    ArrayRef<Instruction *> Chain,
    SmallPtrSet<Instruction *, 16> *InstructionsProcessed) {
  ....
  unsigned Alignment = getAlignment(L0);
  ....
  unsigned NewAlign = getOrEnforceKnownAlignment(L0->getPointerOperand(),
                                                 StackAdjustedAlignment,
                                                 DL, L0, nullptr, &DT);
  if (NewAlign != 0)
    Alignment = NewAlign;
  Alignment = NewAlign;
  ....
}

PVS-Studio warning: V519 [CWE-563] Variabel 'Alignment' diwenehi nilai kaping pindho kanthi berturut-turut. Mbok menawa iki salah. Priksa baris: 1158, 1160. LoadStoreVectorizer.cpp 1160

Iki kode aneh banget sing ketoke ngandhut kesalahan logis. Ing wiwitan, variabel Alignment nilai diutus gumantung ing kondisi. Banjur tugas kasebut ditindakake maneh, nanging saiki tanpa mriksa.

Kahanan sing padha bisa dideleng ing kene:

  • V519 [CWE-563] Variabel 'Efek' diwenehi nilai kaping pindho kanthi berturut-turut. Mbok menawa iki salah. Priksa baris: 152, 165. WebAssemblyRegStackify.cpp 165
  • V519 [CWE-563] Variabel 'ExpectNoDerefChunk' diwenehi nilai kaping pindho kanthi berturut-turut. Mbok menawa iki salah. Priksa baris: 4970, 4973. SemaType.cpp 4973

Fragmen N28: Tansah kahanan bener

static int readPrefixes(struct InternalInstruction* insn) {
  ....
  uint8_t byte = 0;
  uint8_t nextByte;
  ....
  if (byte == 0xf3 && (nextByte == 0x88 || nextByte == 0x89 ||
                       nextByte == 0xc6 || nextByte == 0xc7)) {
    insn->xAcquireRelease = true;
    if (nextByte != 0x90) // PAUSE instruction support             // <=
      break;
  }
  ....
}

PVS-Studio warning: V547 [CWE-571] Ekspresi 'nextByte != 0x90' mesthi bener. X86DisassemblerDecoder.cpp 379

Priksa ora ana gunane. Variabel sabanjureByte tansah ora padha karo regane 0x90, kang nderek saka mriksa sadurungé. Iki minangka sawetara kesalahan logis.

Fragmen N29 - N...: Kahanan sing tansah bener / salah

Analisa ngetokake akeh bebaya yen kabeh kondisi (V547) utawa bagéan saka (V560) tansah bener utawa salah. Asring iki dudu kesalahan nyata, nanging mung kode sing ora apik, asil ekspansi makro, lan liya-liyane. Nanging, ana gunane kanggo ndeleng kabeh bebaya iki, amarga kesalahan logis asli kedadeyan saka wektu kanggo wektu. Contone, bagean kode iki curiga:

static DecodeStatus DecodeGPRPairRegisterClass(MCInst &Inst, unsigned RegNo,
                                   uint64_t Address, const void *Decoder) {
  DecodeStatus S = MCDisassembler::Success;

  if (RegNo > 13)
    return MCDisassembler::Fail;

  if ((RegNo & 1) || RegNo == 0xe)
     S = MCDisassembler::SoftFail;
  ....
}

PVS-Studio warning: V560 [CWE-570] Bagéyan saka ekspresi kondisional tansah palsu: RegNo == 0xe. ARMDisassembler.cpp 939

Konstanta 0xE yaiku nilai 14 ing desimal. Ujian RegNo == 0xe ora masuk akal amarga yen Nomer Reg > 13, banjur fungsi bakal ngrampungake eksekusi.

Ana akeh bebaya liyane karo ID V547 lan V560, nanging minangka karo V595, Aku ora kasengsem sinau bebaya iki. Iku wis cetha yen aku wis cukup materi kanggo nulis artikel :). Mulane, iku ora dingerteni carane akeh kasalahan saka jinis iki bisa dikenali ing LLVM nggunakake PVS-Studio.

Aku bakal menehi conto kenapa nyinaoni pemicu kasebut mboseni. Analisa pancen bener nerbitake bebaya kanggo kode ing ngisor iki. Nanging iki ora salah.

bool UnwrappedLineParser::parseBracedList(bool ContinueOnSemicolons,
                                          tok::TokenKind ClosingBraceKind) {
  bool HasError = false;
  ....
  HasError = true;
  if (!ContinueOnSemicolons)
    return !HasError;
  ....
}

PVS-Studio Warning: V547 [CWE-570] Expression '!HasError' tansah palsu. UnwrappedLineParser.cpp 1635

Fragmen N30: ​​bali curiga

static bool
isImplicitlyDef(MachineRegisterInfo &MRI, unsigned Reg) {
  for (MachineRegisterInfo::def_instr_iterator It = MRI.def_instr_begin(Reg),
      E = MRI.def_instr_end(); It != E; ++It) {
    return (*It).isImplicitDef();
  }
  ....
}

PVS-Studio warning: V612 [CWE-670] 'Bali' tanpa syarat ing daur ulang. R600OptimizeVectorRegisters.cpp 63

Iki salah siji kesalahan utawa technique tartamtu sing dimaksudaké kanggo nerangake soko kanggo programer maca kode. Desain iki ora nerangake apa-apa kanggo kula lan katon banget curiga. Luwih becik ora nulis kaya ngono :).

kesel? Banjur wektu kanggo nggawe teh utawa kopi.

Nemokake bug ing LLVM 8 nggunakake analyzer PVS-Studio

Cacat sing diidentifikasi kanthi diagnostik anyar

Aku 30 aktifitas diagnostik lawas cukup. Saiki ayo ndeleng apa sing menarik sing bisa ditemokake karo diagnosa anyar sing muncul ing penganalisis sadurunge mriksa. Secara total, 66 diagnostik tujuan umum ditambahake ing penganalisis C++ sajrone wektu kasebut.

Fragmen N31: Kode ora bisa digayuh

Error CtorDtorRunner::run() {
  ....
  if (auto CtorDtorMap =
          ES.lookup(JITDylibSearchList({{&JD, true}}), std::move(Names),
                    NoDependenciesToRegister, true))
  {
    ....
    return Error::success();
  } else
    return CtorDtorMap.takeError();

  CtorDtorsByPriority.clear();

  return Error::success();
}

PVS-Studio warning: V779 [CWE-561] Kode sing ora bisa digayuh dideteksi. Bisa uga ana kesalahan. ExecutionUtils.cpp 146

Nalika sampeyan bisa ndeleng, loro cabang saka operator if dipungkasi karo telpon menyang operator bali. Patut, wadhah CtorDtorsByPriority ora bakal diresiki.

Fragmen N32: Kode ora bisa digayuh

bool LLParser::ParseSummaryEntry() {
  ....
  switch (Lex.getKind()) {
  case lltok::kw_gv:
    return ParseGVEntry(SummaryID);
  case lltok::kw_module:
    return ParseModuleEntry(SummaryID);
  case lltok::kw_typeid:
    return ParseTypeIdEntry(SummaryID);                        // <=
    break;                                                     // <=
  default:
    return Error(Lex.getLoc(), "unexpected summary kind");
  }
  Lex.setIgnoreColonInIdentifiers(false);                      // <=
  return false;
}

PVS-Studio warning: V779 [CWE-561] kode unreachable dideteksi. Bisa uga ana kesalahan. LLParser.cpp 835

Kahanan sing menarik. Ayo ndeleng panggonan iki dhisik:

return ParseTypeIdEntry(SummaryID);
break;

Sepisanan, kayane ora ana kesalahan ing kene. Iku katon kaya operator break ana tambahan ing kene, lan sampeyan mung bisa mbusak. Nanging, ora kabeh supaya prasaja.

Analisa nerbitake bebaya ing baris:

Lex.setIgnoreColonInIdentifiers(false);
return false;

Lan pancen, kode iki ora bisa digayuh. Kabeh kasus ing ngalih rampung karo telpon saka operator bali. Lan saiki ora duwe akal dhewe break ora katon mbebayani banget! Mbok siji saka cabang kudu mungkasi karo break, ora ing bali?

Fragmen N33: Reset acak saka bit dhuwur

unsigned getStubAlignment() override {
  if (Arch == Triple::systemz)
    return 8;
  else
    return 1;
}

Expected<unsigned>
RuntimeDyldImpl::emitSection(const ObjectFile &Obj,
                             const SectionRef &Section,
                             bool IsCode) {
  ....
  uint64_t DataSize = Section.getSize();
  ....
  if (StubBufSize > 0)
    DataSize &= ~(getStubAlignment() - 1);
  ....
}

PVS-Studio warning: V784 Ukuran topeng bit kurang saka ukuran operan pisanan. Iki bakal nyebabake mundhut bit sing luwih dhuwur. RuntimeDyld.cpp 815

Wigati dimangerteni yen fungsi kasebut getStubAlignment jinis bali ditandatangani. Ayo ngetung nilai ekspresi kasebut, kanthi nganggep yen fungsi kasebut ngasilake nilai 8:

~(getStubAlignment() - 1)

~(8u-1)

0xFFFFFFFF8u

Saiki sok dong mirsani sing variabel Ukuran Data nduweni jinis unsigned 64-bit. Pranyata nalika nindakake operasi DataSize & 0xFFFFFFF8u, kabeh telung puluh loro bit urutan dhuwur bakal direset menyang nol. Paling kamungkinan, iki ora dikarepake programmer. Aku curiga yen dheweke pengin ngetung: DataSize & 0xFFFFFFFFFFFFFFFF8u.

Kanggo ndandani kesalahan, sampeyan kudu nulis iki:

DataSize &= ~(static_cast<uint64_t>(getStubAlignment()) - 1);

Utawa:

DataSize &= ~(getStubAlignment() - 1ULL);

Fragmen N34: Gagal jinis eksplisit cast

template <typename T>
void scaleShuffleMask(int Scale, ArrayRef<T> Mask,
                      SmallVectorImpl<T> &ScaledMask) {
  assert(0 < Scale && "Unexpected scaling factor");
  int NumElts = Mask.size();
  ScaledMask.assign(static_cast<size_t>(NumElts * Scale), -1);
  ....
}

PVS-Studio warning: V1028 [CWE-190] Kemungkinan kebanjiran. Coba casting operands saka operator 'NumElts * Skala' kanggo jinis 'size_t', ora asil. X86ISelLowering.h 1577

Casting jinis eksplisit digunakake kanggo ngindhari kebanjiran nalika multiply jinis variabel int. Nanging, casting jinis eksplisit ing kene ora nglindhungi saka kebanjiran. Pisanan, variabel bakal dikalikan, lan mung asil 32-bit saka perkalian bakal ditambahi dadi jinis. ukuran_t.

Fragmen N35: Gagal Nyalin-Tempel

Instruction *InstCombiner::visitFCmpInst(FCmpInst &I) {
  ....
  if (!match(Op0, m_PosZeroFP()) && isKnownNeverNaN(Op0, &TLI)) {
    I.setOperand(0, ConstantFP::getNullValue(Op0->getType()));
    return &I;
  }
  if (!match(Op1, m_PosZeroFP()) && isKnownNeverNaN(Op1, &TLI)) {
    I.setOperand(1, ConstantFP::getNullValue(Op0->getType()));        // <=
    return &I;
  }
  ....
}

V778 [CWE-682] Loro pecahan kode padha ditemokaké. Mbok menawa iki salah ketik lan variabel 'Op1' kudu digunakake tinimbang 'Op0'. InstCombineCompares.cpp 5507

Diagnosa menarik anyar iki ngenali kahanan ing ngendi potongan kode wis disalin lan sawetara jeneng ing iku wis wiwit diganti, nanging ing sak panggonan padha ora didandani.

Wigati dimangerteni menawa ing blok kapindho padha diganti Op0 ing Op1. Nanging ing sak panggonan padha ora ndandani. Paling kamungkinan, kudu ditulis kaya iki:

if (!match(Op1, m_PosZeroFP()) && isKnownNeverNaN(Op1, &TLI)) {
  I.setOperand(1, ConstantFP::getNullValue(Op1->getType()));
  return &I;
}

Fragmen N36: Kebingungan Variabel

struct Status {
  unsigned Mask;
  unsigned Mode;

  Status() : Mask(0), Mode(0){};

  Status(unsigned Mask, unsigned Mode) : Mask(Mask), Mode(Mode) {
    Mode &= Mask;
  };
  ....
};

PVS-Studio warning: V1001 [CWE-563] Variabel 'Mode' ditugasake nanging ora digunakake ing pungkasan fungsi kasebut. SIModeRegister.cpp 48

Mbebayani banget kanggo menehi argumen fungsi kanthi jeneng sing padha karo anggota kelas. Gampang banget bingung. Kita duwe kasus kaya ngono sadurunge. Ekspresi iki ora masuk akal:

Mode &= Mask;

Argumen fungsi diganti. Mekaten. Argumentasi iki ora digunakake maneh. Paling kamungkinan, sampeyan kudu nulis kaya iki:

Status(unsigned Mask, unsigned Mode) : Mask(Mask), Mode(Mode) {
  this->Mode &= Mask;
};

Fragmen N37: Kebingungan Variabel

class SectionBase {
  ....
  uint64_t Size = 0;
  ....
};

class SymbolTableSection : public SectionBase {
  ....
};

void SymbolTableSection::addSymbol(Twine Name, uint8_t Bind, uint8_t Type,
                                   SectionBase *DefinedIn, uint64_t Value,
                                   uint8_t Visibility, uint16_t Shndx,
                                   uint64_t Size) {
  ....
  Sym.Value = Value;
  Sym.Visibility = Visibility;
  Sym.Size = Size;
  Sym.Index = Symbols.size();
  Symbols.emplace_back(llvm::make_unique<Symbol>(Sym));
  Size += this->EntrySize;
}

Warning PVS-Studio: V1001 [CWE-563] Variabel 'Ukuran' diutus nanging ora digunakake ing mburi fungsi. Object.cpp 424

Kahanane padha karo sing sadurunge. Iku kudu ditulis:

this->Size += this->EntrySize;

Fragmen N38-N47: Padha kelalen mriksa indeks

Sadurunge, kita ndeleng conto pemicu diagnostik V595. Intine yaiku pointer kasebut dereferenced ing wiwitan, lan mung banjur dicenthang. Diagnosa enom V1004 tegesipun kosok wangsulipun, nanging ugi ngungkapaken kathah kalepatan. Iki ngenali kahanan nalika pointer wis dicenthang ing wiwitan lan banjur dilalekake. Ayo goleki kasus kaya ngono sing ditemokake ing LLVM.

int getGEPCost(Type *PointeeType, const Value *Ptr,
               ArrayRef<const Value *> Operands) {
  ....
  if (Ptr != nullptr) {                                            // <=
    assert(....);
    BaseGV = dyn_cast<GlobalValue>(Ptr->stripPointerCasts());
  }
  bool HasBaseReg = (BaseGV == nullptr);

  auto PtrSizeBits = DL.getPointerTypeSizeInBits(Ptr->getType());  // <=
  ....
}

PVS-Studio warning: V1004 [CWE-476] Pointer 'Ptr' digunakake ora aman sawise diverifikasi marang nullptr. Priksa baris: 729, 738. TargetTransformInfoImpl.h 738

Variabel Ptr bisa uga padha nullptr, minangka bukti saka mriksa:

if (Ptr != nullptr)

Nanging, ing ngisor pointer iki ora ana referensi tanpa pamriksan awal:

auto PtrSizeBits = DL.getPointerTypeSizeInBits(Ptr->getType());

Ayo nimbang kasus liyane sing padha.

llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(GlobalDecl GD,
                                                          bool Stub) {
  ....
  auto *FD = dyn_cast<FunctionDecl>(GD.getDecl());
  SmallVector<QualType, 16> ArgTypes;
  if (FD)                                                                // <=
    for (const ParmVarDecl *Parm : FD->parameters())
      ArgTypes.push_back(Parm->getType());
  CallingConv CC = FD->getType()->castAs<FunctionType>()->getCallConv(); // <=
  ....
}

PVS-Studio warning: V1004 [CWE-476] Pointer 'FD' digunakake ora aman sawise diverifikasi marang nullptr. Priksa baris: 3228, 3231. CGDebugInfo.cpp 3231

Pay manungsa waé kanggo tandha FD. Aku yakin masalah kasebut katon jelas lan ora ana panjelasan khusus sing dibutuhake.

Lan luwih:

static void computePolynomialFromPointer(Value &Ptr, Polynomial &Result,
                                         Value *&BasePtr,
                                         const DataLayout &DL) {
  PointerType *PtrTy = dyn_cast<PointerType>(Ptr.getType());
  if (!PtrTy) {                                                   // <=
    Result = Polynomial();
    BasePtr = nullptr;
  }
  unsigned PointerBits =
      DL.getIndexSizeInBits(PtrTy->getPointerAddressSpace());     // <=
  ....
}

PVS-Studio warning: V1004 [CWE-476] Pointer 'PtrTy' digunakake ora aman sawise diverifikasi marang nullptr. Priksa baris: 960, 965. InterleavedLoadCombinePass.cpp 965

Kepiye carane nglindhungi dhewe saka kesalahan kasebut? Dadi luwih ati-ati babagan Code-Review lan gunakake penganalisa statis PVS-Studio kanggo mriksa kode sampeyan kanthi rutin.

Ora ana gunane ngutip fragmen kode liyane kanthi kesalahan jinis iki. Aku mung bakal ninggalake dhaptar bebaya ing artikel:

  • V1004 [CWE-476] Pointer 'Expr' digunakake kanthi ora aman sawise diverifikasi marang nullptr. Priksa baris: 1049, 1078. DebugInfoMetadata.cpp 1078
  • V1004 [CWE-476] Pitunjuk 'PI' digunakake kanthi ora aman sawise diverifikasi marang nullptr. Priksa baris: 733, 753. LegacyPassManager.cpp 753
  • V1004 [CWE-476] Pointer 'StatepointCall' digunakake kanthi ora aman sawise diverifikasi marang nullptr. Priksa baris: 4371, 4379. Verifier.cpp 4379
  • V1004 [CWE-476] Pointer 'RV' digunakake ora aman sawise diverifikasi marang nullptr. Priksa baris: 2263, 2268. TGParser.cpp 2268
  • V1004 [CWE-476] Pointer 'CalleeFn' digunakake kanthi ora aman sawise diverifikasi marang nullptr. Priksa baris: 1081, 1096. SimplifyLibCalls.cpp 1096
  • V1004 [CWE-476] Pointer 'TC' digunakake ora aman sawise diverifikasi marang nullptr. Priksa baris: 1819, 1824. Driver.cpp 1824

Fragmen N48-N60: Ora kritis, nanging cacat (kemungkinan bocor memori)

std::unique_ptr<IRMutator> createISelMutator() {
  ....
  std::vector<std::unique_ptr<IRMutationStrategy>> Strategies;
  Strategies.emplace_back(
      new InjectorIRStrategy(InjectorIRStrategy::getDefaultOps()));
  ....
}

PVS-Studio warning: V1023 [CWE-460] Pointer tanpa pemilik ditambahake menyang wadhah 'Strategi' kanthi metode 'emplace_back'. Kebocoran memori bakal kedadeyan yen ana pangecualian. llvm-isel-fuzzer.cpp 58

Kanggo nambah unsur menyang mburi wadhah kaya std::vektor > sampeyan ora bisa mung nulis xxx.push_back(X anyar), amarga ora ana konversi implisit saka X* в std::unique_ptr.

Solusi umum yaiku nulis xxx.emplace_back(X anyar)awit iku kompilasi: cara emplace_back mbangun unsur langsung saka argumen lan mulane bisa nggunakake konstruktor eksplisit.

Iku ora aman. Yen vektor kebak, banjur memori diparengake maneh. Operasi realokasi memori bisa uga gagal, nyebabake pangecualian dibuwang std::bad_alloc. Ing kasus iki, pointer bakal ilang lan obyek sing digawe ora bakal dibusak.

Solusi sing aman yaiku nggawe unik_ptrsing bakal duwe pointer sadurunge vektor nyoba relokasi memori:

xxx.push_back(std::unique_ptr<X>(new X))

Wiwit C++ 14, sampeyan bisa nggunakake 'std::make_unique':

xxx.push_back(std::make_unique<X>())

Cacat jinis iki ora kritis kanggo LLVM. Yen memori ora bisa dialokasikan, compiler mung bakal mandheg. Nanging, kanggo aplikasi karo dawa uptime, sing ora mung bisa mungkasi yen alokasi memori gagal, iki bisa dadi bug sing ora becik.

Dadi, sanajan kode iki ora nuduhke ancaman praktis kanggo LLVM, Aku ketemu iku migunani kanggo pirembagan bab pola kesalahan iki lan analyzer PVS-Studio wis sinau kanggo ngenali.

Bebaya liyane saka jinis iki:

  • V1023 [CWE-460] Pointer tanpa pemilik ditambahake menyang wadhah 'Passes' kanthi metode 'emplace_back'. Kebocoran memori bakal kedadeyan yen ana pangecualian. PassManager.h 546
  • V1023 [CWE-460] Pointer tanpa pemilik ditambahake menyang wadhah 'AAs' kanthi metode 'emplace_back'. Kebocoran memori bakal kedadeyan yen ana pangecualian. AliasAnalysis.h 324
  • V1023 [CWE-460] Pointer tanpa pemilik ditambahake menyang wadhah 'Entri' kanthi metode 'emplace_back'. Kebocoran memori bakal kedadeyan yen ana pangecualian. DWARFDebugFrame.cpp 519
  • V1023 [CWE-460] Pointer tanpa pemilik ditambahake menyang wadhah 'AllEdges' kanthi metode 'emplace_back'. Kebocoran memori bakal kedadeyan yen ana pangecualian. CFGMST.h 268
  • V1023 [CWE-460] Pointer tanpa pemilik ditambahake menyang wadhah 'VMaps' kanthi metode 'emplace_back'. Kebocoran memori bakal kedadeyan yen ana pangecualian. SimpleLoopUnswitch.cpp 2012
  • V1023 [CWE-460] Pointer tanpa pemilik ditambahake menyang wadhah 'Records' kanthi metode 'emplace_back'. Kebocoran memori bakal kedadeyan yen ana pangecualian. FDRLogBuilder.h 30
  • V1023 [CWE-460] Pointer tanpa pemilik ditambahake menyang wadhah 'PendingSubmodules' kanthi metode 'emplace_back'. Kebocoran memori bakal kedadeyan yen ana pangecualian. ModuleMap.cpp 810
  • V1023 [CWE-460] Pointer tanpa pemilik ditambahake menyang wadhah 'Obyek' kanthi metode 'emplace_back'. Kebocoran memori bakal kedadeyan yen ana pangecualian. DebugMap.cpp 88
  • V1023 [CWE-460] Pointer tanpa pemilik ditambahake menyang wadhah 'Strategi' kanthi metode 'emplace_back'. Kebocoran memori bakal kedadeyan yen ana pangecualian. llvm-isel-fuzzer.cpp 60
  • V1023 [CWE-460] Pointer tanpa pemilik ditambahake menyang wadhah 'Modifiers' kanthi metode 'emplace_back'. Kebocoran memori bakal kedadeyan yen ana pangecualian. llvm-stress.cpp 685
  • V1023 [CWE-460] Pointer tanpa pemilik ditambahake menyang wadhah 'Modifiers' kanthi metode 'emplace_back'. Kebocoran memori bakal kedadeyan yen ana pangecualian. llvm-stress.cpp 686
  • V1023 [CWE-460] Pointer tanpa pemilik ditambahake menyang wadhah 'Modifiers' kanthi metode 'emplace_back'. Kebocoran memori bakal kedadeyan yen ana pangecualian. llvm-stress.cpp 688
  • V1023 [CWE-460] Pointer tanpa pemilik ditambahake menyang wadhah 'Modifiers' kanthi metode 'emplace_back'. Kebocoran memori bakal kedadeyan yen ana pangecualian. llvm-stress.cpp 689
  • V1023 [CWE-460] Pointer tanpa pemilik ditambahake menyang wadhah 'Modifiers' kanthi metode 'emplace_back'. Kebocoran memori bakal kedadeyan yen ana pangecualian. llvm-stress.cpp 690
  • V1023 [CWE-460] Pointer tanpa pemilik ditambahake menyang wadhah 'Modifiers' kanthi metode 'emplace_back'. Kebocoran memori bakal kedadeyan yen ana pangecualian. llvm-stress.cpp 691
  • V1023 [CWE-460] Pointer tanpa pemilik ditambahake menyang wadhah 'Modifiers' kanthi metode 'emplace_back'. Kebocoran memori bakal kedadeyan yen ana pangecualian. llvm-stress.cpp 692
  • V1023 [CWE-460] Pointer tanpa pemilik ditambahake menyang wadhah 'Modifiers' kanthi metode 'emplace_back'. Kebocoran memori bakal kedadeyan yen ana pangecualian. llvm-stress.cpp 693
  • V1023 [CWE-460] Pointer tanpa pemilik ditambahake menyang wadhah 'Modifiers' kanthi metode 'emplace_back'. Kebocoran memori bakal kedadeyan yen ana pangecualian. llvm-stress.cpp 694
  • V1023 [CWE-460] Pointer tanpa pemilik ditambahake menyang wadhah 'Operand' kanthi metode 'emplace_back'. Kebocoran memori bakal kedadeyan yen ana pangecualian. GlobalISelEmitter.cpp 1911
  • V1023 [CWE-460] Pointer tanpa pemilik ditambahake menyang wadhah 'Stash' kanthi cara 'emplace_back'. Kebocoran memori bakal kedadeyan yen ana pangecualian. GlobalISelEmitter.cpp 2100
  • V1023 [CWE-460] A pointer tanpa pemilik ditambahake menyang wadhah 'Matchers' kanthi cara 'emplace_back'. Kebocoran memori bakal kedadeyan yen ana pangecualian. GlobalISelEmitter.cpp 2702

kesimpulan

Aku ngetokake 60 bebaya kanthi total lan banjur mandheg. Apa ana cacat liyane sing dideteksi PVS-Studio analyzer ing LLVM? Ya wis. Nanging, nalika aku nulis fragmen kode kanggo artikel kasebut, wis sore, utawa malah wengi, lan aku mutusake yen wis wayahe nyebat dina.

Muga-muga sampeyan nemokake iku menarik lan pengin nyoba analisa PVS-Studio.

Sampeyan bisa ngundhuh analyzer lan njaluk tombol mineweeper ing kaca iki.

Sing paling penting, gunakake analisis statis kanthi rutin. Priksa siji-wektu, digawa metu dening kita supaya popularize metodologi analisis statis lan PVS-Studio ora skenario normal.

Good luck kanggo nambah kualitas lan linuwih kode!

Nemokake bug ing LLVM 8 nggunakake analyzer PVS-Studio

Yen sampeyan pengin nuduhake artikel iki karo pamirsa sing nganggo basa Inggris, gunakake tautan terjemahan: Andrey Karpov. Nemokake Bugs ing LLVM 8 karo PVS-Studio.

Source: www.habr.com

Add a comment