Pagpangita mga bug sa LLVM 8 gamit ang PVS-Studio analyzer

Pagpangita mga bug sa LLVM 8 gamit ang PVS-Studio analyzer
Kapin sa duha ka tuig ang milabay sukad sa katapusang pagsusi sa code sa proyekto sa LLVM gamit ang among PVS-Studio analyzer. Atong siguroon nga ang PVS-Studio analyzer usa gihapon ka nanguna nga himan alang sa pag-ila sa mga sayup ug potensyal nga mga kahuyangan. Aron mahimo kini, among susihon ug pangitaon ang bag-ong mga sayup sa pagpagawas sa LLVM 8.0.0.

Artikulo nga isulat

Sa tinuud, dili ko gusto nga isulat kini nga artikulo. Dili makapaikag ang pagsulat bahin sa usa ka proyekto nga gisusi na namo sa makadaghang higayon (1, 2, 3). Mas maayo nga magsulat bahin sa bag-ong butang, apan wala akoy kapilian.

Matag higayon nga ang usa ka bag-ong bersyon sa LLVM ipagawas o gi-update Clang Static Analyzer, makadawat mig mga pangutana sa mosunod nga matang sa among mail:

Tan-awa, ang bag-ong bersyon sa Clang Static Analyzer nakakat-on sa pagpangita og bag-ong mga sayop! Para nako nagkunhod ang kalambigitan sa paggamit sa PVS-Studio. Ang Clang nakit-an ang daghang mga sayup kaysa kaniadto ug nakuha ang mga kapabilidad sa PVS-Studio. Unsay imong hunahuna bahin niini?

Niini gusto nako kanunay nga tubagon sama sa:

Dili usab kami maglingkod nga walay pulos! Gipauswag namo pag-ayo ang mga kapabilidad sa PVS-Studio analyzer. Busa ayaw kabalaka, nagpadayon kami sa pagpanguna sama kaniadto.

Ikasubo, kini usa ka dili maayo nga tubag. Walay mga pruweba niini. Ug mao kana ngano nga gisulat ko kini nga artikulo karon. Busa, ang proyekto sa LLVM gisusi na usab ug lainlain nga mga sayup ang nakit-an niini. Akong ipakita karon kadtong morag makapainteres kanako. Ang Clang Static Analyzer dili makit-an kini nga mga sayup (o dili kaayo kombenyente nga buhaton kini sa tabang niini). Apan mahimo nato. Dugang pa, akong nakit-an ug gisulat kining tanan nga mga sayup sa usa ka gabii.

Apan ang pagsulat sa artikulo mikabat ug pipila ka semana. Dili nako madala ang akong kaugalingon nga ibutang kini tanan sa teksto :).

Pinaagi sa dalan, kung interesado ka kung unsang mga teknolohiya ang gigamit sa analista sa PVS-Studio aron mahibal-an ang mga sayup ug potensyal nga mga kahuyangan, nan gisugyot ko nga pamilyar ka niini. timan-i.

Bag-o ug daan nga mga diagnostic

Sama sa nahibal-an na, mga duha ka tuig ang milabay ang proyekto sa LLVM gisusi pag-usab, ug ang mga sayup nga nakit-an gitul-id. Karon kini nga artikulo magpakita usa ka bag-ong hugpong sa mga sayup. Nganong nakit-an ang bag-ong mga bug? Adunay 3 ka rason niini:

  1. Ang proyekto sa LLVM nag-uswag, nagbag-o sa daan nga code ug nagdugang bag-ong code. Natural, adunay bag-ong mga sayup sa giusab ug gisulat nga code. Kini tin-aw nga nagpakita nga ang static nga pagtuki kinahanglang gamiton kanunay, ug dili usahay. Ang among mga artikulo nagpakita og maayo sa mga kapabilidad sa PVS-Studio analyzer, apan kini walay kalabotan sa pagpausbaw sa kalidad sa code ug pagpakunhod sa gasto sa pag-ayo sa mga sayop. Regular nga mogamit ug static code analyzer!
  2. Gitapos ug gipauswag namo ang kasamtangan nga mga diagnostic. Busa, ang analisador makaila sa mga sayop nga wala niini namatikdan sa miaging mga pag-scan.
  3. Ang bag-ong mga diagnostic nagpakita sa PVS-Studio nga wala maglungtad 2 ka tuig na ang milabay. Nakahukom ko nga i-highlight sila sa usa ka bulag nga seksyon aron klaro nga ipakita ang pag-uswag sa PVS-Studio.

Mga depekto nga giila sa diagnostics nga naglungtad 2 ka tuig na ang milabay

Tipik N1: Kopyaha-Paste

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 pasidaan: V501 [CWE-570] Adunay managsama nga sub-expression nga 'Name.startswith("avx512.mask.permvar.")' sa wala ug sa tuo sa '||' operator. AutoUpgrade.cpp 73

Doble nga gisusi nga ang ngalan nagsugod sa substring nga "avx512.mask.permvar.". Sa ikaduhang tseke, klaro nga gusto nilang magsulat og lain, apan nakalimot sa pagtul-id sa gikopya nga teksto.

Tipik 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;
  ....
}

Pasidaan sa PVS-Studio: V501 Adunay managsama nga mga sub-expression nga 'CXNameRange_WantQualifier' sa wala ug sa tuo sa '|' operator. CIindex.cpp 7245

Tungod sa usa ka typo, ang parehas nga ngalan nga kanunay gigamit kaduha CXNameRange_WantQualifier.

Fragment N3: Kalibog sa operator precedence

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

PVS-Studio pasidaan: V502 [CWE-783] Tingali ang operator nga '?:' nagtrabaho sa lahi nga paagi kaysa sa gilauman. Ang operator nga '?:' adunay ubos nga prayoridad kay sa operator nga '=='. PPCTargetTransformInfo.cpp 404

Sa akong hunahuna, kini usa ka matahum nga sayup. Oo, nahibal-an nako nga naa koy mga katingad-an nga ideya bahin sa kaanyag :).

Karon, sumala sa mga prayoridad sa operator, ang ekspresyon gitimbang-timbang sama sa mosunod:

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

Gikan sa usa ka praktikal nga punto sa panglantaw, ang ingon nga kahimtang dili makatarunganon, tungod kay kini mahimong mubu sa:

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

Kini usa ka klaro nga sayup. Lagmit, gusto nila nga itandi ang 0/1 sa usa ka variable index. Aron ayohon ang code kinahanglan nimo nga idugang ang mga parentesis sa palibot sa ternary operator:

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

Pinaagi sa dalan, ang operator sa ternary delikado kaayo ug naghagit sa mga lohikal nga sayup. Pag-amping pag-ayo niini ug ayaw pagkahakog sa mga parentesis. Gitan-aw nako kini nga hilisgutan sa mas detalyado dinhi, sa kapitulo nga β€œPagbantay sa ?: Operator ug Ilakip Kini sa Parentheses.”

Tipik 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 pasidaan: V522 [CWE-476] Mahimong mahitabo ang dereferencing sa null pointer nga 'LHS'. TGParser.cpp 2152

Kung ang pointer LHS mao ang null, usa ka pasidaan kinahanglan nga gi-isyu. Bisan pa, sa baylo, kini nga parehas nga null pointer ibaliwala: LHS->getAsString().

Kini usa ka kasagaran nga kahimtang kung ang usa ka sayup gitago sa usa ka tigdumala sa sayup, tungod kay wala’y usa nga nagsulay niini. Gisusi sa mga static analisador ang tanan nga maabot nga code, bisan kung unsa ka sagad kini gigamit. Kini usa ka maayo kaayo nga panig-ingnan kung giunsa ang static nga pag-analisa nakadugang sa uban pang mga pamaagi sa pagsulay ug pagpanalipod sa sayup.

Ang parehas nga sayup sa pagdumala sa pointer RHS gitugot sa code sa ubos: V522 [CWE-476] Ang dereferencing sa null pointer nga 'RHS' mahimong mahitabo. TGParser.cpp 2186

Fragment N6: Paggamit sa pointer pagkahuman sa paglihok

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] Mahimong mahitabo ang dereferencing sa null pointer nga 'ProgClone'. Micompilation.cpp 601

Sa sinugdanan usa ka smart pointer ProgClone mihunong sa pagpanag-iya sa butang:

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

Sa pagkatinuod, karon ProgClone usa ka null pointer. Busa, ang usa ka null pointer dereference kinahanglan mahitabo sa ubos:

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

Apan, sa pagkatinuod, kini dili mahitabo! Timan-i nga ang loop dili aktuwal nga gipatuman.

Sa sinugdanan sa sudlanan Nasayop nga mga Kalihokan gilimpyohan:

MiscompiledFunctions.clear();

Sunod, ang gidak-on niini nga sudlanan gigamit sa kahimtang sa loop:

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

Sayon nga makita nga ang loop wala magsugod. Sa akong hunahuna kini usa usab ka bug ug ang code kinahanglan nga isulat nga lahi.

Morag nasugatan namo kanang bantogang pagkaparehas sa mga sayop! Ang usa ka sayup nagtabon sa lain :).

Fragment N7: Paggamit sa pointer pagkahuman sa paglihok

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 nga pasidaan: V522 [CWE-476] Ang dereferencing sa null pointer nga 'Pagsulay' mahimong mahitabo. Sayop nga pag-compile.cpp 709

Ang sama nga kahimtang pag-usab. Sa sinugdan, ang mga sulod sa butang gipalihok, ug unya kini gigamit ingon nga walay nahitabo. Nakita nako kini nga sitwasyon nga mas ug mas kanunay sa code sa programa human ang mga semantika sa paglihok nagpakita sa C ++. Mao kini ang hinungdan nganong ganahan ko sa C++ nga pinulongan! Adunay dugang ug mas bag-ong mga paagi sa pagpusil sa imong kaugalingong bitiis. Ang PVS-Studio analyzer kanunay adunay trabaho :).

Fragment 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);
}

Pahimangno sa PVS-Studio: V522 [CWE-476] Mahimong mahitabo ang dereferencing sa null pointer nga 'Type'. PrettyFunctionDumper.cpp 233

Dugang sa mga tigdumala sa sayop, ang pag-debug sa mga function sa printout kasagarang dili masulayan. Kami adunay ingon nga kaso sa among atubangan. Naghulat ang function alang sa tiggamit, nga, imbes nga masulbad ang iyang mga problema, mapugos sa pag-ayo niini.

Husto nga:

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

Fragment 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());
   ....
}

Pahimangno sa PVS-Studio: V522 [CWE-476] Mahimong mahitabo ang dereferencing sa null pointer nga 'Ty'. SearchableTableEmitter.cpp 614

Sa akong hunahuna ang tanan klaro ug wala magkinahanglan og katin-awan.

Tipik 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 pasidaan: V570 Ang 'Identifier->Type' nga baryable gi-assign sa iyang kaugalingon. FormatTokenLexer.cpp 249

Walay kapuslanan ang pag-assign sa usa ka variable sa iyang kaugalingon. Lagmit gusto nilang isulat:

Identifier->Type = Question->Type;

Fragment N11: Kadudahang break

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 pasidaan: V622 [CWE-478] Ikonsiderar ang pagsusi sa pahayag sa 'switch'. Posible nga nawala ang unang 'case' operator. SystemZAsmParser.cpp 652

Adunay usa ka kadudahang operator sa sinugdanan pahugno. Nakalimot ka ba sa pagsulat og laing butang dinhi?

Fragment N12: Pagsusi sa usa ka pointer human sa 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 pasidaan: V595 [CWE-476] Ang 'Callee' pointer gigamit sa wala pa kini mapamatud-an batok sa nullptr. Susiha ang mga linya: 172, 174. AMDGPUInline.cpp 172

Timaan Callee sa sinugdanan gi-dereference sa panahon nga ang function gitawag getTTI.

Ug unya kini nahimo nga kini nga pointer kinahanglan nga susihon alang sa pagkaparehas nullptr:

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

Apan ulahi na ang tanan…

Fragment N13 - N...: Pagsusi sa pointer human sa dereferencing

Ang sitwasyon nga gihisgutan sa miaging code fragment dili talagsaon. Kini makita dinhi:

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] Ang 'CalleeFn' pointer gigamit sa wala pa kini mapamatud-an batok sa nullptr. Susiha ang mga linya: 1079, 1081. SimplifyLibCalls.cpp 1079

Ug dinhi:

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] Ang 'ND' pointer gigamit sa wala pa kini mapamatud-an batok sa nullptr. Susiha ang mga linya: 532, 534. SemaTemplateInstantiateDecl.cpp 532

Ug dinhi:

  • V595 [CWE-476] Ang 'U' pointer gigamit sa wala pa kini mapamatud-an batok sa nullptr. Susiha ang mga linya: 404, 407. DWARFormValue.cpp 404
  • V595 [CWE-476] Ang 'ND' pointer gigamit sa wala pa kini mapamatud-an batok sa nullptr. Susiha ang mga linya: 2149, 2151. SemaTemplateInstantiate.cpp 2149

Ug unya wala ako interesado sa pagtuon sa mga pasidaan nga adunay numero nga V595. Mao nga wala ko mahibal-an kung adunay daghang parehas nga mga sayup gawas sa mga nalista dinhi. Lagmit anaa.

Fragment N17, N18: Kadudahang pagbalhin

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

PVS-Studio pasidaan: V629 [CWE-190] Ikonsiderar ang pagsusi sa '~(Size - 1) << 1' nga ekspresyon. Pagbalhin sa bit sa 32-bit nga kantidad nga adunay sunod nga pagpalapad sa 64-bit nga tipo. AArch64AddressingModes.h 260

Mahimong dili kini usa ka bug ug ang kodigo molihok sa eksakto nga katuyoan. Apan kini klaro nga usa ka kadudahang lugar ug kinahanglan nga susihon.

Ingnon ta ang variable Size katumbas sa 16, ug dayon ang tagsulat sa code nagplano nga makuha kini sa usa ka variable NImms bili:

1111111111111111111111111111111111111111111111111111111111100000

Apan, sa pagkatinuod, ang resulta mao ang:

0000000000000000000000000000000011111111111111111111111111100000

Ang kamatuoran mao nga ang tanan nga mga kalkulasyon mahitabo gamit ang 32-bit unsigned type. Ug unya ra, kini nga 32-bit nga wala’y pirma nga tipo nga hingpit nga gipalapdan uint64_t. Sa kini nga kaso, ang labing hinungdanon nga mga bit mahimong zero.

Mahimo nimong ayuhon ang sitwasyon sama niini:

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

Susama nga sitwasyon: V629 [CWE-190] Ikonsiderar ang pagsusi sa 'Immr << 6' nga ekspresyon. Pagbalhin sa bit sa 32-bit nga kantidad nga adunay sunod nga pagpalapad sa 64-bit nga tipo. AArch64AddressingModes.h 269

Fragment N19: Nawala nga keyword lain?

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 pasidaan: V646 [CWE-670] Ikonsiderar ang pagsusi sa lohika sa aplikasyon. Posible nga nawala ang 'lain' nga keyword. AMDGPUAsmParser.cpp 5655

Walay sayop dinhi. Sukad niadto-block sa una if matapos sa magpadayon, unya dili igsapayan, adunay usa ka keyword lain o dili. Sa bisan unsang paagi ang code molihok parehas. Gimingaw pa lain naghimo sa code nga mas klaro ug peligroso. Kung sa umaabot magpadayon mawala, ang code magsugod sa pagtrabaho sa hingpit nga lahi. Sa akong hunahuna mas maayo nga idugang lain.

Fragment N20: Upat ka typo sa parehas nga tipo

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;
}

Mga pasidaan sa PVS-Studio:

  • V655 [CWE-480] Ang mga kuwerdas gidugtong apan wala gigamit. Ikonsiderar ang pagsusi sa 'Result + Name.str()' nga ekspresyon. Simbolo.cpp 32
  • V655 [CWE-480] Ang mga kuwerdas gidugtong apan wala gigamit. Ikonsiderar ang pagsusi sa 'Resulta + "(ObjC Class)" + Name.str()' nga ekspresyon. Simbolo.cpp 35
  • V655 [CWE-480] Ang mga kuwerdas gidugtong apan wala gigamit. Ikonsiderar ang pagsusi sa 'Resulta + "(ObjC Class EH) " + Name.str()' nga ekspresyon. Simbolo.cpp 38
  • V655 [CWE-480] Ang mga kuwerdas gidugtong apan wala gigamit. Ikonsiderar ang pagsusi sa 'Resulta + "(ObjC IVar)" + Name.str()' nga ekspresyon. Simbolo.cpp 41

Sa aksidente, ang + operator gigamit imbes ang += operator. Ang resulta mao ang mga disenyo nga walay kahulogan.

Fragment N21: Dili matino nga kinaiya

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();
    }
  }
}

Sulayi ang pagpangita sa peligro nga code sa imong kaugalingon. Ug kini usa ka hulagway aron makabalda sa atensyon aron dili dayon tan-awon ang tubag:

Pagpangita mga bug sa LLVM 8 gamit ang PVS-Studio analyzer

PVS-Studio pasidaan: V708 [CWE-758] Delikado nga pagtukod gigamit: 'FeaturesMap[Op] = FeaturesMap.size()', diin ang 'FeaturesMap' kay sa 'map' class. Kini mahimong mosangpot sa dili matino nga kinaiya. RISCVCompressInstEmitter.cpp 490

Linya sa problema:

FeaturesMap[Op] = FeaturesMap.size();

Kung elemento Op dili makit-an, unya usa ka bag-ong elemento ang gihimo sa mapa ug ang gidaghanon sa mga elemento niini nga mapa gisulat didto. Wala lang nahibal-an kung tawagan ang function gidak-on sa wala pa o pagkahuman sa pagdugang usa ka bag-ong elemento.

Fragment N22-N24: Gibalikbalik nga mga buluhaton

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 pasidaan: V519 [CWE-563] Ang variable nga 'NType' gi-assign nga mga kantidad kaduha nga sunud-sunod. Tingali kini usa ka sayup. Susiha ang mga linya: 1663, 1664. MachOObjectFile.cpp 1664

Sa akong hunahuna wala'y tinuod nga sayup dinhi. Usa lang ka wala kinahanglana nga gibalikbalik nga buluhaton. Pero blunder gihapon.

Ingon usab:

  • V519 [CWE-563] Ang variable nga 'B.NDesc' gi-assign nga mga kantidad kaduha nga sunud-sunod. Tingali kini usa ka sayup. Susiha ang mga linya: 1488, 1489. llvm-nm.cpp 1489
  • V519 [CWE-563] Ang variable gi-assign nga mga kantidad kaduha nga sunud-sunod. Tingali kini usa ka sayup. Susiha ang mga linya: 59, 61. coff2yaml.cpp 61

Fragment N25-N27: Daghang reassignment

Karon atong tan-awon ang usa ka gamay nga lahi nga bersyon sa reassignment.

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;
  ....
}

Pahimangno sa PVS-Studio: V519 [CWE-563] Ang variable nga 'Alignment' gi-assign nga mga kantidad kaduha nga sunud-sunod. Tingali kini usa ka sayup. Susiha ang mga linya: 1158, 1160. LoadStoreVectorizer.cpp 1160

Talagsaon kaayo kini nga code nga dayag nga adunay usa ka lohikal nga sayup. Sa sinugdanan, variable paglaray, pagtalay usa ka bili ang gi-assign depende sa kondisyon. Ug unya ang buluhaton mahitabo pag-usab, apan karon walay bisan unsa nga tseke.

Ang susamang mga sitwasyon makita dinhi:

  • V519 [CWE-563] Ang variable nga 'Epekto' gi-assign nga mga kantidad kaduha nga sunud-sunod. Tingali kini usa ka sayup. Susiha ang mga linya: 152, 165. WebAssemblyRegStackify.cpp 165
  • V519 [CWE-563] Ang variable nga 'ExpectNoDerefChunk' gi-assign nga mga kantidad kaduha nga sunud-sunod. Tingali kini usa ka sayup. Susiha ang mga linya: 4970, 4973. SemaType.cpp 4973

Fragment N28: Kanunay tinuod nga kahimtang

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 pasidaan: V547 [CWE-571] Ang ekspresyong 'nextByte != 0x90' kay kanunay tinuod. X86DisassemblerDecoder.cpp 379

Ang pagsusi dili makatarunganon. Variable sunodByte sa kanunay dili katumbas sa bili 0x90, nga nagsunod gikan sa miaging tseke. Kini usa ka matang sa lohikal nga sayup.

Fragment N29 - N...: Kanunay tinuod/sayup nga mga kondisyon

Ang analisador nag-isyu og daghang mga pasidaan nga ang tibuok nga kondisyon (V547) o bahin niini (V560) kanunay tinuod o bakak. Kasagaran kini dili tinuod nga mga sayup, apan yano nga sloppy code, ang resulta sa pagpalapad sa macro, ug uban pa. Bisan pa, makatarunganon nga tan-awon kining tanan nga mga pasidaan, tungod kay ang tinuod nga lohikal nga mga sayup mahitabo matag karon ug unya. Pananglitan, kini nga seksyon sa code kadudahan:

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 pasidaan: V560 [CWE-570] Usa ka bahin sa conditional nga ekspresyon kanunay bakak: RegNo == 0xe. ARMDisassembler.cpp 939

Ang kanunay nga 0xE mao ang kantidad nga 14 sa decimal. Pagsusi RegNo == 0xe dili makataronganon kay kung RegNo > 13, unya ang function makompleto ang pagpatuman niini.

Adunay daghang uban pang mga pasidaan nga adunay mga ID V547 ug V560, apan sama sa V595, dili ko interesado sa pagtuon niini nga mga pasidaan. Klaro na nga aduna akoy igong materyal sa pagsulat ug artikulo :). Busa, wala mahibal-an kung pila ang mga sayup sa kini nga klase nga mailhan sa LLVM gamit ang PVS-Studio.

Hatagan ko ikaw usa ka pananglitan kung ngano nga ang pagtuon sa kini nga mga hinungdan makalaay. Ang analisador hingpit nga husto sa pag-isyu sa usa ka pasidaan alang sa mosunod nga code. Apan dili kini sayop.

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

PVS-Studio Warning: V547 [CWE-570] Ang ekspresyong '!HasError' kanunay bakak. UnwrappedLineParser.cpp 1635

Fragment N30: ​​Kadudahang pagbalik

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 pasidaan: V612 [CWE-670] Usa ka walay kondisyon nga 'pagbalik' sulod sa usa ka loop. R600OptimizeVectorRegisters.cpp 63

Kini usa ka sayup o usa ka piho nga teknik nga gituyo aron ipatin-aw ang usa ka butang sa mga programmer nga nagbasa sa code. Kini nga disenyo wala magpatin-aw sa bisan unsa nga butang kanako ug tan-awon kaayo kadudahan. Mas maayo nga dili ingon niana ang pagsulat :).

Gikapoy? Unya panahon na sa paghimo og tsa o kape.

Pagpangita mga bug sa LLVM 8 gamit ang PVS-Studio analyzer

Mga depekto nga giila sa bag-ong mga diagnostic

Sa akong hunahuna ang 30 nga pagpaaktibo sa daan nga mga diagnostic igo na. Atong tan-awon karon kung unsang makapaikag nga mga butang ang makit-an sa mga bag-ong diagnostic nga nagpakita sa analisador pagkahuman nauna mga tseke. Niini nga panahon, usa ka kinatibuk-an nga 66 nga mga diagnostic sa kinatibuk-ang katuyoan ang gidugang sa C++ analyzer.

Fragment N31: Dili maabot nga code

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 pasidaan: V779 [CWE-561] Dili maabot nga kodigo nakit-an. Posible nga adunay usa ka sayup. ExecutionUtils.cpp 146

Sama sa imong nakita, ang duha nga mga sanga sa operator if matapos sa usa ka tawag sa operator pagbalik. Sumala niana, ang sudlanan CtorDtorsByPriority dili gayud malimpyohan.

Fragment N32: Dili maabot nga code

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 nga pasidaan: V779 [CWE-561] Dili maabot nga kodigo namatikdan. Posible nga adunay usa ka sayup. LLParser.cpp 835

Makaiikag nga kahimtang. Atong tan-awon una kining dapita:

return ParseTypeIdEntry(SummaryID);
break;

Sa unang tan-aw, morag walay sayop dinhi. Murag operator pahugno adunay usa ka dugang dinhi, ug mahimo nimo kining papason. Bisan pa, dili tanan yano ra.

Ang analisador nagpagawas ug pasidaan sa mga linya:

Lex.setIgnoreColonInIdentifiers(false);
return false;

Ug sa tinuud, kini nga code dili maabot. Ang tanan nga mga kaso sa switch matapos sa usa ka tawag gikan sa operator pagbalik. Ug karon walay salabutan nga nag-inusara pahugno murag dili kaayo harmless! Tingali ang usa sa mga sanga kinahanglan nga matapos sa pahugno, dili sa pagbalik?

Fragment N33: Random nga pag-reset sa taas nga mga bit

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 pasidaan: V784 Ang gidak-on sa bit mask mas gamay kay sa gidak-on sa unang operand. Kini ang hinungdan sa pagkawala sa mas taas nga mga bit. RuntimeDyld.cpp 815

Palihug timan-i nga ang function getStubAlignment nagbalik nga tipo unsigned. Atong kuwentahon ang bili sa ekspresyon, sa paghunahuna nga ang function mobalik sa bili 8:

~(getStubAlignment() - 1)

~(8u-1)

0xFFFFFFFF8u

Karon matikdi nga ang variable Gidak-on sa datos adunay 64-bit unsigned type. Kini nahimo nga kung himuon ang DataSize & 0xFFFFFFF8u nga operasyon, ang tanan nga katloan ug duha nga mga high-order bit i-reset sa zero. Lagmit, dili kini ang gusto sa programmer. Nagduda ko nga gusto niyang kuwentahon: DataSize & 0xFFFFFFFFFFFFFFF8u.

Aron ayohon ang sayup, kinahanglan nimong isulat kini:

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

O sa ingon:

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

Fragment N34: Napakyas ang klaro nga tipo sa 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 pasidaan: V1028 [CWE-190] Posibleng pag-awas. Ikonsiderar ang pag-cast sa mga operand sa operator nga 'NumElts * Scale' sa tipo nga 'size_t', dili ang resulta. X86ISelLowering.h 1577

Ang tin-aw nga tipo sa paghulma gigamit aron malikayan ang pag-awas kung magpadaghan ang mga variable nga tipo int. Bisan pa, ang tin-aw nga tipo sa paghulma dinhi dili makapanalipod batok sa pag-awas. Una, ang mga variable padaghanon, ug unya ang 32-bit nga resulta sa pagpadaghan mapalapad sa tipo kadako_t.

Fragment N35: Napakyas nga Kopyaha-Paste

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] Duha ka susama nga mga tipik sa code ang nakit-an. Tingali, kini usa ka typo ug 'Op1' variable kinahanglan gamiton imbes nga 'Op0'. InstCombineCompares.cpp 5507

Kining bag-o nga makapaikag nga diagnostic nagpaila sa mga sitwasyon diin ang usa ka piraso sa code gikopya ug ang pipila ka mga ngalan nagsugod sa pag-ilis niini, apan sa usa ka dapit wala nila kini gitul-id.

Palihug timan-i nga sa ikaduhang bloke sila nausab Sa 0 sa Sa 1. Apan sa usa ka dapit wala nila kini giayo. Lagmit kinahanglan nga kini gisulat sama niini:

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

Fragment N36: Variable Confusion

struct Status {
  unsigned Mask;
  unsigned Mode;

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

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

PVS-Studio pasidaan: V1001 [CWE-563] Ang variable nga 'Mode' gi-assign apan wala gigamit sa katapusan sa function. SIModeRegister.cpp 48

Delikado kaayo ang paghatag sa mga argumento sa function sa parehas nga ngalan sa mga miyembro sa klase. Dali ra kaayo maglibog. Kami adunay ingon nga kaso sa among atubangan. Kini nga ekspresyon dili makatarunganon:

Mode &= Mask;

Nagbag-o ang argumento sa function. Mao ra. Kini nga argumento wala na gigamit. Lagmit kinahanglan nimo kining isulat sama niini:

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

Fragment N37: Variable Confusion

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;
}

Pasidaan sa PVS-Studio: V1001 [CWE-563] Ang 'Size' variable kay gi-assign apan wala gigamit sa katapusan sa function. Object.cpp 424

Ang kahimtang susama sa nauna. Kini kinahanglan nga isulat:

this->Size += this->EntrySize;

Fragment N38-N47: Nakalimot sila sa pagsusi sa index

Kaniadto, among gitan-aw ang mga pananglitan sa diagnostic triggering V595. Ang esensya niini mao nga ang pointer gi-dereference sa sinugdanan, ug pagkahuman gisusi. Batan-ong mga diagnostic V1004 mao ang kaatbang sa kahulogan, apan usab nagpadayag sa daghang mga sayop. Kini nagpaila sa mga sitwasyon diin ang pointer gisusi sa sinugdanan ug unya nakalimot sa pagbuhat niini. Atong tan-awon ang mga kaso nga makita sa sulod sa 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());  // <=
  ....
}

Pahimangno sa PVS-Studio: V1004 [CWE-476] Ang 'Ptr' pointer gigamit nga dili luwas human kini mapamatud-an batok sa nullptr. Susiha ang mga linya: 729, 738. TargetTransformInfoImpl.h 738

Variable Si Ptr mahimong managsama nullptr, ingon nga ebidensya sa tseke:

if (Ptr != nullptr)

Bisan pa, sa ubos niini nga pointer gi-dereference nga wala’y pasiuna nga pagsusi:

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

Atong tagdon ang laing susamang kaso.

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] Ang 'FD' pointer gigamit nga dili luwas human kini mapamatud-an batok sa nullptr. Susiha ang mga linya: 3228, 3231. CGDebugInfo.cpp 3231

Hatagi'g pagtagad ang timaan FD. Sigurado ako nga ang problema klaro nga makita ug wala’y kinahanglan nga espesyal nga katin-awan.

Ug dugang pa:

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());     // <=
  ....
}

Pahimangno sa PVS-Studio: V1004 [CWE-476] Ang 'PtrTy' pointer gigamit nga dili luwas human kini mapamatud-an batok sa nullptr. Susiha ang mga linya: 960, 965. InterleavedLoadCombinePass.cpp 965

Giunsa pagpanalipod ang imong kaugalingon gikan sa ingon nga mga sayup? Pagmabinantayon sa Code-Review ug gamita ang PVS-Studio static analyzer aron kanunay nga susihon ang imong code.

Walay kapuslanan ang pagkutlo sa ubang mga tipik sa code nga adunay mga sayop niini nga matang. Magbilin lang kog listahan sa mga pasidaan sa artikulo:

  • V1004 [CWE-476] Ang 'Expr' pointer gigamit nga dili luwas human kini mapamatud-an batok sa nullptr. Susiha ang mga linya: 1049, 1078. DebugInfoMetadata.cpp 1078
  • V1004 [CWE-476] Ang 'PI' pointer gigamit nga dili luwas human kini mapamatud-an batok sa nullptr. Susiha ang mga linya: 733, 753. LegacyPassManager.cpp 753
  • V1004 [CWE-476] Ang 'StatepointCall' pointer gigamit nga dili luwas human kini mapamatud-an batok sa nullptr. Susiha ang mga linya: 4371, 4379. Verifier.cpp 4379
  • V1004 [CWE-476] Ang 'RV' pointer gigamit nga dili luwas human kini mapamatud-an batok sa nullptr. Susiha ang mga linya: 2263, 2268. TGParser.cpp 2268
  • V1004 [CWE-476] Ang 'CalleeFn' pointer gigamit nga dili luwas human kini mapamatud-an batok sa nullptr. Susiha ang mga linya: 1081, 1096. SimplifyLibCalls.cpp 1096
  • V1004 [CWE-476] Ang 'TC' pointer gigamit nga dili luwas human kini mapamatud-an batok sa nullptr. Susiha ang mga linya: 1819, 1824. Driver.cpp 1824

Fragment N48-N60: Dili kritikal, apan usa ka depekto (posible nga pagtulo sa memorya)

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

PVS-Studio pasidaan: V1023 [CWE-460] Ang usa ka pointer nga walay tag-iya gidugang sa 'Mga estratehiya' nga sudlanan pinaagi sa 'emplace_back' nga pamaagi. Ang usa ka memory leak mahitabo sa kaso sa usa ka eksepsiyon. llvm-isel-fuzzer.cpp 58

Aron makadugang usa ka elemento sa katapusan sa usa ka sudlanan sama sa std::vektor > dili ka basta magsulat xxx.push_back(bag-ong X), tungod kay walay implicit nga pagkakabig gikan sa X* Π² std::unique_ptr.

Usa ka komon nga solusyon mao ang pagsulat xxx.emplace_back(bag-ong X)tungod kay kini nag-compile: pamaagi emplace_back nagtukod ug usa ka elemento nga direkta gikan sa mga argumento niini ug busa makagamit ug klaro nga mga konstruktor.

Dili kini luwas. Kung ang vector puno, nan ang memorya gigahin pag-usab. Ang operasyon sa pag-usab sa panumduman mahimong mapakyas, nga moresulta sa usa ka eksepsiyon nga gilabay std::bad_alloc. Sa kini nga kaso, ang pointer mawala ug ang gibuhat nga butang dili gayud mapapas.

Ang usa ka luwas nga solusyon mao ang paghimo talagsaon_ptrnga manag-iya sa pointer sa dili pa ang vector mosulay sa pag-relocate sa memorya:

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

Sukad sa C++ 14, mahimo nimong gamiton ang 'std::make_unique':

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

Kini nga matang sa depekto dili kritikal alang sa LLVM. Kung ang memorya dili magahin, ang compiler mohunong lamang. Bisan pa, alang sa mga aplikasyon nga adunay dugay uptime, nga dili lang matapos kung mapakyas ang alokasyon sa memorya, mahimo kini nga usa ka tinuod nga daotan nga bug.

Mao nga, bisan kung kini nga code wala maghatag usa ka praktikal nga hulga sa LLVM, nakit-an nako nga mapuslanon ang paghisgot bahin sa kini nga sumbanan sa sayup ug nga ang analista sa PVS-Studio nakakat-on sa pag-ila niini.

Ang ubang mga pasidaan niini nga matang:

  • V1023 [CWE-460] Usa ka pointer nga walay tag-iya gidugang sa 'Passes' nga sudlanan pinaagi sa 'emplace_back' nga pamaagi. Ang usa ka memory leak mahitabo sa kaso sa usa ka eksepsiyon. PassManager.h 546
  • V1023 [CWE-460] Usa ka pointer nga walay tag-iya gidugang sa 'AAs' nga sudlanan pinaagi sa 'emplace_back' nga pamaagi. Ang usa ka memory leak mahitabo sa kaso sa usa ka eksepsiyon. AliasAnalysis.h 324
  • V1023 [CWE-460] Usa ka pointer nga walay tag-iya gidugang sa 'Entries' nga sudlanan pinaagi sa 'emplace_back' nga pamaagi. Ang usa ka memory leak mahitabo sa kaso sa usa ka eksepsiyon. DWARFDebugFrame.cpp 519
  • V1023 [CWE-460] Usa ka pointer nga walay tag-iya gidugang sa 'AllEdges' nga sudlanan pinaagi sa 'emplace_back' nga pamaagi. Ang usa ka memory leak mahitabo sa kaso sa usa ka eksepsiyon. CFGMST.h 268
  • V1023 [CWE-460] Usa ka pointer nga walay tag-iya gidugang sa 'VMaps' nga sudlanan pinaagi sa 'emplace_back' nga pamaagi. Ang usa ka memory leak mahitabo sa kaso sa usa ka eksepsiyon. SimpleLoopUnswitch.cpp 2012
  • V1023 [CWE-460] Usa ka pointer nga walay tag-iya gidugang sa 'Records' nga sudlanan pinaagi sa 'emplace_back' nga pamaagi. Ang usa ka memory leak mahitabo sa kaso sa usa ka eksepsiyon. FDRLogBuilder.h 30
  • V1023 [CWE-460] Usa ka pointer nga walay tag-iya gidugang sa 'PendingSubmodules' nga sudlanan pinaagi sa 'emplace_back' nga pamaagi. Ang usa ka memory leak mahitabo sa kaso sa usa ka eksepsiyon. ModuleMap.cpp 810
  • V1023 [CWE-460] Ang usa ka pointer nga walay tag-iya gidugang sa 'Mga butang' nga sudlanan pinaagi sa 'emplace_back' nga pamaagi. Ang usa ka memory leak mahitabo sa kaso sa usa ka eksepsiyon. DebugMap.cpp 88
  • V1023 [CWE-460] Usa ka pointer nga walay tag-iya gidugang sa 'Mga Estratehiya' nga sudlanan pinaagi sa 'emplace_back' nga pamaagi. Ang usa ka memory leak mahitabo sa kaso sa usa ka eksepsiyon. llvm-isel-fuzzer.cpp 60
  • V1023 [CWE-460] Usa ka pointer nga walay tag-iya gidugang sa 'Modifiers' nga sudlanan pinaagi sa 'emplace_back' nga pamaagi. Ang usa ka memory leak mahitabo sa kaso sa usa ka eksepsiyon. llvm-stress.cpp 685
  • V1023 [CWE-460] Usa ka pointer nga walay tag-iya gidugang sa 'Modifiers' nga sudlanan pinaagi sa 'emplace_back' nga pamaagi. Ang usa ka memory leak mahitabo sa kaso sa usa ka eksepsiyon. llvm-stress.cpp 686
  • V1023 [CWE-460] Usa ka pointer nga walay tag-iya gidugang sa 'Modifiers' nga sudlanan pinaagi sa 'emplace_back' nga pamaagi. Ang usa ka memory leak mahitabo sa kaso sa usa ka eksepsiyon. llvm-stress.cpp 688
  • V1023 [CWE-460] Usa ka pointer nga walay tag-iya gidugang sa 'Modifiers' nga sudlanan pinaagi sa 'emplace_back' nga pamaagi. Ang usa ka memory leak mahitabo sa kaso sa usa ka eksepsiyon. llvm-stress.cpp 689
  • V1023 [CWE-460] Usa ka pointer nga walay tag-iya gidugang sa 'Modifiers' nga sudlanan pinaagi sa 'emplace_back' nga pamaagi. Ang usa ka memory leak mahitabo sa kaso sa usa ka eksepsiyon. llvm-stress.cpp 690
  • V1023 [CWE-460] Usa ka pointer nga walay tag-iya gidugang sa 'Modifiers' nga sudlanan pinaagi sa 'emplace_back' nga pamaagi. Ang usa ka memory leak mahitabo sa kaso sa usa ka eksepsiyon. llvm-stress.cpp 691
  • V1023 [CWE-460] Usa ka pointer nga walay tag-iya gidugang sa 'Modifiers' nga sudlanan pinaagi sa 'emplace_back' nga pamaagi. Ang usa ka memory leak mahitabo sa kaso sa usa ka eksepsiyon. llvm-stress.cpp 692
  • V1023 [CWE-460] Usa ka pointer nga walay tag-iya gidugang sa 'Modifiers' nga sudlanan pinaagi sa 'emplace_back' nga pamaagi. Ang usa ka memory leak mahitabo sa kaso sa usa ka eksepsiyon. llvm-stress.cpp 693
  • V1023 [CWE-460] Usa ka pointer nga walay tag-iya gidugang sa 'Modifiers' nga sudlanan pinaagi sa 'emplace_back' nga pamaagi. Ang usa ka memory leak mahitabo sa kaso sa usa ka eksepsiyon. llvm-stress.cpp 694
  • V1023 [CWE-460] Usa ka pointer nga walay tag-iya gidugang sa 'Operands' nga sudlanan pinaagi sa 'emplace_back' nga pamaagi. Ang usa ka memory leak mahitabo sa kaso sa usa ka eksepsiyon. GlobalISelEmitter.cpp 1911
  • V1023 [CWE-460] Usa ka pointer nga walay tag-iya gidugang sa 'Stash' nga sudlanan pinaagi sa 'emplace_back' nga pamaagi. Ang usa ka memory leak mahitabo sa kaso sa usa ka eksepsiyon. GlobalISelEmitter.cpp 2100
  • V1023 [CWE-460] Usa ka pointer nga walay tag-iya gidugang sa 'Matchers' nga sudlanan pinaagi sa 'emplace_back' nga pamaagi. Ang usa ka memory leak mahitabo sa kaso sa usa ka eksepsiyon. GlobalISelEmitter.cpp 2702

konklusyon

Nagpagawas ako og 60 ka mga pasidaan sa kinatibuk-an ug dayon mihunong. Aduna bay ubang mga depekto nga nakita sa PVS-Studio analyzer sa LLVM? Oo, naa ko. Bisan pa, sa dihang nagsulat ako og mga tipik sa code alang sa artikulo, gabii na kaayo, o kaha gabii pa, ug nakahukom ko nga panahon na nga tawgon kini nga usa ka adlaw.

Nanghinaut ko nga nakit-an nimo kini nga makapaikag ug gusto nimong sulayan ang analisador sa PVS-Studio.

Mahimo nimong i-download ang analisador ug makuha ang yawe sa minesweeper sa kini nga panid.

Labing importante, gamita kanunay ang static analysis. Usa ka higayon nga mga tseke, nga gihimo kanamo aron mapopular ang pamaagi sa static nga pagtuki ug ang PVS-Studio dili usa ka normal nga senaryo.

Good luck sa pagpalambo sa kalidad ug kasaligan sa imong code!

Pagpangita mga bug sa LLVM 8 gamit ang PVS-Studio analyzer

Kung gusto nimong ipaambit kini nga artikulo sa usa ka tigpaminaw nga nagsultig English, palihug gamita ang link sa paghubad: Andrey Karpov. Pagpangita mga Bug sa LLVM 8 nga adunay PVS-Studio.

Source: www.habr.com

Idugang sa usa ka comment