Inventum cimices in LLVM 8 utens PVS Studio analyser

Inventum cimices in LLVM 8 usura PVS Studio analyser
Plus quam duo anni elapsi sunt ab ultimo codice perscriptio LLVM projectoris nostri PVS-Studii analystoris utentis. Faciamus analysrem PVS-Studii adhuc praecipuum instrumentum esse ad errores cognoscendos et vulnerabilitates potentiales. Ad hoc faciendum nos in LLVM 8.0.0 emissiones novas errores cohibebimus ac reperiemus.

Articulus scribendus

Probus esse, articulum hunc scribere nolui. Non interest scribere consilium quod aliquoties iam repressimus (1, 2, 3). Melius est scribere de re nova, sed nihil habeo.

Quotienscumque nova versio LLVM dimissa vel renovata est Clang Static Analyzerquaestionibus huius generis in epistula nostra accipimus:

Ecce novam versionem Clang Static Analyzer novos errores invenire didicit! Mihi videtur pertinere ad PVS-Studii utendi decrescentem. Clang plus errores invenit quam ante et facultates PVS-Studii prehendit. Quid de hoc putas?

Ad haec ego semper aliquid simile respondere volo;

Non otiosi sumus! Significanter emendavimus facultates PVS-Studii analystoris. Noli ergo solliciti esse, ut ante pergamus.

Proh dolor, male respondet. probationes nullae in eo sunt. Et ideo hoc articulum nunc scribo. Ita, consilium LLVM iterum repressum est et in variis erroribus inventi sunt. Nunc demonstrabo ea quae mihi placuerunt. Clang Static Analyzer hos errores invenire non potest (vel perquam incommodum est hoc eius auxilio). Sed possumus. Omnes autem istos errores inveni in una vespera.

Sed scribens articulum plures septimanas tulit. Modo non potui me adducere ut haec omnia in textum mitterem :).

Obiter, si quaeras qualibus technologiae in PVS-Studio analyseri adhibentur ad cognoscendos errores et vulnerabilitates potentiae, tunc admoneo ut cognoscas hanc. nota.

Nova et vetera diagnostica

Ut iam dictum est, abhinc duos annos LLVM inceptum denuo repressum est et errores inventi emendantur. Nunc hic articulus novam praepostere errorum exhibebit. Cur novi cimices inventi sunt? 3 Causae huius sunt:

  1. LLVM propositum evolvitur, mutato vetere codice et addito novo codice. Naturaliter errores novi sunt in codice mutato et scripto. Hoc clare demonstrat analysis statice adhibenda regulariter, non interdum. Articuli nostri facultates PVS-Studii analystoris bene ostendunt, sed hoc nihil ad rem pertinet ad qualitatem codicis meliorem ac sumptus ad errores figendi reducendo. Utere static codice analyser regulariter!
  2. Nos diagnostica exsistentes finalisamus et emendamus. Ideo analyser errores cognoscere potest quos in superioribus lustrationibus non animadvertit.
  3. Nova diagnostica in PVS-Studio apparuerunt quae ante abhinc annos non 2 exstiterunt. Eos in sectione singula illustrare decrevi ut evolutionem PVS-Studii clare ostenderet.

Vitia notantur diagnostica, quae fuit II annos

Fragment N1: Copy-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-Studium monitum; V501 There are identical sub- expressions 'Name.startswith("avx570.mask.permvar.") 'ad laevam et ad dextram' || operator. AutoUpgrade.cpp 512

Duplex est coercitum quod nomen incipit a substring "avx512.mask.permvar.". In secunda perscriptio, plane aliud scribere volebant, sed textum exscriptum emendare obliti sunt.

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

Monitum PVS-Studio: V501 Sunt idem sub-expressiones 'CXNameRange_WantQualifier' ad sinistram et ad dextram '|' operator. CIndex.cpp 7245

Ob typum idem nomen constans bis adhibetur CXNameRange_WantQualifier.

Fragment N3: Confusio cum praecedentia operator

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

PVS-Studium monitum; V502 Fortasse opera '?:' aliter operante quam expectabatur. Auctor '?:' inferior prioritatem habet quam '==' operator. PPCTargetTransformInfo.cpp 783

Opinor, hic error pulcherrimus est. Ita, scio me alienas ideas de pulchritudine habere :).

Nunc, secundum operator prioritatibuslocutio aestimatur sic:

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

Ex parte practica, talis conditio non convenit, cum reduci possit;

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

Patet hic error. Maxime, 0/1 cum variabili comparare voluerunt Index. Ad codicem figere debes parenthesi addere circa operator ternarios:

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

Viam operans ternarius valde periculosus est ac errores logicos provocat. Diligenter cum illa et ne parenthesi avarus sis. Hoc loco accuratius vidi hicc. Cavete operante et incluse parenthesi.

Fragment N4, N5:

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-Studium monitum; V522 [CWE-476] Dereference of the null indicator 'LHS' locum habere potest. TGParser.cpp 2152

Si monstratorem LHS nulla sit, cautio fiat. Sed, sed, idem regula nulla dereferenced erit. LHS->getAsString().

Haec res admodum typica est, cum in errore tracto error latet, cum nemo eos probat. Static analysres reprehendo omnes codicem reachabile, quamvis saepe adhibetur. Optime hoc exemplum est quomodo analysis stabilis complementa aliae artes probationis et erroris tutelae complent.

Similis regula tractantem errorem RHS licet in codice proxime infra: V522 [CWE-476] Dereferenceing of the null indicator 'RHS' locum habere possit. TGParser.cpp 2186

Fragmentum N6: Using the monstratorem post movens

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 Admonitio: V522 [CWE-476] Dereferenceing of the null indicator 'ProgClone' locum habere potest. Miscompilation.cpp 601

In principio dolor indicatorum ProgClone desinit habere obiectum;

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

Nam nunc ProgClone nulla regula est. Ideo nulla regula dereferentia mox infra occurrere debet:

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

Sed re vera hoc non fiet! Nota quod fascias non actu supplicium est.

In principio continens MiscompiledFunctions purgatur;

MiscompiledFunctions.clear();

Deinceps amplitudo vasis huius in ansa conditionis adhibetur;

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

Ansam non incipere facile est videre. Mendum quoque hunc codicem aliter scribi debere puto.

Parem inclitam errorum incidisse nobis videtur! Unus error personat alium :).

Fragmentum N7: Using the monstratorem post movens

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-Studia admonitionis: V522 [CWE-476] Dereferenceing of the null indicator 'Expertus' locum habere potest. Miscompilation.cpp 709

Eadem res iterum. Primo contenta objecti moventur, et tunc ponitur quasi nihil factum. Hanc condicionem magis ac saepius in codice programmatis post motus semanticos in C++ apparuisse video. Inde est quod linguam C++ amabo! Plures magisque novae sunt viae ad proprium crus emittentes. PVS-Studia analyser semper laborem habebit :).

Fragment N8:

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 monitum: V522 [CWE-476] Dereferenceing of the null pointer 'Type' locum habere potest. PrettyFunctionDumper.cpp 233

Praeter tractores errorum, functiones printout debugging probare non solent. Talem causam coram nobis habemus. Munus exspectat utentis, qui pro solvendo problemata reficere cogetur.

corrigere;

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

Fragment N9:

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-Studia admonitionis: V522 [CWE-476] Dereferencens nulli regulae 'Ty' locum habere potest. SearchableTableEmitter.cpp 614

Omnia plana puto, nec explicatione eget.

Fragment 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-Studium monitum; V570 Genus variabilis sibi ipsi attribuitur. FormatTokenLexer.cpp 249

Nihil sibi variabile assignando. Verisimile scribere volebant:

Identifier->Type = Question->Type;

Fragment N11:

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-Studium monitum; V622 [CWE-478] Vide inspiciendo sententiam 'switch'. Fieri potest ut primus auctor "casus" desit. SystemZAsmParser.cpp 652

Valde suspectum est operator in principio intermissum. An oblitus es hic aliud scribere?

Fragment N12: Reperiens monstratorem post 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-Studium monitum; V595 [CWE-476] Monstrator Callee adhibebatur antequam contra nullptr comprobaretur. Perscriptio lineae: 172, 174. AMDGPUInline.cpp 172

monstratorem Callee in principio est dereferenced tempore munus quod vocatur getTTI.

Et tunc evenit ut hoc regula cohibeatur ad aequalitatem nullptr:

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

Sed sera ...

Fragment N13 - N..

De condicione in priore codice fragmentum disputatum non est singulare. Hinc apparet;

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 monitus: V595 [CWE-476] The ' CalleeFn' monstratorem adhibitum erat antequam contra nullptr verificaretur. Perscriptio lineae: 1079, 1081. SimplifyLibCalls.cpp 1079

Et hic:

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-Studia admonitionis: V595 [CWE-476] The 'ND' monstrator ante adhibitum erat contra nullptr verificatum. Perscriptio lineae: 532, 534. SemaTemplateInstantiateDecl.cpp 532

Et hic:

  • V595 [CWE-476] The 'U' monstrator adhibitus est antequam verificatur contra nullptr. Perscriptio lineae: 404, 407. DWARFormValue.cpp 404
  • V595 [CWE-476] The 'ND' monstratorem adhibitum erat antequam contra nullptr verificaretur. Perscriptio lineae: 2149, 2151. SemaTemplateInstantiate.cpp 2149

V595. Nescio igitur an plures sint similes errores praeter eos qui hic recensentur. Verisimile est.

Fragment N17, N18: Suspicious shift

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

PVS-Studium monitum; V629 [CWE-190] Considera inspectis '~(Size - 1) << 1' expression. Bit shifting of the 32-bit value with the subsequent expansion to the 64-bit type. AArch64AddressingModes.h 260

Non potest esse cimex et signum opera prorsus ut intendit. Sed hoc plane valde suspectum est ac reprimendum.

Dicamus variabilis Size 16 = XNUMX , et tunc auctor codicis cogitavit eam in variabili NImms significatio;

1111111111111111111111111111111111111111111111111111111111100000

Sed re vera id ipsum erit;

0000000000000000000000000000000011111111111111111111111111100000

Ita res omnes calculi fiunt utentes 32-biti speciei unsigned. Et tunc demum implicite dilatabitur hoc genus 32-bit non signatum uint64_t. In hoc casu, maximae notabiles frena nulla erunt.

Rem sic figere potes:

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

Similis condicio: V629 [CWE-190] Considera inspectis expressionibus 'Immr << 6'. Bit shifting of the 32-bit value with the subsequent expansion to the 64-bit type. AArch64AddressingModes.h 269

Fragment N19: Absentis keyword aliud?

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-Studium monitum; V646 [CWE-670] Considera logicam applicationis inspectionem. Fieri potest ut aliud keyword desit. AMDGPUAsmParser.cpp 5655

Non est hic error. Quia tunc scandalum primi if finit in continueergo non refert, est keyword aliud aut non. Utroque modo idem opus in codice erit. Adhuc desiderari aliud facit codicem incertius et periculosius. Si in posterum continue evanescit, opus incipiet in codice omnino aliter. Mea sententia melius est addere aliud.

Fragmentum N20: quattuor typos eiusdem generis

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-Studia monita;

  • V655 [CWE-480] Fila concatenata non sunt usui. Considerans inspiciendo 'Expression + Name.str()'. Symbol.cpp 32
  • V655 [CWE-480] Fila concatenata non sunt usui. Considera inspicientes "Expression +" (ObjC Class)" + Name.str()' expression. Symbol.cpp 35
  • V655 [CWE-480] Fila concatenata non sunt usui. Considera inspicientes "Expression +" (ObjC Class EH) " + Name.str()" expressionem. Symbol.cpp 38
  • V655 [CWE-480] Fila concatenata non sunt usui. Considera inspicientes "Expression +" (ObjC IVar)" + Name.str()' expression. Symbol.cpp 41

Casu + operans loco += operantis ponitur. Unde fit consiliorum, qui sunt insensati.

Fragment N21: mores Undefined

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

Conare invenire in periculo codice te ipsum. Et haec est picturae attentionem ad distrahendum, ut non statim responsum spectet;

Inventum cimices in LLVM 8 usura PVS Studio analyser

PVS-Studium monitum; V708 [CWE-758] Constructio periculosa adhibetur: 'FeaturesMap[Op] = FeaturesMap.size()', ubi 'FeaturesMap' est 'mappa' classis. Indefinitis moribus hoc perducat. RISCVCompressInstEmitter.cpp 490

Quaestio recta:

FeaturesMap[Op] = FeaturesMap.size();

Si elementum Op non invenitur, tunc novum elementum in tabula creatum est et numerus elementorum in hac tabula ibi scribitur. Num munus vocabitur solum ignotum est magnitudine ante vel post addit novum elementum.

Fragment N22-N24: Repetita destinationes

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-Studium monitum; V519 'NType' variabilis valores bis successive assignatur. Fallitur fortasse hoc. Perscriptio linearum: 563, 1663. MachOObjectFile.cpp 1664

Non puto hic verum esse errorem. Iustus supervacuum iterata assignatione. Sed tamen erro.

Item:

  • V519 [CWE-563] The 'B.NDesc' variabilis bis successive assignatur. Fallitur fortasse hoc. Perscriptio linearum: 1488, 1489. llvm-nm.cpp 1489
  • V519 [CWE-563] Variabilis bis successive assignatur. Fallitur fortasse hoc. Perscriptio lineae: 59, 61. coff2yaml.cpp 61

Fragment N25-N27: More Repositions

Nunc inspiciamus paulum aliam versionem Repositionis.

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 monitum: V519 [CWE-563] The 'Alignment' variabilis valores bis successive assignatur. Fallitur fortasse hoc. Check lines: 1158, 1160. LoadStoreVectorizer.cpp 1160

Valde mirum est hoc codicem qui logicam errorem videtur continere. In principio, variabilis noctis valor assignatus secundum conditionem. Et tunc iterum fit assignatio, sed nunc sine aliqua retenta.

Similia condiciones hic videri possunt:

  • V519 [CWE-563] Effectus variabiles bis successive assignatur. Fallitur fortasse hoc. Perscriptio lineae: 152, 165. WebAssemblyRegStackify.cpp 165 .
  • V519 [CWE-563] The 'Expecta NoDerefChunk' variabilis bis successive assignatur. Fallitur fortasse hoc. Perscriptio linearum: 4970, 4973. SemaType.cpp 4973

Fragment N28: Semper vera conditio

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-Studium monitum; V547 Semper verum est. X571DisassemblerDecoder.cpp 0

Reprehendo non facit sensum. Variabilis nextByte semper non pervenerunt usque ad valorem 0x90quae ex antecedente reprehendo. Hic est error quidam logicus.

Fragment N29 - N..

Multis admonitionibus analyser prodit totam condicionem (V547) Vel pars eius (V560) Semper verum aut falsum est. Saepe hi errores reales non sunt, sed simpliciter imperiti Codicis, effectus tortor dilatationis, et similia. Sensum tamen est has omnes admonitiones intueri, cum verae logicae errores subinde eveniant. Exempli gratia haec sectionis codicis suspecta est;

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-Studium monitum; V560 Pars expressionis conditionalis semper falsa est: RegNo == 570xe. ARMDisassembler.cpp 0

Constans 0xE valor 14 in decimalibus est. Examen RegNo == 0xe non facit sensum, quod si RegNo > 13tunc ipsa omissum complebit.

Multae aliae admonitiones cum IDs V547 et V560, sed ut cum V595His ego monitis non quaero. Iam satis liquet me habuisse materiam scribendae articulum :). Ignotum est igitur quot huius generis errores in LLVM usu PVS-Studii reperiri possint.

Exemplum dabo tibi cur has pervestigationes taedet. analyser rectissime ad admonitionem edendam in codice sequenti. Sed hoc non est error.

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

PVS-Studio Monitum: V547 [CWE-570] elocutio '!HasError' semper falsa est. UnwrappedLineParser.cpp 1635

Fragment N30: ​​Suspectus reditus

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-Studium monitum; V612 [CWE-670] Merito 'redire' intra ansam. R600OptimizeVectorRegisters.cpp 63

Haec vel error vel ars specifica est quae aliquid explanare vult programmatoribus codicis legendi. Hoc consilium mihi nihil explicat et valde suspectum spectat. Melius est non sic scribere :).

Taedet? Tum tempus est ut tea vel capulus.

Inventum cimices in LLVM 8 usura PVS Studio analyser

Vitia quae a novis diagnostica

Puto 30 activationes diagnostica veterum satis esse. Nunc videamus quae res commodae reperiri possint cum novis diagnosticis quae in analysi postquam apparuerunt prior compescit. Hoc tempore summa 66 diagnostica generalis propositi ad C ++ analystoris additae sunt.

Fragmentum N31: unreachable 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-Studium monitum; V779 [CWE-561] impossibile codice deprehenditur. Fieri potest ut error sit praesens. ExecutionUtils.cpp 146

Ut videre potes, utraque operantis rami if desinit invitatio operantis reditum. Proinde continens CtorDtorsByPriority numquam absolvi.

Fragmentum N32: unreachable 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 admonitio: V779 [CWE-561] Impossibile codicem deprehendi. Fieri potest ut error sit praesens. LLParser.cpp 835

Novus locus. Intueamur hunc locum primum:

return ParseTypeIdEntry(SummaryID);
break;

Primo aspectu, videtur quod hic non sit error. Is vultus ut auctor intermissum Extra hic est, et delere simpliciter potes. Sed non omnes simplices.

Analyser commonitionem in lineis prodit:

Lex.setIgnoreColonInIdentifiers(false);
return false;

Et quidem impossibile est hoc signum. Omnes casus in SWITCH desinit invitatio operantis reditum. et nunc solus insipiens est intermissum non tam innocens! Forsitan unus ex ramis finiendus est intermissumquam reditum?

Fragmentum N33: Random reset in altum bits

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-Studium monitum; V784 Magnitudo frenum larva minor est quam magnitudo operandi prioris. Haec tibi causa est superiora frena iacturae. RuntimeDyld.cpp 815

Nota quod munus getStubAlignment redit genus unsigned. Computemus vim locutionis, si munus reddat valorem 8:

~(getStubAlignment() - 1)

~(8u-1)

0xFFFFFFFF8u

Nunc animadverto ut variabilis DataSize LXIV-genus unsigned frenum habet. Evenit ut cum operandi DataSize & 64xFFFFFF0u faciendo, omnes triginta duo summi ordinis minutas ad nihilum retexere. Maxime, hoc non est quod programmator voluit. Suspicor voluisse computare: DataSize &8xFFFFFFFFFFFFFF0u.

Errorem figere, hoc scribere debes;

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

Aut isto:

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

Fragmentum N34: expressa generis cast Deficio

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-Studium monitum; V1028 [CWE-190] Possibile est redundantiam esse. Considera operanda iactantia 'NumElts* Scale operantis ad 'size_t' generis, non exitum. X86ISelLowering.h 1577

Expresse genus iectionis adhibetur ad vitandum redundantiam cum multiplicatione generis variabilium int. Sed expressa ratio mittentes hic contra redundantiam non tutatur. Primum variabiles multiplicabuntur, et tunc demum 32-blum multiplicationis multiplicationis rationi dilatetur. size_t.

Fragmentum N35: Deficio Copy-Crustulum

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] Duo similia codicis fragmenta inventa sunt. Fortasse, hoc typo et 'Op1' variabile pro 'Op0' adhiberi debet. InstCombineCompares.cpp 5507

Haec nova interesting diagnostica condiciones designat ubi fragmentum codicis exscriptum est et nonnulla nomina in eo mutata esse inceperunt, sed in uno loco eam non emendaverunt.

Lorem quod in secundo obstructionum mutaverunt Op0 on Op1. Sed in uno loco id non habebant. Verisimile debet esse sic scriptum:

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

Fragment N36:

struct Status {
  unsigned Mask;
  unsigned Mode;

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

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

PVS-Studium monitum; V1001 Modus variabilis assignatur, sed fine functionis non adhibetur. SIModeRegister.cpp 563

Periculosum est rationes eadem nomina dare ac membra ordinis. Confusum est facillime. Talem causam coram nobis habemus. Haec expressio non facit sensum:

Mode &= Mask;

Munus argumentum mutat. Id omne. Hoc argumentum iam non est usus. Verisimile est tibi sic scripsisse;

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

Fragment N37:

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

Monitum PVS-Studio: V1001 [CWE-563] Magnitudo variabilis assignatur sed functionis fine non adhibetur. Object.cpp 424

Simile est cum priori. Scribatur:

this->Size += this->EntrySize;

Fragment N38-N47: Obliti sunt indicem cohibere

Antea exempla diagnostica excitato inspeximus V595. Essentia eius est quod monstratorem ab initio dereferenced et tunc demum cohibere. Iuvenes diagnostica V1004 est contrarium in sensu, sed multum manifestat errorum. condiciones indicat ubi monstratorem in principio repressum ac deinde oblitum fuisse. Intueamur tales casus intra LLVM repertos.

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 monitus: V1004 [CWE-476] The 'Ptr' monstrator male usus est postquam contra nullptr verificatur. Check lines: 729, 738. TargetTransformInfoImpl.h 738

variabilis Ptr par sit nullptrut patet per repressionem;

if (Ptr != nullptr)

Attamen sub hac regula dereferenced sine praevia perceptio est:

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

Aliud consimiliter consideremus.

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 monitus: V1004 [CWE-476] The 'FD' monstrator male usus est postquam contra nullptr verificavit. Perscriptio lineae: 3228, 3231. CGDebugInfo.cpp 3231

Attende signum FD. Pro certo habeo quaestionem clare visibilis et nullam specialem explicationem requiri.

Et infra:

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 monitum: V1004 [CWE-476] The 'PtrTy' monstrator usus est non securus postquam contra nullptr verificatur. Perscriptio lineae: 960, 965. InterleavedLoadCombinePass.cpp 965

Quomodo te ab istis erroribus defendas? Diligentius in Codicis-Review et utere analysi PVS-Studii static ad regulariter codicem tuum reprehendo.

Nihil attinet nos in aliis codicis fragmentis commemorare cum eiusmodi erroribus. Tantum elenchum monitionum in capitulo relinquam;

  • V1004 [CWE-476] The Expr' monstrator usus est infideliter postquam contra nullptr verificatur. Perscriptio lineae: 1049, 1078. DebugInfoMetadata.cpp 1078
  • V1004 [CWE-476] The 'PI' monstrator male adhibitus est postquam contra nullptr comprobatum est. Perscriptio lineae: 733, 753. LegacyPassManager.cpp 753
  • V1004 [CWE-476] The 'StatepointCall' monstratorem non tuto adhibebatur postquam contra nullptr comprobatum est. Perscriptio lineae: 4371, 4379. Verifier.cpp 4379
  • V1004 [CWE-476] Regula RV non tuto adhibita est postquam contra nullptr comprobata est. Perscriptio lines: 2263, 2268. TGParser.cpp 2268
  • V1004 [CWE-476] Regula CalleeFn male adhibita est postquam contra nullptr comprobata est. Check lines: 1081, 1096. SimplifyLibCalls.cpp 1096
  • V1004 [CWE-476] Regula TC non tuto adhibebatur postquam contra nullptr verificabatur. Perscriptio lineae: 1819, 1824. Driver.cpp 1824

Fragment N48-N60: Not critica, sed defectio (potest memoria Leak)

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

PVS-Studium monitum; V1023 [CWE-460] Regula sine possessore ad modum emplace_backe continens per 'strategies' continens additur. Memoria Leak occurret in casu exceptionis. llvm-isel-fuzzer.cpp 58

Addere elementum usque ad finem continentis std :: vector > non solum scribere xxx.push_back (novum X)Cum enim nulla sit conversio implicita X* Π² std :: unique_ptr.

Communis solutio est scribere xxx.emplace_back(new X)cum componat: method emplace_back elementum directe ex suis argumentis construit ideoque auctoribus expressis uti potest.

Non est tutum. Si vector plenus est, memoria re- partita est. Operatio reallocation memoria deficiat, inde in exceptione coniecta std :: bad_alloc. In hoc casu, monstrator amittetur, et objectum creatum nunquam delebitur.

Tuta solutio est creare unique_ptrquae monstratorem possidebit antequam vector reallocate memoriam conatur;

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

Cum C++14, std::make_unique uti potes.

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

Hoc genus defectus LLVM criticum non est. Si memoria collocari non potest, compilator simpliciter subsistet. Sed ut mauris magna uptimeQuod si desinere non potest, si memoria deficiat, hoc verum esse potest cimex sordidus.

Itaque, licet hoc codicem LLVM practicam minationem non ponat, utilem inveni de hoc errore loqui et quod PVS-Studii analyser ad cognoscendum illum didicit.

Alia huius generis monita:

  • V1023 [CWE-460] Regula sine possessore ad modum transeuntis continens per modum emplace_backe additur. Memoria Leak occurret in casu exceptionis. PassManager.h 546
  • V1023 [CWE-460] Regula sine possessore additur "AAs continens per modum emplace_back. Memoria Leak occurret in casu exceptionis. AliasAnalysis.h 324
  • V1023 [CWE-460] Regula sine possessore ad modum Viscus continens per modum emplace_backe additur. Memoria Leak occurret in casu exceptionis. DWARFDebugFrame.cpp 519
  • V1023 [CWE-460] Regula sine possessore additur 'AllEdges' continens modum 'emplace_back'. Memoria Leak occurret in casu exceptionis. CFGMST.h 268
  • V1023 [CWE-460] Regula sine possessore additur 'VMaps' continens modum 'emplace_back'. Memoria Leak occurret in casu exceptionis. SimpleLoopUnswitch.cpp 2012
  • V1023 [CWE-460] Regula sine possessore ad modum continentis Records continens per "emplace_back". Memoria Leak occurret in casu exceptionis. FDRLogBuilder.h 30
  • V1023 [CWE-460] Regula sine possessore additur "PendingSubmodules" continens modum emplace_back. Memoria Leak occurret in casu exceptionis. ModuleMap.cpp 810
  • V1023 [CWE-460] Regula sine possessore ad modum obiecti continens per modum emplace_backe additur. Memoria Leak occurret in casu exceptionis. DebugMap.cpp 88
  • V1023 [CWE-460] Regula sine possessore ad modum emplace_backe continens per 'strategies' continens additur. Memoria Leak occurret in casu exceptionis. llvm-isel-fuzzer.cpp 60
  • V1023 [CWE-460] Regula sine possessore ad modum emplace_backe continens per modum emplace_backe additur. Memoria Leak occurret in casu exceptionis. llvm-stress.cpp 685
  • V1023 [CWE-460] Regula sine possessore ad modum emplace_backe continens per modum emplace_backe additur. Memoria Leak occurret in casu exceptionis. llvm-stress.cpp 686
  • V1023 [CWE-460] Regula sine possessore ad modum emplace_backe continens per modum emplace_backe additur. Memoria Leak occurret in casu exceptionis. llvm-stress.cpp 688
  • V1023 [CWE-460] Regula sine possessore ad modum emplace_backe continens per modum emplace_backe additur. Memoria Leak occurret in casu exceptionis. llvm-stress.cpp 689
  • V1023 [CWE-460] Regula sine possessore ad modum emplace_backe continens per modum emplace_backe additur. Memoria Leak occurret in casu exceptionis. llvm-stress.cpp 690
  • V1023 [CWE-460] Regula sine possessore ad modum emplace_backe continens per modum emplace_backe additur. Memoria Leak occurret in casu exceptionis. llvm-stress.cpp 691
  • V1023 [CWE-460] Regula sine possessore ad modum emplace_backe continens per modum emplace_backe additur. Memoria Leak occurret in casu exceptionis. llvm-stress.cpp 692
  • V1023 [CWE-460] Regula sine possessore ad modum emplace_backe continens per modum emplace_backe additur. Memoria Leak occurret in casu exceptionis. llvm-stress.cpp 693
  • V1023 [CWE-460] Regula sine possessore ad modum emplace_backe continens per modum emplace_backe additur. Memoria Leak occurret in casu exceptionis. llvm-stress.cpp 694
  • V1023 [CWE-460] Regula sine possessore additur 'Operandi' continens modum emplace_back. Memoria Leak occurret in casu exceptionis. GlobalISelEmitter.cpp 1911
  • V1023 [CWE-460] Regula sine possessore ad modum Stash continens per modum emplace_backe additur. Memoria Leak occurret in casu exceptionis. GlobalISelEmitter.cpp 2100
  • V1023 [CWE-460] Regula sine possessore addito 'Matchers' continens modum 'emplace_back'. Memoria Leak occurret in casu exceptionis. GlobalISelEmitter.cpp 2702

conclusio,

60 monita prorsus edita sum ac deinde cessavi. Suntne alia vitia quae in LLVM detegit analyser PVS-Studiae? Ita, habeo. Sed cum scriberem e codice fragmentorum ad articulum, sero vespere vel potius etiam nocte factum est, et decrevi ut tempus esset, ut diem dicerem.

Spero te iucundam reperisse ac experiri PVS-Studii analysrem volentem esse.

Potes detrahere analyser et clavis fodinas at hoc page.

Maxime, utere analysi static regulariter. Unus-vicis checksa nobis ad popularem methodologiam analysis statice ac PVS-Studiae ad popularem missionem normalem non sunt.

Bene vale in meliori qualitate et fidelitate tui codicis!

Inventum cimices in LLVM 8 usura PVS Studio analyser

Si articulum hunc cum auditorio Anglico loquentem communicare vis, nexus translationis utere: Andrey Karpov. Inventum Bugs in LLVM 8 cum PVS-Studio.

Source: www.habr.com