Tha còrr air dà bhliadhna air a dhol seachad bhon sgrùdadh còd mu dheireadh den phròiseact LLVM a’ cleachdadh ar n-anailisiche PVS-Studio. Dèan cinnteach gu bheil an anailisiche PVS-Studio fhathast na phrìomh inneal airson mearachdan agus so-leòntachd a chomharrachadh. Gus seo a dhèanamh, nì sinn sgrùdadh agus lorgaidh sinn mearachdan ùra anns an naidheachd LLVM 8.0.0.
Artaigil ri sgrìobhadh
Gus a bhith onarach, cha robh mi airson an artaigil seo a sgrìobhadh. Chan eil e inntinneach sgrìobhadh mu phròiseact air an do rinn sinn sgrùdadh grunn thursan (
Gach uair a thèid dreach ùr de LLVM fhoillseachadh no ùrachadh
Seall, tha an dreach ùr de Clang Static Analyzer air ionnsachadh gus mearachdan ùra a lorg! Tha e coltach rium gu bheil iomchaidheachd cleachdadh PVS-Studio a’ dol sìos. Bidh Clang a’ lorg barrachd mhearachdan na bha e roimhe agus a’ togail suas ri comasan PVS-Studio. Dè do bheachd air seo?
Airson seo tha mi an-còmhnaidh ag iarraidh rudeigin mar seo a fhreagairt:
Cha bhith sinn a’ suidhe leisg idir! Tha sinn air comasan an anailisiche PVS-Studio a leasachadh gu mòr. Mar sin na gabh dragh, cumaidh sinn oirnn a’ stiùireadh mar a bha sinn roimhe.
Gu mì-fhortanach, is e droch fhreagairt a tha seo. Chan eil dearbhadh sam bith ann. Agus is ann air sgàth sin a tha mi a’ sgrìobhadh an artaigil seo a-nis. Mar sin, chaidh am pròiseact LLVM a sgrùdadh a-rithist agus chaidh grunn mhearachdan a lorg ann. Seallaidh mi a-nis an fheadhainn a bha inntinneach dhomh. Chan urrainn do Clang Static Analyzer na mearachdan sin a lorg (no tha e air leth mì-ghoireasach sin a dhèanamh le a chuideachadh). Ach is urrainn dhuinn. A bharrachd air an sin, lorg mi agus sgrìobh mi sìos na mearachdan sin uile ann an aon fheasgar.
Ach thug sgrìobhadh an artaigil grunn sheachdainean. Cha b’ urrainn dhomh mi fhìn a thoirt leam airson seo uile a chuir ann an teacsa :).
Co-dhiù, ma tha ùidh agad anns na teicneòlasan a thathas a’ cleachdadh anns an anailisiche PVS-Studio gus mearachdan agus so-leòntachd a chomharrachadh, tha mi a’ moladh eòlas fhaighinn air an seo.
Diagnosachd ùr is sean
Mar a chaidh ainmeachadh cheana, timcheall air dà bhliadhna air ais chaidh am pròiseact LLVM a sgrùdadh a-rithist, agus chaidh na mearachdan a chaidh a lorg a cheartachadh. A-nis nochdaidh an artaigil seo baidse ùr de mhearachdan. Carson a chaidh biastagan ùra a lorg? Tha 3 adhbharan airson seo:
- Tha am pròiseact LLVM ag atharrachadh, ag atharrachadh seann chòd agus a’ cur còd ùr ris. Gu nàdarra, tha mearachdan ùra anns a’ chòd atharraichte agus sgrìobhte. Tha seo a’ sealltainn gu soilleir gum bu chòir mion-sgrùdadh statach a chleachdadh gu cunbhalach, agus chan ann bho àm gu àm. Tha na h-artaigilean againn a’ nochdadh gu math comasan an anailisiche PVS-Studio, ach chan eil gnothach aig seo ri bhith a’ leasachadh càileachd còd agus a’ lughdachadh cosgais mearachdan a chàradh. Cleachd anailisiche còd statach gu cunbhalach!
- Tha sinn a’ cur crìoch air agus ag adhartachadh diagnosachd gnàthaichte. Mar sin, faodaidh an anailisiche mearachdan a chomharrachadh nach do mhothaich e rè sganaidhean roimhe.
- Tha diagnosachd ùr air nochdadh ann am PVS-Studio nach robh ann o chionn 2 bhliadhna. Cho-dhùin mi an comharrachadh ann an earrann air leth gus leasachadh PVS-Studio a nochdadh gu soilleir.
Duilgheadasan air an comharrachadh le diagnosachd a bha ann o chionn 2 bhliadhna
Earrann 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
....
}
Rabhadh PVS-Studio:
Thathas a’ dèanamh sgrùdadh dùbailte air gu bheil an t-ainm a’ tòiseachadh leis an fho-earrann “avx512.mask.permvar.”. Anns an dàrna seic, bha e follaiseach gu robh iad airson rudeigin eile a sgrìobhadh, ach dhìochuimhnich iad an teacsa a chaidh a chopaigeadh a cheartachadh.
Earrann 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;
....
}
Rabhadh PVS-Studio: V501 Tha na h-aon fho-aithrisean 'CXNameRange_WantQualifier' air an taobh chlì agus air taobh deas an '|' gnìomhaiche. Cindex.cpp 7245
Air sgàth typo, bidh an aon sheasmhach ainmichte air a chleachdadh dà uair CXNameRange_WantQualifier.
Pàirt N3: Mì-chinnt le prìomhachas gnìomhaiche
int PPCTTIImpl::getVectorInstrCost(unsigned Opcode, Type *Val, unsigned Index) {
....
if (ISD == ISD::EXTRACT_VECTOR_ELT && Index == ST->isLittleEndian() ? 1 : 0)
return 0;
....
}
Rabhadh PVS-Studio:
Nam bheachd-sa, is e mearachd glè bhrèagha a tha seo. Tha, tha fios agam gu bheil beachdan neònach agam mu bhòidhchead :).
A-nis, a rèir
(ISD == ISD::EXTRACT_VECTOR_ELT && (Index == ST->isLittleEndian())) ? 1 : 0
Bho shealladh practaigeach, chan eil a leithid de staid a 'dèanamh ciall, oir faodar a lùghdachadh gu:
(ISD == ISD::EXTRACT_VECTOR_ELT && Index == ST->isLittleEndian())
Is e mearachd soilleir a tha seo. Nas coltaiche, bha iad airson coimeas a dhèanamh eadar 0/1 le caochladair Clàr-innse. Gus an còd a chàradh feumaidh tu bragan a chuir timcheall air a’ ghnìomhaiche ternary:
if (ISD == ISD::EXTRACT_VECTOR_ELT && Index == (ST->isLittleEndian() ? 1 : 0))
Air an t-slighe, tha an gnìomhaiche ternary gu math cunnartach agus a 'brosnachadh mhearachdan loidsigeach. Bi gu math faiceallach leis agus na bi sanntach le bragan. Thug mi sùil nas mionaidiche air a’ chuspair seo
Criomag N4, N5: Puing neonach
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;
}
....
}
Rabhadh PVS-Studio:
Ma tha am puing LHS tha e null, bu chòir rabhadh a thoirt seachad. Ach, an àite sin, thèid an aon phuing null seo a thoirt às: LHS-> getAsString().
Is e suidheachadh gu math àbhaisteach a tha seo nuair a tha mearachd falaichte ann an làimhseachadh mearachd, leis nach eil duine gan deuchainn. Bidh sgrùdairean statach a’ sgrùdadh a h-uile còd ruigsinneach, ge bith dè cho tric sa thèid a chleachdadh. Is e fìor dheagh eisimpleir a tha seo air mar a tha mion-sgrùdadh statach a’ cur ri dòighean deuchainn agus dìon mhearachdan eile.
Mearachd làimhseachaidh puing coltach ris RHS ceadaichte sa chòd dìreach gu h-ìosal: V522 [CWE-476] Dh’ fhaodadh gun tèid iomradh a thoirt air a’ phuing null ‘RHS’. TGParser.cpp 2186
Earrann N6: A’ cleachdadh a’ phuing às deidh gluasad
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);
}
....
}
Rabhadh PVS-Studio: V522 [CWE-476] Dh’ fhaodadh gun tèid iomradh a thoirt air a’ phuing null ‘ProgClone’. Miscompilation.cpp 601
Aig an toiseach inneal snasail ProgClone sguir e de shealbh an nì:
BD.setNewProgram(std::move(ProgClone));
Gu dearbh, a-nis ProgClone tha e na phuing null. Mar sin, bu chòir iomradh puing null a bhith ann dìreach gu h-ìosal:
Function *NewF = ProgClone->getFunction(MisCompFunctions[i].first);
Ach, ann an da-rìribh, cha tachair seo! Thoir an aire nach eil an lùb air a chuir gu bàs gu fìor.
Aig toiseach a 'chòmhdaich Gnìomhan Miscompiled air a ghlanadh:
MiscompiledFunctions.clear();
An ath rud, tha meud an t-soithich seo air a chleachdadh ann an staid lùb:
for (unsigned i = 0, e = MisCompFunctions.size(); i != e; ++i) {
Tha e furasta fhaicinn nach tòisich an lùb. Tha mi a’ smaoineachadh gur e bug a tha seo cuideachd agus bu chòir an còd a sgrìobhadh ann an dòigh eadar-dhealaichte.
Tha e coltach gun do thachair sinn ris a’ cho-ionannachd mhearachdan ainmeil sin! Tha aon mhearachd a' falach fear eile :).
Earrann N7: A’ cleachdadh a’ phuing às deidh gluasad
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;
}
....
}
Rabhadh PVS-Studio: V522 [CWE-476] Dh’ fhaodadh gun tèid iomradh a thoirt air a’ phuing null ‘Deuchainn’. Miscompilation.cpp 709
An aon suidheachadh a-rithist. An toiseach, tha susbaint an nì air a ghluasad, agus an uairsin tha e air a chleachdadh mar gum biodh dad air tachairt. Bidh mi a’ faicinn an t-suidheachaidh seo barrachd is nas trice ann an còd prògram às deidh dha semantics gluasaid nochdadh ann an C ++. Sin as coireach gu bheil gaol agam air a’ chànan C ++! Tha barrachd is barrachd dhòighean ùra ann airson do chas fhèin a chuir dheth. Bidh obair an-còmhnaidh aig an anailisiche PVS-Studio :).
Earrann N8: Puing neonach
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);
}
Rabhadh PVS-Studio: V522 [CWE-476] Dh’ fhaodadh gun tèid iomradh a thoirt air a’ phuing null ‘Type’. PrettyFunctionDumper.cpp 233
A bharrachd air làimhseachadh mhearachdan, mar as trice cha bhithear a’ dèanamh deuchainn air gnìomhan clò-bhualaidh deasbaid. Tha dìreach a leithid de chùis againn air thoiseach oirnn. Tha an gnìomh a 'feitheamh ris an neach-cleachdaidh, a dh' fheumas, an àite a bhith a 'fuasgladh nan duilgheadasan aige, a chàradh.
Ceart:
if (Type)
Type->dump(*this);
else
Printer << "<unknown-type>";
Earrann N9: Puing neonach
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());
....
}
Rabhadh PVS-Studio: V522 [CWE-476] Dh’ fhaodadh gun tèid iomradh a thoirt air a’ phuing null ‘Ty’. SearchableTableEmitter.cpp 614
Tha mi a’ smaoineachadh gu bheil a h-uile dad soilleir agus nach eil feum air mìneachadh.
Earrann 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;
}
Rabhadh PVS-Studio:
Chan eil feum air caochladair a shònrachadh dha fhèin. Is dòcha gu robh iad airson sgrìobhadh:
Identifier->Type = Question->Type;
Earrann N11: Briseadh amharasach
void SystemZOperand::print(raw_ostream &OS) const {
switch (Kind) {
break;
case KindToken:
OS << "Token:" << getToken();
break;
case KindReg:
OS << "Reg:" << SystemZInstPrinter::getRegisterName(getReg());
break;
....
}
Rabhadh PVS-Studio:
Tha gnìomhaiche gu math amharasach aig an toiseach fois. An do dhìochuimhnich thu rudeigin eile a sgrìobhadh an seo?
Earrann N12: A' sgrùdadh comharraiche an dèidh iomradh a thoirt air
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");
....
}
Rabhadh PVS-Studio:
Pointer Callee aig an toiseach tha dereferenced aig an àm ris an canar an gnìomh faighTTI.
Agus an uairsin tha e a 'tionndadh a-mach gum bu chòir an comharra seo a bhith air a sgrùdadh airson co-ionannachd nullptr:
if (!Callee || Callee->isDeclaration())
Ach tha e ro fhadalach…
Earrann N13 - N...: A’ sgrùdadh comharraiche às deidh dhut iomradh a thoirt air
Chan eil an suidheachadh a chaidh a dheasbad anns a’ chriomag còd roimhe gun samhail. Tha e a’ nochdadh an seo:
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()) { // <=
....
}
Rabhadh PVS-Studio: V595 [CWE-476] Chaidh am puing ‘CalleeFn’ a chleachdadh mus deach a dhearbhadh an aghaidh nullptr. Loidhnichean sgrùdaidh: 1079, 1081. SimplifyLibCalls.cpp 1079
Agus an seo:
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()); // <=
....
}
Rabhadh PVS-Studio: V595 [CWE-476] Chaidh am puing ‘ND’ a chleachdadh mus deach a dhearbhadh an aghaidh nullptr. Loidhne-sgrùdaidh: 532, 534. SemaTemplateInstantiateDecl.cpp 532
Agus an seo:
- V595 [CWE-476] Chaidh am puing 'U' a chleachdadh mus deach a dhearbhadh an aghaidh nullptr. Loidhnichean sgrùdaidh: 404, 407. DWARFormValue.cpp 404
- V595 [CWE-476] Chaidh am puing 'ND' a chleachdadh mus deach a dhearbhadh an aghaidh nullptr. Loidhnichean sgrùdaidh: 2149, 2151. SemaTemplateInstantiate.cpp 2149
Agus an uairsin dh’ fhàs mi gun ùidh ann a bhith a’ sgrùdadh nan rabhaidhean leis an àireamh V595. Mar sin chan eil fios agam a bheil barrachd mhearachdan coltach ris a bharrachd air an fheadhainn a tha air an liostadh an seo. As dualtaiche gu bheil.
Earrann N17, N18: Gluasad amharasach
static inline bool processLogicalImmediate(uint64_t Imm, unsigned RegSize,
uint64_t &Encoding) {
....
unsigned Size = RegSize;
....
uint64_t NImms = ~(Size-1) << 1;
....
}
Rabhadh PVS-Studio:
Is dòcha nach e biast a th’ ann agus tha an còd ag obair dìreach mar a bha dùil. Ach tha e soilleir gur e àite gu math amharasach a tha seo agus feumar sgrùdadh a dhèanamh air.
Canaidh sinn an caochlaideach meud co-ionann ri 16, agus an uairsin bha ùghdar a’ chòd an dùil a thoirt ann an caochladair NImms luach:
1111111111111111111111111111111111111111111111111111111111100000
Ach, ann an da-rìribh bidh an toradh:
0000000000000000000000000000000011111111111111111111111111100000
Is e an fhìrinn gu bheil a h-uile àireamhachadh a ’tachairt a’ cleachdadh an seòrsa 32-bit gun ainm. Agus dìreach an uairsin, thèid an seòrsa 32-bit seo gun ainm a leudachadh gu h-obann uint64_t. Anns a 'chùis seo, bidh na pìosan as cudromaiche neoni.
Faodaidh tu an suidheachadh a cheartachadh mar seo:
uint64_t NImms = ~static_cast<uint64_t>(Size-1) << 1;
Suidheachadh coltach ris: V629 [CWE-190] Beachdaich air an abairt 'Immr << 6' a sgrùdadh. Gluasad beag den luach 32-bit le leudachadh às deidh sin chun t-seòrsa 64-bit. AArch64AddressingModes.h 269
Earrann N19: Facal-luirg a dhìth eile?
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");
}
....
}
Rabhadh PVS-Studio:
Chan eil mearachd an seo. Bhon uairsin - bloc a 'chiad fhear if a' crìochnachadh le leantainn air adhart, an uairsin chan eil e gu diofar, tha prìomh fhacal ann eile no nach eil. Co-dhiù, obraichidh an còd mar an ceudna. Fhathast air chall eile a’ dèanamh a’ chòd nas neo-shoilleir agus cunnartach. Ma tha san àm ri teachd leantainn air adhart à sealladh, tòisichidh an còd ag obair gu tur eadar-dhealaichte. Na mo bheachd-sa tha e nas fheàrr a chur ris eile.
Earrann N20: Ceithir typos den aon sheòrsa
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;
}
Rabhaidhean PVS-Studio:
- V655 [CWE-480] Chaidh na teudan a cheangal ach chan eilear gan cleachdadh. Beachdaich air sgrùdadh a dhèanamh air an abairt 'Toradh + Name.str()'. samhla.cpp 32
- V655 [CWE-480] Chaidh na teudan a cheangal ach chan eilear gan cleachdadh. Beachdaich air sgrùdadh a dhèanamh air an abairt 'Toraidh + "(Clas ObjC)" + Name.str()'. samhla.cpp 35
- V655 [CWE-480] Chaidh na teudan a cheangal ach chan eilear gan cleachdadh. Beachdaich air sgrùdadh a dhèanamh air an abairt 'Toradh + "(ObjC Class EH)" + Name.str()'. samhla.cpp 38
- V655 [CWE-480] Chaidh na teudan a cheangal ach chan eilear gan cleachdadh. Beachdaich air sgrùdadh a dhèanamh air an abairt 'Toradh + "(ObjC IVar)" + Name.str()'. samhla.cpp 41
Le tubaist, thèid an gnìomhaiche + a chleachdadh an àite a’ ghnìomhaiche +=. Is e an toradh dealbhadh gun chiall.
Earrann N21: Giùlan neo-mhìnichte
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();
}
}
}
Feuch an lorg thu an còd cunnartach thu fhèin. Agus is e seo dealbh airson aire a tharraing gus nach coimhead thu sa bhad air an fhreagairt:
Rabhadh PVS-Studio:
Loidhne duilgheadas:
FeaturesMap[Op] = FeaturesMap.size();
Ma tha eileamaid Op Chan eil lorg, an uairsin tha eileamaid ùr air a chruthachadh sa mhapa agus tha an àireamh de eileamaidean sa mhapa seo sgrìobhte an sin. Chan eil fios an tèid an gnìomh a ghairm meud ro no às deidh eileamaid ùr a chur ris.
Earrann N22-N24: Sònrachaidhean a-rithist
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;
}
....
}
Rabhadh PVS-Studio:
Chan eil mi a’ smaoineachadh gu bheil fìor mhearachd an seo. Dìreach obair neo-riatanach a-rithist. Ach fhathast blunder.
Mar an ceudna:
- V519 [CWE-563] Tha an caochladair 'B.NDesc' air a shònrachadh luachan dà uair an dèidh a chèile. Is dòcha gur e mearachd a tha seo. Loidhne-sgrùdaidh: 1488, 1489. llvm-nm.cpp 1489
- V519 [CWE-563] Tha an caochladair air luachan a shònrachadh dà uair às deidh a chèile. Is dòcha gur e mearachd a tha seo. Thoir sùil air loidhnichean: 59, 61. coff2yaml.cpp 61
Earrann N25-N27: Barrachd ath-shònrachaidhean
A-nis leig dhuinn sùil a thoirt air dreach beagan eadar-dhealaichte de ath-shònrachadh.
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;
....
}
Rabhadh PVS-Studio: V519 [CWE-563] Tha an caochladair 'Co-thaobhadh' air a shònrachadh dà uair an dèidh a chèile. Is dòcha gur e mearachd a tha seo. Loidhnichean sgrùdaidh: 1158, 1160. LoadStoreVectorizer.cpp 1160
Is e còd gu math neònach a tha seo a tha coltach gu bheil mearachd loidsigeach ann. Aig an toiseach, caochlaideach Co-thaobhadh tha luach air a shònrachadh a rèir an t-suidheachaidh. Agus an uairsin bidh an obair a 'tachairt a-rithist, ach a-nis gun sgrùdadh sam bith.
Chithear suidheachaidhean coltach ris an seo:
- V519 [CWE-563] Tha an caochladair ‘Effects’ air a shònrachadh luachan dà uair às deidh a chèile. Is dòcha gur e mearachd a tha seo. Loidhne-sgrùdaidh: 152, 165. WebAssemblyRegStackify.cpp 165
- V519 [CWE-563] Tha an caochladair ‘ExpectNoDerefChunk’ air luachan a shònrachadh dà uair às deidh a chèile. Is dòcha gur e mearachd a tha seo. Loidhnichean sgrùdaidh: 4970, 4973. SemaType.cpp 4973
Earrann N28: An-còmhnaidh fìor staid
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;
}
....
}
Rabhadh PVS-Studio:
Chan eil sgrùdadh a’ dèanamh ciall. Caochlaideach athBite an-còmhnaidh nach eil co-ionann ris an luach 0x90, a tha a’ leantainn bhon t-seic roimhe. Is e seo seòrsa de mhearachd loidsigeach.
Earrann N29 - N...: An-còmhnaidh fìor / ceàrr
Bidh an anailisiche a’ toirt a-mach mòran rabhaidhean gu bheil an suidheachadh gu lèir (
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;
....
}
Rabhadh PVS-Studio:
Is e an seasmhach 0xE an luach 14 ann an deicheach. Sgrùdadh Reg Chan eil == 0xe chan eil e ciallach oir ma tha Riaghailt > 13, an uairsin cuiridh an gnìomh crìoch air a chur gu bàs.
Bha mòran rabhaidhean eile ann le IDan V547 agus V560, ach mar le
Bheir mi eisimpleir dhut air carson a tha sgrùdadh air na brosnachaidhean sin dòrainneach. Tha an anailisiche gu tur ceart ann a bhith a’ toirt seachad rabhadh airson a’ chòd a leanas. Ach chan e mearachd a tha seo.
bool UnwrappedLineParser::parseBracedList(bool ContinueOnSemicolons,
tok::TokenKind ClosingBraceKind) {
bool HasError = false;
....
HasError = true;
if (!ContinueOnSemicolons)
return !HasError;
....
}
Rabhadh PVS-Studio: V547 [CWE-570] Tha abairt ‘! HasError’ an-còmhnaidh meallta. Loidhne Parser.cpp 1635
Fragment N30: Tilleadh amharasach
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();
}
....
}
Rabhadh PVS-Studio:
Is e mearachd a tha seo no dòigh sònraichte a thathar an dùil rudeigin a mhìneachadh do luchd-prògramaidh a tha a’ leughadh a’ chòd. Chan eil an dealbhadh seo a’ mìneachadh dad dhomh agus tha e a’ coimhead gu math amharasach. Tha e nas fheàrr gun a bhith a’ sgrìobhadh mar sin :).
Sgìthichte? An uairsin tha an t-àm ann tì no cofaidh a dhèanamh.
Duilgheadasan air an comharrachadh le diagnosachd ùr
Tha mi a’ smaoineachadh gu bheil 30 gnìomh de sheann diagnosachd gu leòr. Chì sinn a-nis dè na rudan inntinneach a lorgar leis na diagnosachd ùr a nochd san anailisiche às deidh sin
Earrann N31: Còd nach gabh a ruighinn
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();
}
Rabhadh PVS-Studio:
Mar a chì thu, an dà mheur den ghnìomhaiche if a’ crìochnachadh le fios chun ghnìomhaiche air ais. A rèir sin, an container CtorDtorsLe prìomhachas cha tèid a ghlanadh gu bràth.
Earrann N32: Còd nach gabh a ruighinn
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;
}
Rabhadh PVS-Studio: V779 [CWE-561] Còd nach gabh ruighinn air a lorg. Tha e comasach gu bheil mearachd an làthair. LLParser.cpp 835
Suidheachadh inntinneach. Bheir sinn sùil air an àite seo an toiseach:
return ParseTypeIdEntry(SummaryID);
break;
Aig a 'chiad sealladh, tha e coltach nach eil mearachd an seo. Tha e coltach ris a’ ghnìomhaiche fois tha fear a bharrachd an seo, agus faodaidh tu dìreach a sguabadh às. Ach, chan eil a h-uile cho sìmplidh.
Bidh an anailisiche a’ toirt seachad rabhadh air na loidhnichean:
Lex.setIgnoreColonInIdentifiers(false);
return false;
Agus gu dearbh, chan eil an còd seo ruigsinneach. A h-uile cùis ann an suidse a’ crìochnachadh le fios bhon ghnìomhaiche air ais. Agus a-nis gun chiall leis fhèin fois chan eil e a’ coimhead cho gun chron! Is dòcha gum bu chòir aon de na meuran crìochnachadh le foischan ann air adhart air ais?
Pàirt N33: Ath-shuidheachadh air thuaiream de bhuillean àrda
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);
....
}
Rabhadh PVS-Studio:
Thoir an aire gu bheil an gnìomh faighStubAlignment seòrsa tilleadh gun ainm. Feuch an obraich sinn a-mach luach an abairt, a’ gabhail ris gu bheil an gnìomh a’ tilleadh an luach 8:
~ (getStubAlignment() - 1)
~(8u-1)
0xFFFFFFFF8u
A-nis mothaich gu bheil an caochlaideach Meud dàta tha seòrsa 64-bit gun ainm aige. Tha e a’ tionndadh a-mach, nuair a bhios tu a’ coileanadh gnìomhachd DataSize & 0xFFFFFFF8u, gun tèid na trithead ’s a dhà pìosan àrd-òrdugh ath-shuidheachadh gu neoni. Nas coltaiche, chan e seo a bha am prògramadair ag iarraidh. Tha amharas agam gu robh e airson obrachadh a-mach: DataSize & 0xFFFFFFFFFFFFFF8u.
Gus a’ mhearachd a cheartachadh, bu chòir dhut seo a sgrìobhadh:
DataSize &= ~(static_cast<uint64_t>(getStubAlignment()) - 1);
No mar sin:
DataSize &= ~(getStubAlignment() - 1ULL);
Earrann N34: Dh’ fhàillig seòrsa de sheòrsa sònraichte
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);
....
}
Rabhadh PVS-Studio:
Thathas a’ cleachdadh tilgeadh seòrsa sònraichte gus cus sruthadh a sheachnadh nuair a thathar ag iomadachadh caochladairean seòrsa int. Ach, chan eil tilgeadh seòrsa soilleir an seo a’ dìon an aghaidh thar-shruth. An toiseach, thèid na caochladairean iomadachadh, agus dìreach an uairsin thèid toradh 32-bit an iomadachaidh a leudachadh chun t-seòrsa
Earrann N35: Leth-bhreac air fàiligeadh
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;
}
....
}
Tha am breithneachadh inntinneach ùr seo a’ comharrachadh shuidheachaidhean far an deach pìos còd a chopaigeadh agus cuid de na h-ainmean a th’ ann air tòiseachadh air atharrachadh, ach ann an aon àite chan eil iad air a cheartachadh.
Thoir an aire gun do dh'atharraich iad san dàrna bloc Air 0 air Air 1. Ach ann an aon àite cha do shocraich iad e. Is coltaiche gum bu chòir a bhith air a sgrìobhadh mar seo:
if (!match(Op1, m_PosZeroFP()) && isKnownNeverNaN(Op1, &TLI)) {
I.setOperand(1, ConstantFP::getNullValue(Op1->getType()));
return &I;
}
Earrann N36: Mì-chinnt caochlaideach
struct Status {
unsigned Mask;
unsigned Mode;
Status() : Mask(0), Mode(0){};
Status(unsigned Mask, unsigned Mode) : Mask(Mask), Mode(Mode) {
Mode &= Mask;
};
....
};
Rabhadh PVS-Studio:
Tha e glè chunnartach na h-aon ainmean a thoirt do bhuill a’ chlas air argamaidean gnìomh. Tha e gu math furasta a bhith troimh-chèile. Tha dìreach a leithid de chùis againn air thoiseach oirnn. Chan eil an abairt seo a’ dèanamh ciall:
Mode &= Mask;
Bidh an argamaid gnìomh ag atharrachadh. Sin e. Chan eil an argamaid seo air a chleachdadh tuilleadh. Is dòcha gum bu chòir dhut a bhith air a sgrìobhadh mar seo:
Status(unsigned Mask, unsigned Mode) : Mask(Mask), Mode(Mode) {
this->Mode &= Mask;
};
Earrann N37: Mì-chinnt caochlaideach
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;
}
Rabhadh PVS-Studio: V1001 [CWE-563] Tha an caochladair 'Meud' air a shònrachadh ach chan eil e air a chleachdadh ro dheireadh a 'ghnìomh. Rud.cpp 424
Tha an suidheachadh coltach ris an fhear roimhe. Bu chòir a sgrìobhadh:
this->Size += this->EntrySize;
Criomag N38-N47: Dhìochuimhnich iad sgrùdadh a dhèanamh air a’ chlàr-amais
Roimhe seo, thug sinn sùil air eisimpleirean de bhrosnachadh breithneachaidh
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()); // <=
....
}
Rabhadh PVS-Studio: V1004 [CWE-476] Chaidh am puing ‘Ptr’ a chleachdadh gu mì-shàbhailte às deidh dha a bhith air a dhearbhadh an aghaidh nullptr. Loidhnichean sgrùdaidh: 729, 738. TargetTransformInfoImpl.h 738
Caochlaideach Ptr faodaidh e bhith co-ionnan nullptr, mar a chithear leis an t-seic:
if (Ptr != nullptr)
Ach, gu h-ìosal tha an comharra seo air a chuir dheth gun sgrùdadh tòiseachaidh:
auto PtrSizeBits = DL.getPointerTypeSizeInBits(Ptr->getType());
Beachdaichidh sinn air cùis eile den aon seòrsa.
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(); // <=
....
}
Rabhadh PVS-Studio: V1004 [CWE-476] Chaidh am puing ‘FD’ a chleachdadh gu mì-shàbhailte às deidh dha a bhith air a dhearbhadh an aghaidh nullptr. Loidhnichean sgrùdaidh: 3228, 3231. CGDebugInfo.cpp 3231
Thoir aire don t-soidhne FD. Tha mi cinnteach gu bheil an duilgheadas ri fhaicinn gu soilleir agus nach eil feum air mìneachadh sònraichte.
Agus a bharrachd:
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()); // <=
....
}
Rabhadh PVS-Studio: V1004 [CWE-476] Chaidh am puing ‘PtrTy’ a chleachdadh gu mì-shàbhailte às deidh dha a bhith air a dhearbhadh an aghaidh nullptr. Loidhnichean sgrùdaidh: 960, 965. InterleavedLoadCombinePass.cpp 965
Ciamar thu fhèin a dhìon bho mhearachdan mar sin? Bi nas furachail air Còd-Lèirmheas agus cleachd an anailisiche statach PVS-Studio gus do chòd a sgrùdadh gu cunbhalach.
Chan eil adhbhar ann a bhith ag ainmeachadh criomagan còd eile le mearachdan den t-seòrsa seo. Chan fhàg mi ach liosta de rabhaidhean san artaigil:
- V1004 [CWE-476] Chaidh am puing ‘Expr’ a chleachdadh gu mì-shàbhailte às deidh dha a bhith air a dhearbhadh an aghaidh nullptr. Loidhnichean sgrùdaidh: 1049, 1078. DebugInfoMetadata.cpp 1078
- V1004 [CWE-476] Chaidh am puing ‘PI’ a chleachdadh gu mì-shàbhailte às deidh dha a bhith air a dhearbhadh an aghaidh nullptr. Loidhnichean sgrùdaidh: 733, 753. LegacyPassManager.cpp 753
- V1004 [CWE-476] Chaidh am puing ‘StatepointCall’ a chleachdadh gu mì-shàbhailte às deidh dha a bhith air a dhearbhadh an aghaidh nullptr. Loidhnichean sgrùdaidh: 4371, 4379. Verifier.cpp 4379
- V1004 [CWE-476] Chaidh am puing ‘RV’ a chleachdadh gu mì-shàbhailte às deidh dha a bhith air a dhearbhadh an aghaidh nullptr. Loidhnichean sgrùdaidh: 2263, 2268. TGParser.cpp 2268
- V1004 [CWE-476] Chaidh am puing ‘CalleeFn’ a chleachdadh gu mì-shàbhailte às deidh dha a bhith air a dhearbhadh an aghaidh nullptr. Loidhne-sgrùdaidh: 1081, 1096. SimplifyLibCalls.cpp 1096
- V1004 [CWE-476] Chaidh am puing ‘TC’ a chleachdadh gu mì-shàbhailte às deidh dha a bhith air a dhearbhadh an aghaidh nullptr. Loidhnichean seic: 1819, 1824. Driver.cpp 1824
Criomag N48-N60: Chan eil e riatanach, ach uireasbhaidh (aodion cuimhne comasach)
std::unique_ptr<IRMutator> createISelMutator() {
....
std::vector<std::unique_ptr<IRMutationStrategy>> Strategies;
Strategies.emplace_back(
new InjectorIRStrategy(InjectorIRStrategy::getDefaultOps()));
....
}
Rabhadh PVS-Studio:
Gus eileamaid a chur ri deireadh container mar std::vector > chan urrainn dhut dìreach sgrìobhadh xxx.push_back(X ùr), leis nach eil tionndadh follaiseach ann bho X* в std::unique_ptr.
Is e fuasgladh cumanta sgrìobhadh xxx.emplace_back(X ùr)oir tha e a 'cur ri chèile: modh àite_cùl a’ togail eileamaid gu dìreach bho na h-argamaidean aige agus mar sin faodaidh iad luchd-togail soilleir a chleachdadh.
Chan eil e sàbhailte. Ma tha an vectar làn, thèid cuimhne ath-riarachadh. Dh’ fhaodadh gun fàillig an obair ath-riarachadh cuimhne, agus mar thoradh air an sin thèid eisgeachd a thilgeil std :: bad_alloc. Anns a 'chùis seo, thèid am puing a chall agus cha tèid an rud a chaidh a chruthachadh a dhubhadh às gu bràth.
Is e fuasgladh sàbhailte a chruthachadh gun samhail_ptraig am bi sealbh air a’ phuing mus feuchaidh an vectar ri cuimhne ath-riarachadh:
xxx.push_back(std::unique_ptr<X>(new X))
Bho C ++14, faodaidh tu 'std :: make_unique' a chleachdadh:
xxx.push_back(std::make_unique<X>())
Chan eil an seòrsa uireasbhaidh seo deatamach airson LLVM. Mura h-urrainnear cuimhne a thoirt seachad, stadaidh an t-inneal-cruinneachaidh. Ach, airson iarrtasan le fada
Mar sin, ged nach eil an còd seo na chunnart practaigeach do LLVM, bha e feumail dhomh bruidhinn mun phàtran mearachd seo agus gu bheil an anailisiche PVS-Studio air ionnsachadh a chomharrachadh.
Rabhaidhean eile den t-seòrsa seo:
- V1023 [CWE-460] Thathas a’ cur puing gun shealbhadair ris a’ bhogsa ‘Passes’ leis an dòigh ‘emplace_back’. Bidh aodion cuimhne a’ tachairt gun fhios nach bi eisgeachd ann. Manaidsear-siubhail.h 546
- V1023 [CWE-460] Thathas a’ cur puing gun shealbhadair ris a’ ghobhar ‘AAs’ leis an dòigh ‘emplace_back’. Bidh aodion cuimhne a’ tachairt gun fhios nach bi eisgeachd ann. AliasAnailis.h 324
- V1023 [CWE-460] Thathas a’ cur puing gun shealbhadair ris a’ bhogsa ‘Entries’ leis an dòigh ‘emplace_back’. Bidh aodion cuimhne a’ tachairt gun fhios nach bi eisgeachd ann. DWARFDebugFrame.cpp 519
- V1023 [CWE-460] Thathas a’ cur puing gun shealbhadair ris a’ bhogsa ‘AllEdges’ leis an dòigh ‘emplace_back’. Bidh aodion cuimhne a’ tachairt gun fhios nach bi eisgeachd ann. CFGMST.h 268
- V1023 [CWE-460] Thathas a’ cur puing gun shealbhadair ris a’ bhogsa ‘VMaps’ leis an dòigh ‘emplace_back’. Bidh aodion cuimhne a’ tachairt gun fhios nach bi eisgeachd ann. SimpleLoopUnswitch.cpp 2012
- V1023 [CWE-460] Thathas a’ cur puing gun shealbhadair ris a’ bhogsa ‘Records’ leis an dòigh ‘emplace_back’. Bidh aodion cuimhne a’ tachairt gun fhios nach bi eisgeachd ann. FDRLogBuilder.h 30
- V1023 [CWE-460] Tha comharraiche gun sealbhadair air a chur ris a’ ghobhar ‘PendingSubmodules’ leis an dòigh ‘emplace_back’. Bidh aodion cuimhne a’ tachairt gun fhios nach bi eisgeachd ann. ModuleMap.cpp 810
- V1023 [CWE-460] Thathas a’ cur puing às aonais sealbhadair ris a’ bhogsa ‘Objects’ leis an dòigh ‘emplace_back’. Bidh aodion cuimhne a’ tachairt gun fhios nach bi eisgeachd ann. DebugMap.cpp 88
- V1023 [CWE-460] Tha comharraiche gun sealbhadair air a chur ris a’ bhogsa ‘Ro-innleachdan’ leis an dòigh ‘emplace_back’. Bidh aodion cuimhne a’ tachairt gun fhios nach bi eisgeachd ann. llvm-isel-fuzzer.cpp 60
- V1023 [CWE-460] Thathas a’ cur puing gun sealbhadair ris a’ bhogsa ‘Modifiers’ leis an dòigh ‘emplace_back’. Bidh aodion cuimhne a’ tachairt gun fhios nach bi eisgeachd ann. llvm-cuideam.cpp 685
- V1023 [CWE-460] Thathas a’ cur puing gun sealbhadair ris a’ bhogsa ‘Modifiers’ leis an dòigh ‘emplace_back’. Bidh aodion cuimhne a’ tachairt gun fhios nach bi eisgeachd ann. llvm-cuideam.cpp 686
- V1023 [CWE-460] Thathas a’ cur puing gun sealbhadair ris a’ bhogsa ‘Modifiers’ leis an dòigh ‘emplace_back’. Bidh aodion cuimhne a’ tachairt gun fhios nach bi eisgeachd ann. llvm-cuideam.cpp 688
- V1023 [CWE-460] Thathas a’ cur puing gun sealbhadair ris a’ bhogsa ‘Modifiers’ leis an dòigh ‘emplace_back’. Bidh aodion cuimhne a’ tachairt gun fhios nach bi eisgeachd ann. llvm-cuideam.cpp 689
- V1023 [CWE-460] Thathas a’ cur puing gun sealbhadair ris a’ bhogsa ‘Modifiers’ leis an dòigh ‘emplace_back’. Bidh aodion cuimhne a’ tachairt gun fhios nach bi eisgeachd ann. llvm-cuideam.cpp 690
- V1023 [CWE-460] Thathas a’ cur puing gun sealbhadair ris a’ bhogsa ‘Modifiers’ leis an dòigh ‘emplace_back’. Bidh aodion cuimhne a’ tachairt gun fhios nach bi eisgeachd ann. llvm-cuideam.cpp 691
- V1023 [CWE-460] Thathas a’ cur puing gun sealbhadair ris a’ bhogsa ‘Modifiers’ leis an dòigh ‘emplace_back’. Bidh aodion cuimhne a’ tachairt gun fhios nach bi eisgeachd ann. llvm-cuideam.cpp 692
- V1023 [CWE-460] Thathas a’ cur puing gun sealbhadair ris a’ bhogsa ‘Modifiers’ leis an dòigh ‘emplace_back’. Bidh aodion cuimhne a’ tachairt gun fhios nach bi eisgeachd ann. llvm-cuideam.cpp 693
- V1023 [CWE-460] Thathas a’ cur puing gun sealbhadair ris a’ bhogsa ‘Modifiers’ leis an dòigh ‘emplace_back’. Bidh aodion cuimhne a’ tachairt gun fhios nach bi eisgeachd ann. llvm-cuideam.cpp 694
- V1023 [CWE-460] Thathas a’ cur puing gun shealbhadair ris a’ bhogsa ‘Operands’ leis an dòigh ‘emplace_back’. Bidh aodion cuimhne a’ tachairt gun fhios nach bi eisgeachd ann. GlobalISelEmitter.cpp 1911
- V1023 [CWE-460] Thathas a’ cur puing às aonais sealbhadair ris a’ bhogsa ‘Stash’ leis an dòigh ‘emplace_back’. Bidh aodion cuimhne a’ tachairt gun fhios nach bi eisgeachd ann. GlobalISelEmitter.cpp 2100
- V1023 [CWE-460] Thathas a’ cur puing gun shealbhadair ris a’ bhogsa ‘Matchers’ leis an dòigh ‘emplace_back’. Bidh aodion cuimhne a’ tachairt gun fhios nach bi eisgeachd ann. GlobalISelEmitter.cpp 2702
co-dhùnadh
Chuir mi a-mach 60 rabhadh gu h-iomlan agus an uairsin stad mi. A bheil uireasbhaidhean eile ann a lorgas an anailisiche PVS-Studio ann an LLVM? Tha, tha agam. Ach, nuair a bha mi a 'sgrìobhadh criomagan còd airson an artaigil, b' e deireadh an fheasgair a bh 'ann, no eadhon oidhche, agus cho-dhùin mi gu robh an t-àm ann latha a ghairm.
Tha mi an dòchas gun robh e inntinneach dhut agus gum bi thu airson an anailisiche PVS-Studio fheuchainn.
Faodaidh tu an anailisiche a luchdachadh sìos agus an iuchair minesweeper fhaighinn aig
Nas cudromaiche, cleachd mion-sgrùdadh statach gu cunbhalach. Sgrùdaidhean aon-ùine, air a dhèanamh leinn gus an dòigh-obrach airson mion-sgrùdadh statach agus PVS-Studio a chleachdadh mar shuidheachadh àbhaisteach.
Math fortanach ann a bhith ag adhartachadh càileachd agus earbsachd do chòd!
Ma tha thu airson an artaigil seo a cho-roinn le luchd-èisteachd Beurla, cleachd an ceangal eadar-theangachaidh: Andrey Karpov.
Source: www.habr.com