PVS-Studio ๋ถ์๊ธฐ๋ฅผ ์ฌ์ฉํ LLVM ํ๋ก์ ํธ์ ๋ง์ง๋ง ์ฝ๋ ๊ฒ์ฌ ์ดํ 8.0.0๋
์ด์์ด ์ง๋ฌ์ต๋๋ค. PVS-Studio ๋ถ์๊ธฐ๊ฐ ์ฌ์ ํ ์ค๋ฅ์ ์ ์ฌ์ ์ธ ์ทจ์ฝ์ ์ ์๋ณํ๋ ์ต๊ณ ์ ๋๊ตฌ์ธ์ง ํ์ธํ๊ฒ ์ต๋๋ค. ์ด๋ฅผ ์ํด LLVM XNUMX ๋ฆด๋ฆฌ์ค์์ ์๋ก์ด ์ค๋ฅ๋ฅผ ํ์ธํ๊ณ ์ฐพ์๋ณด๊ฒ ์ต๋๋ค.
์์ฑํด์ผ ํ ๊ธฐ์ฌ
์์งํ ๋งํด์ ๋๋ ์ด ๊ธ์ ์ฐ๊ณ ์ถ์ง ์์๋ค. ์ด๋ฏธ ์ฌ๋ฌ ๋ฒ ํ์ธํ ํ๋ก์ ํธ์ ๋ํด ๊ธ์ ์ฐ๋ ๊ฒ์ ํฅ๋ฏธ๋กญ์ง ์์ต๋๋ค(
LLVM์ ์ ๋ฒ์ ์ด ์ถ์๋๊ฑฐ๋ ์
๋ฐ์ดํธ๋ ๋๋ง๋ค
๋ณด์ธ์, Clang ์ ์ ๋ถ์๊ธฐ์ ์ ๋ฒ์ ์์๋ ์๋ก์ด ์ค๋ฅ๋ฅผ ์ฐพ๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์ ์ต๋๋ค! PVS-Studio ์ฌ์ฉ์ ๊ด๋ จ์ฑ์ด ๊ฐ์ํ๊ณ ์๋ ๊ฒ ๊ฐ์ต๋๋ค. Clang์ ์ด์ ๋ณด๋ค ๋ ๋ง์ ์ค๋ฅ๋ฅผ ๋ฐ๊ฒฌํ๊ณ PVS-Studio์ ๊ธฐ๋ฅ์ ๋ฐ๋ผ์ก์ต๋๋ค. ์ด๊ฒ์ ๋ํด ์ด๋ป๊ฒ ์๊ฐํ์ธ์?
์ด์ ๋ํด ์ ๋ ํญ์ ๋ค์๊ณผ ๊ฐ์ด ๋๋ตํ๊ณ ์ถ์ต๋๋ค.
์ฐ๋ฆฌ๋ ํ๊ฐ๋ก์ด ์์ ์์ง ์์ต๋๋ค! PVS-Studio ๋ถ์๊ธฐ์ ๊ธฐ๋ฅ์ด ํฌ๊ฒ ํฅ์๋์์ต๋๋ค. ๊ทธ๋ฌ๋ ๊ฑฑ์ ํ์ง ๋ง์ธ์. ์ฐ๋ฆฌ๋ ์ด์ ์ฒ๋ผ ๊ณ์ํด์ ์ด๋์ด ๊ฐ ๊ฒ์ ๋๋ค.
๋ถํํ๋ ์ด๊ฒ์ ์๋ชป๋ ๋๋ต์ ๋๋ค. ๊ฑฐ๊ธฐ์๋ ์ฆ๊ฑฐ๊ฐ ์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ๊ทธ๊ฒ์ด ๋ฐ๋ก ๋ด๊ฐ ์ง๊ธ ์ด ๊ธ์ ์ฐ๊ณ ์๋ ์ด์ ์ด๋ค. ๊ทธ๋์ LLVM ํ๋ก์ ํธ๋ฅผ ๋ค์ ํ๋ฒ ํ์ธํด ๋ณด๋ ๋ค์ํ ์ค๋ฅ๊ฐ ๋ฐ๊ฒฌ๋์์ต๋๋ค. ์ด์ ๋์๊ฒ ํฅ๋ฏธ๋ก์ ๋ ๊ฒ๋ค์ ๋ณด์ฌ ๋๋ฆฌ๊ฒ ์ต๋๋ค. Clang ์ ์ ๋ถ์๊ธฐ๋ ์ด๋ฌํ ์ค๋ฅ๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค(๋๋ Clang์ ๋์์ ๋ฐ์ ์ด๋ฅผ ์ฐพ๋ ๊ฒ์ด ๋งค์ฐ ๋ถํธํฉ๋๋ค). ํ์ง๋ง ์ฐ๋ฆฌ๋ ํ ์ ์์ต๋๋ค. ๊ฒ๋ค๊ฐ ๋๋ ์ด ๋ชจ๋ ์ค๋ฅ๋ฅผ ์ด๋ ๋ ์ ๋ ์ ๋ฐ๊ฒฌํ๊ณ ์ ์์ต๋๋ค.
๊ทธ๋ฌ๋ ๊ธฐ์ฌ๋ฅผ ์์ฑํ๋ ๋ฐ ๋ช ์ฃผ๊ฐ ๊ฑธ๋ ธ์ต๋๋ค. ๋๋ ์ด ๋ชจ๋ ๊ฒ์ ํ ์คํธ๋ก ํํํ ์ ์์์ต๋๋ค :).
๊ทธ๊ฑด ๊ทธ๋ ๊ณ , ์ค๋ฅ์ ์ ์ฌ์ ์ธ ์ทจ์ฝ์ ์ ์๋ณํ๊ธฐ ์ํด PVS-Studio ๋ถ์๊ธฐ์์ ์ด๋ค ๊ธฐ์ ์ด ์ฌ์ฉ๋๋์ง์ ๊ด์ฌ์ด ์๋ค๋ฉด ์ด์ ๋ํด ์์๋ณด๋ ๊ฒ์ด ์ข์ต๋๋ค.
์ ๊ท ๋ฐ ๊ธฐ์กด ์ง๋จ
์ด๋ฏธ ์ธ๊ธํ ๋ฐ์ ๊ฐ์ด, ์ฝ 3๋ ์ ์ LLVM ํ๋ก์ ํธ๋ฅผ ๋ค์ ํ๋ฒ ์ ๊ฒํ์ฌ ๋ฐ๊ฒฌ๋ ์ค๋ฅ๋ฅผ ์์ ํ์ต๋๋ค. ์ด์ ์ด ๊ธฐ์ฌ์์๋ ์๋ก์ด ์ค๋ฅ ๋ฐฐ์น๋ฅผ ์ ์ํ ๊ฒ์ ๋๋ค. ์๋ก์ด ๋ฒ๊ทธ๊ฐ ๋ฐ๊ฒฌ๋ ์ด์ ๋ ๋ฌด์์ ๋๊น? ์ฌ๊ธฐ์๋ XNUMX๊ฐ์ง ์ด์ ๊ฐ ์์ต๋๋ค:
- LLVM ํ๋ก์ ํธ๋ ์งํํ๊ณ ์์ผ๋ฉฐ ๊ธฐ์กด ์ฝ๋๋ฅผ ๋ณ๊ฒฝํ๊ณ ์ ์ฝ๋๋ฅผ ์ถ๊ฐํ๊ณ ์์ต๋๋ค. ๋น์ฐํ ์์ ๋๊ณ ์์ฑ๋ ์ฝ๋์๋ ์๋ก์ด ์ค๋ฅ๊ฐ ์์ต๋๋ค. ์ด๋ ์ ์ ๋ถ์์ ๊ฐ๋ ์ฌ์ฉํ์ง ์๊ณ ์ ๊ธฐ์ ์ผ๋ก ์ฌ์ฉํด์ผ ํจ์ ๋ถ๋ช ํ ๋ณด์ฌ์ค๋๋ค. ์ฐ๋ฆฌ ๊ธฐ์ฌ์์๋ PVS-Studio ๋ถ์๊ธฐ์ ๊ธฐ๋ฅ์ ์ ๋ณด์ฌ ์ฃผ์ง๋ง ์ด๋ ์ฝ๋ ํ์ง์ ๊ฐ์ ํ๊ณ ์ค๋ฅ ์์ ๋น์ฉ์ ์ค์ด๋ ๊ฒ๊ณผ๋ ์๋ฌด๋ฐ ๊ด๋ จ์ด ์์ต๋๋ค. ์ ์ ์ฝ๋ ๋ถ์๊ธฐ๋ฅผ ์ ๊ธฐ์ ์ผ๋ก ์ฌ์ฉํ์ธ์!
- ๊ธฐ์กด ์ง๋จ์ ๋ง๋ฌด๋ฆฌํ๊ณ ๊ฐ์ ํ๊ณ ์์ต๋๋ค. ๋ฐ๋ผ์ ๋ถ์๊ธฐ๋ ์ด์ ์ค์บ ์ค์ ๋ฐ๊ฒฌํ์ง ๋ชปํ ์ค๋ฅ๋ฅผ ์๋ณํ ์ ์์ต๋๋ค.
- 2๋ ์ ์๋ ์กด์ฌํ์ง ์์๋ ์๋ก์ด ์ง๋จ ๊ธฐ๋ฅ์ด PVS-Studio์ ๋ฑ์ฅํ์ต๋๋ค. PVS-Studio์ ๋ฐ์ ์ ๋ช ํํ๊ฒ ๋ณด์ฌ์ฃผ๊ธฐ ์ํด ๋ณ๋์ ์น์ ์ ๊ฐ์กฐ ํ์ํ๊ธฐ๋ก ๊ฒฐ์ ํ์ต๋๋ค.
2๋ ์ ์ ์กด์ฌํ๋ ์ง๋จ์ ํตํด ํ์ธ๋ ๊ฒฐํจ
์กฐ๊ฐ N1: ๋ณต์ฌํ์ฌ ๋ถ์ฌ๋ฃ๊ธฐ
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 ๊ฒฝ๊ณ :
์ด๋ฆ์ด ํ์ ๋ฌธ์์ด "avx512.mask.permvar."๋ก ์์ํ๋์ง ๋ค์ ํ์ธํฉ๋๋ค. ๋ ๋ฒ์งธ ํ์ธ์์ ๊ทธ๋ค์ ๋ถ๋ช ํ ๋ค๋ฅธ ๊ฒ์ ์ฐ๊ณ ์ถ์์ง๋ง ๋ณต์ฌ๋ ํ ์คํธ๋ฅผ ์์ ํ๋ ๊ฒ์ ์์ด๋ฒ๋ ธ์ต๋๋ค.
์กฐ๊ฐ N2: ์คํ
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;
....
}
๊ฒฝ๊ณ PVS-Studio: V501 '|' ์ผ์ชฝ๊ณผ ์ค๋ฅธ์ชฝ์ ๋์ผํ ํ์ ํํ์ 'CXNameRange_WantQualifier'๊ฐ ์์ต๋๋ค. ์ด์์. CIndex.cpp 7245
์คํ๋ก ์ธํด ๊ฐ์ ์ด๋ฆ์ ์์๊ฐ ๋ ๋ฒ ์ฌ์ฉ๋์์ต๋๋ค. CXNameRange_WantQualifier.
์กฐ๊ฐ N3: ์ฐ์ฐ์ ์ฐ์ ์์์ ๋ํ ํผ๋
int PPCTTIImpl::getVectorInstrCost(unsigned Opcode, Type *Val, unsigned Index) {
....
if (ISD == ISD::EXTRACT_VECTOR_ELT && Index == ST->isLittleEndian() ? 1 : 0)
return 0;
....
}
PVS-Studio ๊ฒฝ๊ณ :
๋ด ์๊ฐ์ ์ด๊ฒ์ ๋งค์ฐ ์๋ฆ๋ค์ด ์ค์์ด๋ค. ๋ค, ์ ๊ฐ ์๋ฆ๋ค์์ ๋ํด ์ด์ํ ์๊ฐ์ ๊ฐ๊ณ ์๋ค๋ ๊ฑธ ์์์ :).
์ด์ ๋ฐ๋ฅด๋ฉด
(ISD == ISD::EXTRACT_VECTOR_ELT && (Index == ST->isLittleEndian())) ? 1 : 0
์ค์ฉ์ ์ธ ๊ด์ ์์ ๋ณผ ๋ ์ด๋ฌํ ์กฐ๊ฑด์ ๋ค์๊ณผ ๊ฐ์ด ์ถ์๋ ์ ์์ผ๋ฏ๋ก ์๋ฏธ๊ฐ ์์ต๋๋ค.
(ISD == ISD::EXTRACT_VECTOR_ELT && Index == ST->isLittleEndian())
์ด๊ฒ์ ๋ช ๋ฐฑํ ์ค์์ ๋๋ค. ์๋ง๋ ๊ทธ๋ค์ 0/1์ ๋ณ์์ ๋น๊ตํ๊ณ ์ถ์์ ๊ฒ์ ๋๋ค. ์์ธ. ์ฝ๋๋ฅผ ์์ ํ๋ ค๋ฉด ์ผํญ ์ฐ์ฐ์ ์ฃผ์์ ๊ดํธ๋ฅผ ์ถ๊ฐํด์ผ ํฉ๋๋ค.
if (ISD == ISD::EXTRACT_VECTOR_ELT && Index == (ST->isLittleEndian() ? 1 : 0))
๊ทธ๋ฐ๋ฐ ์ผํญ ์ฐ์ฐ์๋ ๋งค์ฐ ์ํํ๊ณ ๋
ผ๋ฆฌ์ ์ค๋ฅ๋ฅผ ์ ๋ฐํฉ๋๋ค. ๋งค์ฐ ์กฐ์ฌํ๊ณ ๊ดํธ์ ์์ฌ์ ๋ถ๋ฆฌ์ง ๋ง์ญ์์ค. ์ด ์ฃผ์ ๋ฅผ ๋ ์์ธํ ์ดํด๋ณด์์ต๋๋ค.
์กฐ๊ฐ 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-Studio ๊ฒฝ๊ณ :
ํฌ์ธํฐ์ ๊ฒฝ์ฐ ์ขํ์ null์ด๋ฉด ๊ฒฝ๊ณ ๊ฐ ๋ฐํ๋์ด์ผ ํฉ๋๋ค. ๊ทธ๋ฌ๋ ๋์ ์ด ๋์ผํ null ํฌ์ธํฐ๊ฐ ์ญ์ฐธ์กฐ๋ฉ๋๋ค. LHS->getAsString().
์ด๋ ์๋ฌด๋ ์ค๋ฅ๋ฅผ ํ ์คํธํ์ง ์๊ธฐ ๋๋ฌธ์ ์ค๋ฅ ํธ๋ค๋ฌ์ ์ค๋ฅ๊ฐ ์จ๊ฒจ์ ธ ์๋ ๋งค์ฐ ์ผ๋ฐ์ ์ธ ์ํฉ์ ๋๋ค. ์ ์ ๋ถ์๊ธฐ๋ ์ฌ์ฉ ๋น๋์ ๊ด๊ณ์์ด ๋๋ฌ ๊ฐ๋ฅํ ๋ชจ๋ ์ฝ๋๋ฅผ ํ์ธํฉ๋๋ค. ์ด๋ ์ ์ ๋ถ์์ด ๋ค๋ฅธ ํ ์คํธ ๋ฐ ์ค๋ฅ ๋ฐฉ์ง ๊ธฐ์ ์ ์ด๋ป๊ฒ ๋ณด์ํ๋์ง ๋ณด์ฌ์ฃผ๋ ์์ฃผ ์ข์ ์์ ๋๋ค.
์ ์ฌํ ํฌ์ธํฐ ์ฒ๋ฆฌ ์ค๋ฅ ์ฐ ๋ฐ๋ก ์๋ ์ฝ๋์์ ํ์ฉ๋ฉ๋๋ค: V522 [CWE-476] ๋ ํฌ์ธํฐ 'RHS'์ ์ญ์ฐธ์กฐ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. TGParser.cpp 2186
์กฐ๊ฐ N6: ์ด๋ ํ ํฌ์ธํฐ ์ฌ์ฉ
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 ๊ฒฝ๊ณ : V522 [CWE-476] ๋ ํฌ์ธํฐ 'ProgClone'์ ์ญ์ฐธ์กฐ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. ์๋ชป๋ ์ปดํ์ผ.cpp 601
์ฒ์์๋ ์ค๋งํธ ํฌ์ธํฐ ํ๋ก๊ทธํด๋ก ๊ฐ์ฒด ์์ ๋ฅผ ์ค๋จํฉ๋๋ค.
BD.setNewProgram(std::move(ProgClone));
์ฌ์ค ์ง๊ธ์ ํ๋ก๊ทธํด๋ก ๋ ํฌ์ธํฐ์ ๋๋ค. ๋ฐ๋ผ์ ๋ ํฌ์ธํฐ ์ญ์ฐธ์กฐ๋ ๋ฐ๋ก ์๋์์ ๋ฐ์ํด์ผ ํฉ๋๋ค.
Function *NewF = ProgClone->getFunction(MisCompFunctions[i].first);
๊ทธ๋ฌ๋ ์ค์ ๋ก๋ ์ด๋ฐ ์ผ์ด ์ผ์ด๋์ง ์์ ๊ฒ์ ๋๋ค! ๋ฃจํ๋ ์ค์ ๋ก ์คํ๋์ง ์์ต๋๋ค.
์ปจํ ์ด๋์ ์์ ๋ถ๋ถ์ ์๋ชป ์ปดํ์ผ๋ ํจ์ ์ญ์ ๋จ:
MiscompiledFunctions.clear();
๋ค์์ผ๋ก ์ด ์ปจํ ์ด๋์ ํฌ๊ธฐ๋ ๋ฃจํ ์กฐ๊ฑด์์ ์ฌ์ฉ๋ฉ๋๋ค.
for (unsigned i = 0, e = MisCompFunctions.size(); i != e; ++i) {
๋ฃจํ๊ฐ ์์๋์ง ์๋ ๊ฒ์ ์ฝ๊ฒ ์ ์ ์์ต๋๋ค. ์ด๊ฒ๋ ๋ฒ๊ทธ๋ผ๊ณ ์๊ฐํด์ ์ฝ๋๋ฅผ ๋ค๋ฅด๊ฒ ์์ฑํด์ผ ํ ๊ฒ ๊ฐ์ต๋๋ค.
์ฐ๋ฆฌ๋ ๊ทธ ์ ๋ช ํ ํจ๋ฆฌํฐ ์ค๋ธ ์๋ฌ(parity of error)๋ฅผ ๋ง๋ ๊ฒ ๊ฐ์ต๋๋ค! ํ ๋ฒ์ ์ค์๋ก ๋ค๋ฅธ ์ค์๊ฐ ๊ฐ๋ ค์ง๋๋ค :).
์กฐ๊ฐ N7: ์ด๋ ํ ํฌ์ธํฐ ์ฌ์ฉ
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 ๊ฒฝ๊ณ : V522 [CWE-476] ๋ ํฌ์ธํฐ 'Test'์ ์ญ์ฐธ์กฐ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. ์๋ชป๋ ์ปดํ์ผ.cpp 709
๋ ๊ฐ์ ์ํฉ์ ๋๋ค. ์ฒ์์๋ ๊ฐ์ฒด์ ๋ด์ฉ์ ์ด๋ํ ํ ์๋ฌด ์ผ๋ ์์๋ ๊ฒ์ฒ๋ผ ์ฌ์ฉํฉ๋๋ค. C++์ ์ด๋ ์๋ฏธ๋ก ์ด ๋ฑ์ฅํ ์ดํ ํ๋ก๊ทธ๋จ ์ฝ๋์์ ์ด๋ฌํ ์ํฉ์ ์ ์ ๋ ์์ฃผ ๋ณด๊ฒ ๋ฉ๋๋ค. ์ด๊ฒ์ด ๋ฐ๋ก ์ ๊ฐ C++ ์ธ์ด๋ฅผ ์ข์ํ๋ ์ด์ ์ ๋๋ค! ์์ ์ ๋ค๋ฆฌ๋ฅผ ์๋ ์๋ก์ด ๋ฐฉ๋ฒ์ด ์ ์ ๋ ๋ง์์ง๊ณ ์์ต๋๋ค. PVS-Studio ๋ถ์๊ธฐ๋ ํญ์ ์๋ํฉ๋๋ค :).
์กฐ๊ฐ 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 ๊ฒฝ๊ณ : V522 [CWE-476] ๋ ํฌ์ธํฐ 'Type'์ ์ญ์ฐธ์กฐ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. PrettyFunctionDumper.cpp 233
์ค๋ฅ ์ฒ๋ฆฌ๊ธฐ ์ธ์๋ ๋๋ฒ๊น ์ธ์ ๊ธฐ๋ฅ์ ์ผ๋ฐ์ ์ผ๋ก ํ ์คํธ๋์ง ์์ต๋๋ค. ์ฐ๋ฆฌ ์์๋ ๊ทธ๋ฌํ ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค. ์ด ๊ธฐ๋ฅ์ ์ฌ์ฉ์๊ฐ ์์ ์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋์ ๊ฐ์ ๋ก ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ๋ฅผ ๊ธฐ๋ค๋ฆฌ๊ณ ์์ต๋๋ค.
์ฌ๋ฐ๋ฅด๊ฒ :
if (Type)
Type->dump(*this);
else
Printer << "<unknown-type>";
์กฐ๊ฐ 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-Studio ๊ฒฝ๊ณ : V522 [CWE-476] ๋ ํฌ์ธํฐ 'Ty'์ ์ญ์ฐธ์กฐ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. SearchableTableEmitter.cpp 614
๋๋ ๋ชจ๋ ๊ฒ์ด ๋ช ํํ๊ณ ์ค๋ช ์ด ํ์ํ์ง ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
์กฐ๊ฐ N10: ์คํ
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 ๊ฒฝ๊ณ :
๋ณ์ ์์ฒด๋ฅผ ํ ๋นํ๋ ๊ฒ์ ์๋ฏธ๊ฐ ์์ต๋๋ค. ์๋ง๋ ๊ทธ๋ค์ ๋ค์๊ณผ ๊ฐ์ด ์ฐ๊ณ ์ถ์์ ๊ฒ์ ๋๋ค.
Identifier->Type = Question->Type;
์กฐ๊ฐ 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-Studio ๊ฒฝ๊ณ :
์ด๋ฐ์๋ ๋งค์ฐ ์์ํ ์ด์์๊ฐ ์์ต๋๋ค ํ๋ค. ์ฌ๊ธฐ์ ๋ค๋ฅธ ๊ฒ์ ์ฐ๋ ๊ฒ์ ์์๋์?
์กฐ๊ฐ N12: ์ญ์ฐธ์กฐ ํ ํฌ์ธํฐ ํ์ธ
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 ๊ฒฝ๊ณ :
ํฌ์ธํฐ ์์ ์ ์ฒ์์๋ ํจ์๊ฐ ํธ์ถ๋ ๋ ์ญ์ฐธ์กฐ๋ฉ๋๋ค. getTTI.
๊ทธ๋ฆฌ๊ณ ๋์ ์ด ํฌ์ธํฐ๊ฐ ๋์ผํ์ง ํ์ธํด์ผ ํ๋ค๋ ๊ฒ์ด ๋ฐํ์ก์ต๋๋ค. nullptr:
if (!Callee || Callee->isDeclaration())
ํ์ง๋ง ๋๋ฌด ๋ฆ์์ดโฆ
์กฐ๊ฐ N13 - N...: ์ญ์ฐธ์กฐ ํ ํฌ์ธํฐ ํ์ธ
์ด์ ์ฝ๋ ๋จํธ์์ ๋ ผ์๋ ์ํฉ์ ๊ณ ์ ํ ๊ฒ์ด ์๋๋๋ค. ์ฌ๊ธฐ์ ๋ํ๋ฉ๋๋ค:
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 ๊ฒฝ๊ณ : V595 [CWE-476] 'CalleeFn' ํฌ์ธํฐ๊ฐ nullptr์ ๋ํด ํ์ธ๋๊ธฐ ์ ์ ํ์ฉ๋์์ต๋๋ค. ๋ผ์ธ ํ์ธ: 1079, 1081. SimplifyLibCalls.cpp 1079
๊ทธ๋ฆฌ๊ณ ์ฌ๊ธฐ :
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 ๊ฒฝ๊ณ : V595 [CWE-476] nullptr์ ๋ํด ํ์ธ๋๊ธฐ ์ ์ 'ND' ํฌ์ธํฐ๊ฐ ์ฌ์ฉ๋์์ต๋๋ค. ์ค ํ์ธ: 532, 534. SemaTemplateInstantiateDecl.cpp 532
๊ทธ๋ฆฌ๊ณ ์ฌ๊ธฐ :
- V595 [CWE-476] 'U' ํฌ์ธํฐ๋ nullptr์ ๋ํด ํ์ธ๋๊ธฐ ์ ์ ํ์ฉ๋์์ต๋๋ค. ๋ผ์ธ ํ์ธ: 404, 407. DWARFormValue.cpp 404
- V595 [CWE-476] 'ND' ํฌ์ธํฐ๋ nullptr์ ๋ํด ํ์ธ๋๊ธฐ ์ ์ ํ์ฉ๋์์ต๋๋ค. ๋ผ์ธ ํ์ธ: 2149, 2151. SemaTemplateInstantiate.cpp 2149
๊ทธ๋ฆฌ๊ณ ๋์ ๋๋ V595๋ฒ์ ๊ฒฝ๊ณ ๋ฅผ ์ฐ๊ตฌํ๋ ๋ฐ ๊ด์ฌ์ด ์๊ฒ ๋์์ต๋๋ค. ๊ทธ๋์ ์ฌ๊ธฐ์ ๋์ด๋ ์ค๋ฅ ์ธ์ ์ ์ฌํ ์ค๋ฅ๊ฐ ๋ ์๋์ง๋ ์ ์ ์์ต๋๋ค. ์๋ง๋ ๊ทธ๋ด ๊ฒ์ ๋๋ค.
์กฐ๊ฐ N17, N18: ์์ฌ์ค๋ฌ์ด ๋ณํ
static inline bool processLogicalImmediate(uint64_t Imm, unsigned RegSize,
uint64_t &Encoding) {
....
unsigned Size = RegSize;
....
uint64_t NImms = ~(Size-1) << 1;
....
}
PVS-Studio ๊ฒฝ๊ณ :
๋ฒ๊ทธ๊ฐ ์๋ ์๋ ์์ผ๋ฉฐ ์ฝ๋๋ ์๋ํ ๋๋ก ์ ํํ๊ฒ ์๋ํฉ๋๋ค. ํ์ง๋ง ์ด๋ ๋ถ๋ช ํ ๋งค์ฐ ์์ฌ์ค๋ฌ์ด ๊ณณ์ด๋ฏ๋ก ํ์ธ์ด ํ์ํฉ๋๋ค.
๋ณ์๋ฅผ ๋งํด๋ณด์ ํฌ๊ธฐ ๋ 16์ด๊ณ ์ฝ๋ ์์ฑ์๋ ์ด๋ฅผ ๋ณ์๋ก ๊ฐ์ ธ์ค๋ ค๊ณ ๊ณํํ์ต๋๋ค. NImms ๊ฐ์น :
1111111111111111111111111111111111111111111111111111111111100000
๊ทธ๋ฌ๋ ์ค์ ๋ก ๊ฒฐ๊ณผ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
0000000000000000000000000000000011111111111111111111111111100000
์ฌ์ค ๋ชจ๋ ๊ณ์ฐ์ 32๋นํธ ๋ถํธ ์๋ ์ ํ์ ์ฌ์ฉํ์ฌ ๋ฐ์ํฉ๋๋ค. ๊ทธ๋ฐ ๋ค์์๋ง ์ด 32๋นํธ ๋ถํธ ์๋ ์ ํ์ ๋ค์๊ณผ ๊ฐ์ด ์์์ ์ผ๋ก ํ์ฅ๋ฉ๋๋ค. uint64_t. ์ด ๊ฒฝ์ฐ ์ต์์ ๋นํธ๋ XNUMX์ด ๋ฉ๋๋ค.
๋ค์๊ณผ ๊ฐ์ด ์ํฉ์ ํด๊ฒฐํ ์ ์์ต๋๋ค.
uint64_t NImms = ~static_cast<uint64_t>(Size-1) << 1;
์ ์ฌํ ์ํฉ: V629 [CWE-190] 'Immr << 6' ํํ์ ๊ฒ์ฌ๋ฅผ ๊ณ ๋ คํ์ญ์์ค. 32๋นํธ ์ ํ์ผ๋ก์ ํ์ ํ์ฅ์ ํตํด 64๋นํธ ๊ฐ์ ๋นํธ ์ด๋. AArch64AddressingModes.h 269
์กฐ๊ฐ N19: ํค์๋ ๋๋ฝ ๊ทธ๋ ์ง ์์ผ๋ฉด?
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 ๊ฒฝ๊ณ :
์ฌ๊ธฐ์๋ ์ค์๊ฐ ์์ต๋๋ค. ์ฒซ ๋ฒ์งธ ๋ธ๋ก ์ดํ if ๋ก ๋๋๋ค ๊ณ์, ๊ทธ๋ ๋ค๋ฉด ์๊ด ์์ต๋๋ค. ํค์๋๊ฐ ์์ต๋๋ค ๊ทธ๋ ์ง ์์ผ๋ฉด ์๋๋ฉด. ์ด๋ ์ชฝ์ด๋ ์ฝ๋๋ ๋์ผํ๊ฒ ์๋ํฉ๋๋ค. ์์ง๋ ๊ทธ๋ฆฌ์ ๊ทธ๋ ์ง ์์ผ๋ฉด ์ฝ๋๋ฅผ ๋์ฑ ๋ถ๋ถ๋ช ํ๊ณ ์ํํ๊ฒ ๋ง๋ญ๋๋ค. ๋ง์ฝ ๋ฏธ๋์ ๊ณ์ ์ฌ๋ผ์ง๋ฉด ์ฝ๋๊ฐ ์์ ํ ๋ค๋ฅด๊ฒ ์๋ํ๊ธฐ ์์ํฉ๋๋ค. ์ ์๊ฐ์๋ ์ถ๊ฐํ๋ ๊ฒ์ด ๋ ๋ซ๋ค๊ณ ์๊ฐํฉ๋๋ค ๊ทธ๋ ์ง ์์ผ๋ฉด.
Fragment N20: ๊ฐ์ ์ ํ์ ์คํ XNUMX๊ฐ
LLVM_DUMP_METHOD void Symbol::dump(raw_ostream &OS) const {
std::string Result;
if (isUndefined())
Result += "(undef) ";
if (isWeakDefined())
Result += "(weak-def) ";
if (isWeakReferenced())
Result += "(weak-ref) ";
if (isThreadLocalValue())
Result += "(tlv) ";
switch (Kind) {
case SymbolKind::GlobalSymbol:
Result + Name.str(); // <=
break;
case SymbolKind::ObjectiveCClass:
Result + "(ObjC Class) " + Name.str(); // <=
break;
case SymbolKind::ObjectiveCClassEHType:
Result + "(ObjC Class EH) " + Name.str(); // <=
break;
case SymbolKind::ObjectiveCInstanceVariable:
Result + "(ObjC IVar) " + Name.str(); // <=
break;
}
OS << Result;
}
PVS-Studio ๊ฒฝ๊ณ :
- V655 [CWE-480] ๋ฌธ์์ด์ด ์ฐ๊ฒฐ๋์์ง๋ง ์ฌ์ฉ๋์ง ์์์ต๋๋ค. 'Result + Name.str()' ํํ์์ ๊ฒ์ฌํด ๋ณด์ธ์. Symbol.cpp 32
- V655 [CWE-480] ๋ฌธ์์ด์ด ์ฐ๊ฒฐ๋์์ง๋ง ์ฌ์ฉ๋์ง ์์์ต๋๋ค. 'Result + "(ObjC Class)" + Name.str()' ํํ์์ ๊ฒ์ฌํด ๋ณด์ธ์. Symbol.cpp 35
- V655 [CWE-480] ๋ฌธ์์ด์ด ์ฐ๊ฒฐ๋์์ง๋ง ์ฌ์ฉ๋์ง ์์์ต๋๋ค. 'Result + "(ObjC Class EH) " + Name.str()' ํํ์์ ๊ฒ์ฌํด ๋ณด์ธ์. Symbol.cpp 38
- V655 [CWE-480] ๋ฌธ์์ด์ด ์ฐ๊ฒฐ๋์์ง๋ง ์ฌ์ฉ๋์ง ์์์ต๋๋ค. 'Result + "(ObjC IVar)" + Name.str()' ํํ์์ ๊ฒ์ฌํด ๋ณด์ธ์. Symbol.cpp 41
์ค์๋ก += ์ฐ์ฐ์ ๋์ + ์ฐ์ฐ์๊ฐ ์ฌ์ฉ๋์์ต๋๋ค. ๊ฒฐ๊ณผ์ ์ผ๋ก ์๋ฏธ๊ฐ ์๋ ๋์์ธ์ด ํ์ํ๊ฒ ๋ฉ๋๋ค.
์กฐ๊ฐ N21: ์ ์๋์ง ์์ ๋์
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();
}
}
}
์ํํ ์ฝ๋๋ฅผ ์ง์ ์ฐพ์๋ณด์ธ์. ๊ทธ๋ฆฌ๊ณ ์ด๊ฒ์ ์ฆ์ ๋ต์ ๋ณด์ง ์๋๋ก์ฃผ์๋ฅผ ์ฐ๋งํ๊ฒํ๋ ๊ทธ๋ฆผ์ ๋๋ค.
PVS-Studio ๊ฒฝ๊ณ :
๋ฌธ์ ๋ผ์ธ:
FeaturesMap[Op] = FeaturesMap.size();
์์๋ผ๋ฉด Op ์ ์ฐพ์ ์ ์์ผ๋ฉด ๋งต์ ์ ์์๊ฐ ์์ฑ๋๊ณ ์ด ๋งต์ ์์ ์๊ฐ ๊ฑฐ๊ธฐ์ ๊ธฐ๋ก๋ฉ๋๋ค. ํจ์๊ฐ ํธ์ถ๋ ์ง๋ ์ ์ ์์ต๋๋ค. ํฌ๊ธฐ ์ ์์๋ฅผ ์ถ๊ฐํ๊ธฐ ์ ์ด๋ ํ์.
์กฐ๊ฐ N22-N24: ๋ฐ๋ณต ํ ๋น
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 ๊ฒฝ๊ณ :
๋๋ ์ฌ๊ธฐ์ ์ง์ง ์ค์๊ฐ ์๋ค๊ณ ์๊ฐํ์ง ์์ต๋๋ค. ๋ถํ์ํ ๋ฐ๋ณต ํ ๋น์ผ ๋ฟ์ ๋๋ค. ๊ทธ๋ฌ๋ ์ฌ์ ํ ์ค์์ ๋๋ค.
๋น์ทํ๊ฒ :
- V519 [CWE-563] 'B.NDesc' ๋ณ์์๋ 1488๋ฒ ์ฐ์์ผ๋ก ๊ฐ์ด ํ ๋น๋ฉ๋๋ค. ์๋ง๋ ์ด๊ฒ์ ์ค์์ผ ๊ฒ์ด๋ค. ๋ผ์ธ ํ์ธ: 1489, 1489. llvm-nm.cpp XNUMX
- V519 [CWE-563] ๋ณ์์๋ ์ฐ์์ ์ผ๋ก ๋ ๋ฒ ๊ฐ์ด ํ ๋น๋ฉ๋๋ค. ์๋ง๋ ์ด๊ฒ์ ์ค์์ผ ๊ฒ์ด๋ค. ๋ผ์ธ ํ์ธ: 59, 61. coff2yaml.cpp 61
์กฐ๊ฐ N25-N27: ์ถ๊ฐ ์ฌํ ๋น
์ด์ ์ฝ๊ฐ ๋ค๋ฅธ ๋ฒ์ ์ ์ฌํ ๋น์ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
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 ๊ฒฝ๊ณ : V519 [CWE-563] 'Alignment' ๋ณ์์ ๊ฐ์ด ์ฐ์์ ์ผ๋ก ๋ ๋ฒ ํ ๋น๋ฉ๋๋ค. ์๋ง๋ ์ด๊ฒ์ ์ค์์ผ ๊ฒ์ด๋ค. ๋ผ์ธ ํ์ธ: 1158, 1160. LoadStoreVectorizer.cpp 1160
์ด๊ฒ์ ๋ถ๋ช ํ ๋ ผ๋ฆฌ์ ์ค๋ฅ๊ฐ ํฌํจ๋์ด ์๋ ๋งค์ฐ ์ด์ํ ์ฝ๋์ ๋๋ค. ์ฒ์์๋ ๋ณ์ ์กฐ์ ์กฐ๊ฑด์ ๋ฐ๋ผ ๊ฐ์ด ํ ๋น๋ฉ๋๋ค. ๊ทธ๋ฐ ๋ค์ ํ ๋น์ด ๋ค์ ๋ฐ์ํ์ง๋ง ์ง๊ธ์ ํ์ธ์ด ์์ต๋๋ค.
๋น์ทํ ์ํฉ์ ์ฌ๊ธฐ์์ ๋ณผ ์ ์์ต๋๋ค:
- V519 [CWE-563] 'Effects' ๋ณ์์๋ ์ฐ์์ ์ผ๋ก ๋ ๋ฒ ๊ฐ์ด ํ ๋น๋ฉ๋๋ค. ์๋ง๋ ์ด๊ฒ์ ์ค์์ผ ๊ฒ์ด๋ค. ๋ผ์ธ ํ์ธ: 152, 165. WebAssemblyRegStackify.cpp 165
- V519 [CWE-563] 'ExpectNoDerefChunk' ๋ณ์์๋ 4970๋ฒ ์ฐ์์ผ๋ก ๊ฐ์ด ํ ๋น๋ฉ๋๋ค. ์๋ง๋ ์ด๊ฒ์ ์ค์์ผ ๊ฒ์ด๋ค. ๋ผ์ธ ํ์ธ: 4973, 4973. SemaType.cpp XNUMX
์กฐ๊ฐ N28: ํญ์ ์ฐธ์ธ ์กฐ๊ฑด
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 ๊ฒฝ๊ณ :
ํ์ธํ๋ ๊ฒ์ ์๋ฏธ๊ฐ ์์ต๋๋ค. ๋ณํ๊ธฐ ์ฌ์ด ๋ค์๋ฐ์ดํธ ํญ์ ๊ฐ๊ณผ ๊ฐ์ง ์์ 0 X 90, ์ด๋ ์ด์ ํ์ธ์์ ์ด์ด์ง๋๋ค. ์ด๊ฒ์ ์ผ์ข ์ ๋ ผ๋ฆฌ์ ์ค๋ฅ์ ๋๋ค.
์กฐ๊ฐ N29 - N...: ํญ์ ์ฐธ/๊ฑฐ์ง ์กฐ๊ฑด
๋ถ์๊ธฐ๋ ์ ์ฒด ์กฐ๊ฑด(
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 ๊ฒฝ๊ณ :
์์ 0xE๋ 14์ง์ ๊ฐ XNUMX์ ๋๋ค. ์ํ ๋ฑ๋ก ๋ฒํธ == 0xe ๋ง์ด ์ ๋๋๊น ๋ง์ฝ์ ๋ฑ๋ก๋ฒํธ > 13, ๊ทธ๋ฌ๋ฉด ํจ์ ์คํ์ด ์๋ฃ๋ฉ๋๋ค.
ID V547 ๋ฐ V560์๋ ๋ค๋ฅธ ๋ง์ ๊ฒฝ๊ณ ๊ฐ ์์์ง๋ง
์ด๋ฌํ ์ ๋ฐ ์์ธ์ ์ฐ๊ตฌํ๋ ๊ฒ์ด ์ ์ง๋ฃจํ์ง ์๋ฅผ ๋ค์ด ๋ณด๊ฒ ์ต๋๋ค. ๋ถ์๊ธฐ๋ ๋ค์ ์ฝ๋์ ๋ํด ๊ฒฝ๊ณ ๋ฅผ ๋ฐํํ๋ ๊ฒ์ด ์ ๋์ ์ผ๋ก ์ณ์ต๋๋ค. ๊ทธ๋ฌ๋ ์ด๊ฒ์ ์ค์๊ฐ ์๋๋ค.
bool UnwrappedLineParser::parseBracedList(bool ContinueOnSemicolons,
tok::TokenKind ClosingBraceKind) {
bool HasError = false;
....
HasError = true;
if (!ContinueOnSemicolons)
return !HasError;
....
}
PVS-Studio ๊ฒฝ๊ณ : V547 [CWE-570] ํํ์ '!HasError'๋ ํญ์ ๊ฑฐ์ง์ ๋๋ค. UnwrappedLineParser.cpp 1635
๋จํธ N30: โโโโ์์ฌ์ค๋ฌ์ด ๋ฐํ
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 ๊ฒฝ๊ณ :
์ด๋ ์ค๋ฅ์ด๊ฑฐ๋ ์ฝ๋๋ฅผ ์ฝ๋ ํ๋ก๊ทธ๋๋จธ์๊ฒ ์ค๋ช ํ๊ธฐ ์ํ ํน์ ๊ธฐ์ ์ ๋๋ค. ์ด ๋์์ธ์ ๋์๊ฒ ์๋ฌด๊ฒ๋ ์ค๋ช ํ์ง ์๊ณ ๋งค์ฐ ์์ฌ์ค๋ฌ์ ๋ณด์ ๋๋ค. ๊ทธ๋ฐ ์์ผ๋ก ์ฐ์ง ์๋ ๊ฒ์ด ์ข์ต๋๋ค :).
ํผ๊ณคํ? ๊ทธ๋ฐ ๋ค์ ์ฐจ๋ ์ปคํผ๋ฅผ ๋ง๋ค ์๊ฐ์ ๋๋ค.
์๋ก์ด ์ง๋จ์ผ๋ก ์๋ณ๋ ๊ฒฐํจ
์ค๋๋ ์ง๋จ ๊ธฐ๋ฅ์ 30๋ฒ ํ์ฑํํ๋ฉด ์ถฉ๋ถํ๋ค๊ณ ์๊ฐํฉ๋๋ค. ์ด์ ๋ถ์๊ธฐ์ ๋ํ๋ ์๋ก์ด ์ง๋จ์ผ๋ก ์ด๋ค ํฅ๋ฏธ๋ก์ด ์ ์ ์ฐพ์ ์ ์๋์ง ์ดํด๋ณด๊ฒ ์ต๋๋ค.
์กฐ๊ฐ N31: ์ฐ๊ฒฐํ ์ ์๋ ์ฝ๋
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 ๊ฒฝ๊ณ :
๋ณด์๋ค์ํผ, ์ฐ์ฐ์์ ๋ ์ง์ ๋ชจ๋ if ๊ตํ์ ํธ์ถ๋ก ๋๋จ return. ์ด์ ๋ฐ๋ผ ์ปจํ ์ด๋ CtorDtorsByPriority ์ ๋ ์ง์์ง์ง ์์ต๋๋ค.
์กฐ๊ฐ N32: ์ฐ๊ฒฐํ ์ ์๋ ์ฝ๋
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 ๊ฒฝ๊ณ : V779 [CWE-561] ์ฐ๊ฒฐํ ์ ์๋ ์ฝ๋๊ฐ ๊ฐ์ง๋์์ต๋๋ค. ์ค๋ฅ๊ฐ ์์ ๊ฐ๋ฅ์ฑ์ด ์์ต๋๋ค. LLParser.cpp 835
ํฅ๋ฏธ๋ก์ด ์ํฉ. ๋จผ์ ์ด ์ฅ์๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
return ParseTypeIdEntry(SummaryID);
break;
์ธ๋ป ๋ณด๋ฉด ์ฌ๊ธฐ์๋ ์ค๋ฅ๊ฐ ์๋ ๊ฒ ๊ฐ์ต๋๋ค. ์ด์์ ๊ฐ๋ค์ ํ๋ค ์ฌ๊ธฐ์ ์ถ๊ฐ ํญ๋ชฉ์ด ํ๋ ๋ ์๋๋ฐ ๊ฐ๋จํ ์ญ์ ํ๋ฉด ๋ฉ๋๋ค. ๊ทธ๋ฌ๋ ๋ชจ๋ ๊ฒ์ด ๊ทธ๋ ๊ฒ ๋จ์ํ์ง๋ ์์ต๋๋ค.
๋ถ์๊ธฐ๋ ๋ค์ ์ค์ ๊ฒฝ๊ณ ๋ฅผ ํ์ํฉ๋๋ค.
Lex.setIgnoreColonInIdentifiers(false);
return false;
๊ทธ๋ฆฌ๊ณ ์ค์ ๋ก ์ด ์ฝ๋๋ ์ ๊ทผํ ์ ์์ต๋๋ค. ๋ชจ๋ ์ฌ๋ก ์ค์์น ๊ตํ์์ ์ ํ๋ก ๋๋ฉ๋๋ค return. ๊ทธ๋ฆฌ๊ณ ์ด์ ํผ์์๋ ๋ฌด์๋ฏธํด ํ๋ค ๋ณ๋ก ๋ฌดํดํด ๋ณด์ด์ง๋ ์๋ค์! ์๋ง๋ ๊ฐ์ง ์ค ํ๋๊ฐ ๋ค์์ผ๋ก ๋๋์ผ ํ ๊ฒ์ ๋๋ค. ํ๋ค~์ ์๋ค. return?
์กฐ๊ฐ N33: ์์ ๋นํธ์ ๋ฌด์์ ์ฌ์ค์
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 ๊ฒฝ๊ณ :
๊ธฐ๋ฅ์ ์ฐธ๊ณ ํด์ฃผ์ธ์ getStubAlignment ๋ฐํ ์ ํ ๋ถํธ. ํจ์๊ฐ ๊ฐ 8์ ๋ฐํํ๋ค๊ณ ๊ฐ์ ํ๊ณ ํํ์์ ๊ฐ์ ๊ณ์ฐํด ๋ณด๊ฒ ์ต๋๋ค.
~(getStubAlignment() - 1)
~(8u-1)
0xFFFFFFFF8u
์ด์ ๋ณ์๊ฐ ๋ฐ์ดํฐ ํฌ๊ธฐ 64๋นํธ unsigned ์ ํ์ด ์์ต๋๋ค. DataSize ๋ฐ 0xFFFFFFF8u ์์ ์ ์ํํ๋ฉด 0๊ฐ์ ์์ ๋นํธ๊ฐ ๋ชจ๋ 8์ผ๋ก ์ฌ์ค์ ๋ฉ๋๋ค. ์๋ง๋ ์ด๊ฒ์ ํ๋ก๊ทธ๋๋จธ๊ฐ ์ํ๋ ๊ฒ์ด ์๋ ๊ฒ์ ๋๋ค. ๋๋ ๊ทธ๊ฐ DataSize & XNUMXxFFFFFFFFFFFFFFFFXNUMXu๋ฅผ ๊ณ์ฐํ๊ณ ์ถ์ดํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
์ค๋ฅ๋ฅผ ์์ ํ๋ ค๋ฉด ๋ค์๊ณผ ๊ฐ์ด ์์ฑํด์ผ ํฉ๋๋ค.
DataSize &= ~(static_cast<uint64_t>(getStubAlignment()) - 1);
๋๋ :
DataSize &= ~(getStubAlignment() - 1ULL);
์กฐ๊ฐ N34: ๋ช ์์ ์ ํ ์บ์คํ ์ ์คํจํ์ต๋๋ค.
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 ๊ฒฝ๊ณ :
์ ํ ๋ณ์๋ฅผ ๊ณฑํ ๋ ์ค๋ฒํ๋ก๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด ๋ช
์์ ์ ํ ์บ์คํ
์ด ์ฌ์ฉ๋ฉ๋๋ค. INT. ๊ทธ๋ฌ๋ ์ฌ๊ธฐ์ ๋ช
์์ ์ธ ์ ํ ์บ์คํ
์ ์ค๋ฒํ๋ก๋ฅผ ๋ฐฉ์งํ์ง ์์ต๋๋ค. ๋จผ์ ๋ณ์๊ฐ ๊ณฑํด์ง๊ณ ๋์์ผ 32๋นํธ ๊ณฑ์
๊ฒฐ๊ณผ๊ฐ ๋ค์ ์ ํ์ผ๋ก ํ์ฅ๋ฉ๋๋ค.
์กฐ๊ฐ N35: ๋ณต์ฌ-๋ถ์ฌ๋ฃ๊ธฐ ์คํจ
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;
}
....
}
์ด ์๋ก์ด ํฅ๋ฏธ๋ก์ด ์ง๋จ์ ์ฝ๋ ์กฐ๊ฐ์ด ๋ณต์ฌ๋๊ณ ๊ทธ ์์ ์ผ๋ถ ์ด๋ฆ์ด ๋ณ๊ฒฝ๋๊ธฐ ์์ํ์ง๋ง ํ ๊ณณ์์๋ ์ฝ๋๊ฐ ์์ ๋์ง ์์ ์ํฉ์ ์๋ณํฉ๋๋ค.
๋ ๋ฒ์งธ ๋ธ๋ก์์๋ ๋ณ๊ฒฝ๋์์ต๋๋ค. Op0 ์ Op1. ๊ทธ๋ฌ๋ ํ ๊ณณ์์๋ ๊ณ ์ณ์ง์ง ์์์ต๋๋ค. ์๋ง๋ ๋ค์๊ณผ ๊ฐ์ด ์์ฑ๋์์ ๊ฒ์ ๋๋ค.
if (!match(Op1, m_PosZeroFP()) && isKnownNeverNaN(Op1, &TLI)) {
I.setOperand(1, ConstantFP::getNullValue(Op1->getType()));
return &I;
}
๋จํธ N36: ๋ค์ํ ํผ๋
struct Status {
unsigned Mask;
unsigned Mode;
Status() : Mask(0), Mode(0){};
Status(unsigned Mask, unsigned Mode) : Mask(Mask), Mode(Mode) {
Mode &= Mask;
};
....
};
PVS-Studio ๊ฒฝ๊ณ :
ํจ์ ์ธ์์ ํด๋์ค ๋ฉค๋ฒ์ ๋์ผํ ์ด๋ฆ์ ์ง์ ํ๋ ๊ฒ์ ๋งค์ฐ ์ํํฉ๋๋ค. ํผ๋์ค๋ฌ์์ง๊ธฐ๊ฐ ๋งค์ฐ ์ฝ์ต๋๋ค. ์ฐ๋ฆฌ ์์๋ ๊ทธ๋ฌํ ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค. ์ด ํํ์ ์๋ฏธ๊ฐ ์์ต๋๋ค:
Mode &= Mask;
ํจ์ ์ธ์๊ฐ ๋ณ๊ฒฝ๋ฉ๋๋ค. ๊ทธ๊ฒ ๋ค์ผ. ์ด ์ธ์๋ ๋ ์ด์ ์ฌ์ฉ๋์ง ์์ต๋๋ค. ์๋ง๋ ๋ค์๊ณผ ๊ฐ์ด ์์ฑํ์ ๊ฒ์ ๋๋ค.
Status(unsigned Mask, unsigned Mode) : Mask(Mask), Mode(Mode) {
this->Mode &= Mask;
};
๋จํธ 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;
}
๊ฒฝ๊ณ PVS-Studio: V1001 [CWE-563] 'Size' ๋ณ์๊ฐ ํ ๋น๋์์ง๋ง ๊ธฐ๋ฅ์ด ๋๋ ๋๊น์ง ์ฌ์ฉ๋์ง ์์ต๋๋ค. ๊ฐ์ฒด.cpp 424
์ํฉ์ ์ด์ ๊ณผ ๋น์ทํฉ๋๋ค. ๋ค์๊ณผ ๊ฐ์ด ์์ฑํด์ผ ํฉ๋๋ค.
this->Size += this->EntrySize;
์กฐ๊ฐ N38-N47: ์์ธ ํ์ธ์ ์์ด๋ฒ๋ ธ์ต๋๋ค.
์ด์ ์๋ ์ง๋จ ํธ๋ฆฌ๊ฑฐ๋ง์ ์๋ฅผ ์ดํด๋ณด์์ต๋๋ค.
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 ๊ฒฝ๊ณ : V1004 [CWE-476] 'Ptr' ํฌ์ธํฐ๊ฐ nullptr์ ๋ํด ๊ฒ์ฆ๋ ํ ์์ ํ์ง ์๊ฒ ์ฌ์ฉ๋์์ต๋๋ค. ๋ผ์ธ ํ์ธ: 729, 738. TargetTransformInfoImpl.h 738
๋ณ์ Ptr ๊ฐ์ ์๋ ์๋ค nullptr, ์ํ๋ก ์ ์ ์๋ฏ์ด:
if (Ptr != nullptr)
๊ทธ๋ฌ๋ ์ด ํฌ์ธํฐ ์๋์์๋ ์ฌ์ ํ์ธ ์์ด ์ญ์ฐธ์กฐ๋ฉ๋๋ค.
auto PtrSizeBits = DL.getPointerTypeSizeInBits(Ptr->getType());
๋ ๋ค๋ฅธ ๋น์ทํ ๊ฒฝ์ฐ๋ฅผ ์๊ฐํด ๋ด ์๋ค.
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 ๊ฒฝ๊ณ : V1004 [CWE-476] 'FD' ํฌ์ธํฐ๊ฐ nullptr์ ๋ํด ๊ฒ์ฆ๋ ํ ์์ ํ์ง ์๊ฒ ์ฌ์ฉ๋์์ต๋๋ค. ๋ผ์ธ ํ์ธ: 3228, 3231. CGDebugInfo.cpp 3231
ํ์งํ์ ์ฃผ์ํ์ธ์ FD. ๋ฌธ์ ๊ฐ ๋ช ํํ๊ฒ ๋๋ฌ๋๊ณ ํน๋ณํ ์ค๋ช ์ด ํ์ํ์ง ์๋ค๊ณ ํ์ ํฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ ๋ :
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 ๊ฒฝ๊ณ : V1004 [CWE-476] 'PtrTy' ํฌ์ธํฐ๊ฐ nullptr์ ๋ํด ๊ฒ์ฆ๋ ํ ์์ ํ์ง ์๊ฒ ์ฌ์ฉ๋์์ต๋๋ค. ๋ผ์ธ ํ์ธ: 960, 965. InterleavedLoadCombinePass.cpp 965
๊ทธ๋ฌํ ์ค๋ฅ๋ก๋ถํฐ ์์ ์ ๋ณดํธํ๋ ๋ฐฉ๋ฒ์ ๋ฌด์์ ๋๊น? ์ฝ๋ ๊ฒํ ์ ๋์ฑ ์ฃผ์๋ฅผ ๊ธฐ์ธ์ด๊ณ PVS-Studio ์ ์ ๋ถ์๊ธฐ๋ฅผ ์ฌ์ฉํ์ฌ ์ ๊ธฐ์ ์ผ๋ก ์ฝ๋๋ฅผ ํ์ธํ์ญ์์ค.
์ด๋ฌํ ์ ํ์ ์ค๋ฅ๊ฐ ์๋ ๋ค๋ฅธ ์ฝ๋ ์กฐ๊ฐ์ ์ธ์ฉํ๋ ๊ฒ์ ์๋ฏธ๊ฐ ์์ต๋๋ค. ๊ธฐ์ฌ์๋ ๊ฒฝ๊ณ ๋ชฉ๋ก๋ง ๋จ๊ฒจ ๋๊ฒ ์ต๋๋ค.
- V1004 [CWE-476] 'Expr' ํฌ์ธํฐ๊ฐ nullptr์ ๋ํด ๊ฒ์ฆ๋ ํ ์์ ํ์ง ์๊ฒ ์ฌ์ฉ๋์์ต๋๋ค. ๋ผ์ธ ํ์ธ: 1049, 1078. DebugInfoMetadata.cpp 1078
- V1004 [CWE-476] 'PI' ํฌ์ธํฐ๊ฐ nullptr์ ๋ํด ๊ฒ์ฆ๋ ํ ์์ ํ์ง ์๊ฒ ์ฌ์ฉ๋์์ต๋๋ค. ๋ผ์ธ ํ์ธ: 733, 753. LegacyPassManager.cpp 753
- V1004 [CWE-476] 'StatepointCall' ํฌ์ธํฐ๊ฐ nullptr์ ๋ํด ๊ฒ์ฆ๋ ํ ์์ ํ์ง ์๊ฒ ์ฌ์ฉ๋์์ต๋๋ค. ๋ผ์ธ ํ์ธ: 4371, 4379. Verifier.cpp 4379
- V1004 [CWE-476] 'RV' ํฌ์ธํฐ๊ฐ nullptr์ ๋ํด ๊ฒ์ฆ๋ ํ ์์ ํ์ง ์๊ฒ ์ฌ์ฉ๋์์ต๋๋ค. ๋ผ์ธ ํ์ธ: 2263, 2268. TGParser.cpp 2268
- V1004 [CWE-476] 'CalleeFn' ํฌ์ธํฐ๊ฐ nullptr์ ๋ํด ๊ฒ์ฆ๋ ํ ์์ ํ์ง ์๊ฒ ์ฌ์ฉ๋์์ต๋๋ค. ๋ผ์ธ ํ์ธ: 1081, 1096. SimplifyLibCalls.cpp 1096
- V1004 [CWE-476] 'TC' ํฌ์ธํฐ๊ฐ nullptr์ ๋ํด ๊ฒ์ฆ๋ ํ ์์ ํ์ง ์๊ฒ ์ฌ์ฉ๋์์ต๋๋ค. ๋ผ์ธ ํ์ธ: 1819, 1824. Driver.cpp 1824
์กฐ๊ฐ N48-N60: ์ค์ํ์ง๋ ์์ง๋ง ๊ฒฐํจ(๋ฉ๋ชจ๋ฆฌ ๋์ ๊ฐ๋ฅ์ฑ)
std::unique_ptr<IRMutator> createISelMutator() {
....
std::vector<std::unique_ptr<IRMutationStrategy>> Strategies;
Strategies.emplace_back(
new InjectorIRStrategy(InjectorIRStrategy::getDefaultOps()));
....
}
PVS-Studio ๊ฒฝ๊ณ :
๋ค์๊ณผ ๊ฐ์ด ์ปจํ ์ด๋ ๋์ ์์๋ฅผ ์ถ๊ฐํ๋ ค๋ฉด ํ์ค::๋ฒกํฐ > ๋ ๊ทธ๋ฅ ์ธ ์ ์์ด xxx.push_back(์ X), ์์์ ์ธ ๋ณํ์ด ์๊ธฐ ๋๋ฌธ์ X* ะฒ ํ์ค::unique_ptr.
์ผ๋ฐ์ ์ธ ํด๊ฒฐ์ฑ ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. xxx.emplace_back(์ X)์ปดํ์ผ ์ดํ: ๋ฉ์๋ emplace_back ์ธ์์์ ์ง์ ์์๋ฅผ ์์ฑํ๋ฏ๋ก ๋ช ์์ ์์ฑ์๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
์์ ํ์ง ์์ต๋๋ค. ๋ฒกํฐ๊ฐ ๊ฐ๋ ์ฐจ๋ฉด ๋ฉ๋ชจ๋ฆฌ๊ฐ ๋ค์ ํ ๋น๋ฉ๋๋ค. ๋ฉ๋ชจ๋ฆฌ ์ฌํ ๋น ์์ ์ด ์คํจํ์ฌ ์์ธ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. ํ์ค::bad_alloc. ์ด ๊ฒฝ์ฐ ํฌ์ธํฐ๊ฐ ์์ค๋๊ณ ์์ฑ๋ ๊ฐ์ฒด๊ฐ ์ญ์ ๋์ง ์์ต๋๋ค.
์์ ํ ์๋ฃจ์ ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. ๊ณ ์ _ptr๋ฒกํฐ๊ฐ ๋ฉ๋ชจ๋ฆฌ ์ฌํ ๋น์ ์๋ํ๊ธฐ ์ ์ ํฌ์ธํฐ๋ฅผ ์์ ํ๊ฒ ๋ฉ๋๋ค.
xxx.push_back(std::unique_ptr<X>(new X))
C++14๋ถํฐ 'std::make_unique'๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
xxx.push_back(std::make_unique<X>())
์ด๋ฌํ ์ ํ์ ๊ฒฐํจ์ LLVM์ ์ค์ํ์ง ์์ต๋๋ค. ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ ๋นํ ์ ์์ผ๋ฉด ์ปดํ์ผ๋ฌ๋ ๋จ์ํ ์ค์ง๋ฉ๋๋ค. ๊ทธ๋ฌ๋ ์ฅ๊ธฐ๊ฐ ์์ฉ ํ๋ก๊ทธ๋จ์ ๊ฒฝ์ฐ
๋ฐ๋ผ์ ์ด ์ฝ๋๊ฐ LLVM์ ์ค์ง์ ์ธ ์ํ์ ๊ฐํ์ง๋ ์์ง๋ง ์ด ์ค๋ฅ ํจํด์ ๋ํด ์ด์ผ๊ธฐํ๋ ๊ฒ์ด ์ ์ฉํ๊ณ PVS-Studio ๋ถ์๊ธฐ๊ฐ ์ด๋ฅผ ์๋ณํ๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์ ๋ค๋ ๊ฒ์ ์์์ต๋๋ค.
์ด ์ ํ์ ๊ธฐํ ๊ฒฝ๊ณ :
- V1023 [CWE-460] ์์ ์๊ฐ ์๋ ํฌ์ธํฐ๊ฐ 'emplace_back' ๋ฉ์๋๋ฅผ ํตํด 'Passes' ์ปจํ ์ด๋์ ์ถ๊ฐ๋ฉ๋๋ค. ์์ธ๊ฐ ๋ฐ์ํ๋ฉด ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ๋ฐ์ํฉ๋๋ค. PassManager.h 546
- V1023 [CWE-460] ์์ ์๊ฐ ์๋ ํฌ์ธํฐ๊ฐ 'emplace_back' ๋ฉ์๋๋ฅผ ํตํด 'AA' ์ปจํ ์ด๋์ ์ถ๊ฐ๋ฉ๋๋ค. ์์ธ๊ฐ ๋ฐ์ํ๋ฉด ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ๋ฐ์ํฉ๋๋ค. AliasAnalytics.h 324
- V1023 [CWE-460] ์์ ์๊ฐ ์๋ ํฌ์ธํฐ๊ฐ 'emplace_back' ๋ฉ์๋์ ์ํด 'ํญ๋ชฉ' ์ปจํ ์ด๋์ ์ถ๊ฐ๋ฉ๋๋ค. ์์ธ๊ฐ ๋ฐ์ํ๋ฉด ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ๋ฐ์ํฉ๋๋ค. DWARFDebugFrame.cpp 519
- V1023 [CWE-460] ์์ ์๊ฐ ์๋ ํฌ์ธํฐ๊ฐ 'emplace_back' ๋ฉ์๋์ ์ํด 'AllEdges' ์ปจํ ์ด๋์ ์ถ๊ฐ๋ฉ๋๋ค. ์์ธ๊ฐ ๋ฐ์ํ๋ฉด ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ๋ฐ์ํฉ๋๋ค. CFGMST.h 268
- V1023 [CWE-460] ์์ ์๊ฐ ์๋ ํฌ์ธํฐ๊ฐ 'emplace_back' ๋ฉ์๋์ ์ํด 'VMaps' ์ปจํ ์ด๋์ ์ถ๊ฐ๋ฉ๋๋ค. ์์ธ๊ฐ ๋ฐ์ํ๋ฉด ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ๋ฐ์ํฉ๋๋ค. SimpleLoopUnswitch.cpp 2012
- V1023 [CWE-460] ์์ ์๊ฐ ์๋ ํฌ์ธํฐ๊ฐ 'emplace_back' ๋ฉ์๋์ ์ํด 'Records' ์ปจํ ์ด๋์ ์ถ๊ฐ๋ฉ๋๋ค. ์์ธ๊ฐ ๋ฐ์ํ๋ฉด ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ๋ฐ์ํฉ๋๋ค. FDRLogBuilder.h 30
- V1023 [CWE-460] ์์ ์๊ฐ ์๋ ํฌ์ธํฐ๊ฐ 'emplace_back' ๋ฉ์๋์ ์ํด 'PendingSubmodules' ์ปจํ ์ด๋์ ์ถ๊ฐ๋ฉ๋๋ค. ์์ธ๊ฐ ๋ฐ์ํ๋ฉด ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ๋ฐ์ํฉ๋๋ค. ModuleMap.cpp 810
- V1023 [CWE-460] ์์ ์๊ฐ ์๋ ํฌ์ธํฐ๊ฐ 'emplace_back' ๋ฉ์๋์ ์ํด 'Objects' ์ปจํ ์ด๋์ ์ถ๊ฐ๋ฉ๋๋ค. ์์ธ๊ฐ ๋ฐ์ํ๋ฉด ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ๋ฐ์ํฉ๋๋ค. DebugMap.cpp 88
- V1023 [CWE-460] ์์ ์๊ฐ ์๋ ํฌ์ธํฐ๊ฐ 'emplace_back' ๋ฉ์๋์ ์ํด 'Strategies' ์ปจํ ์ด๋์ ์ถ๊ฐ๋ฉ๋๋ค. ์์ธ๊ฐ ๋ฐ์ํ๋ฉด ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ๋ฐ์ํฉ๋๋ค. llvm-isel-fuzzer.cpp 60
- V1023 [CWE-460] ์์ ์๊ฐ ์๋ ํฌ์ธํฐ๊ฐ 'emplace_back' ๋ฉ์๋๋ฅผ ํตํด '์์ ์' ์ปจํ ์ด๋์ ์ถ๊ฐ๋ฉ๋๋ค. ์์ธ๊ฐ ๋ฐ์ํ๋ฉด ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ๋ฐ์ํฉ๋๋ค. llvm-stress.cpp 685
- V1023 [CWE-460] ์์ ์๊ฐ ์๋ ํฌ์ธํฐ๊ฐ 'emplace_back' ๋ฉ์๋๋ฅผ ํตํด '์์ ์' ์ปจํ ์ด๋์ ์ถ๊ฐ๋ฉ๋๋ค. ์์ธ๊ฐ ๋ฐ์ํ๋ฉด ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ๋ฐ์ํฉ๋๋ค. llvm-stress.cpp 686
- V1023 [CWE-460] ์์ ์๊ฐ ์๋ ํฌ์ธํฐ๊ฐ 'emplace_back' ๋ฉ์๋๋ฅผ ํตํด '์์ ์' ์ปจํ ์ด๋์ ์ถ๊ฐ๋ฉ๋๋ค. ์์ธ๊ฐ ๋ฐ์ํ๋ฉด ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ๋ฐ์ํฉ๋๋ค. llvm-stress.cpp 688
- V1023 [CWE-460] ์์ ์๊ฐ ์๋ ํฌ์ธํฐ๊ฐ 'emplace_back' ๋ฉ์๋๋ฅผ ํตํด '์์ ์' ์ปจํ ์ด๋์ ์ถ๊ฐ๋ฉ๋๋ค. ์์ธ๊ฐ ๋ฐ์ํ๋ฉด ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ๋ฐ์ํฉ๋๋ค. llvm-stress.cpp 689
- V1023 [CWE-460] ์์ ์๊ฐ ์๋ ํฌ์ธํฐ๊ฐ 'emplace_back' ๋ฉ์๋๋ฅผ ํตํด '์์ ์' ์ปจํ ์ด๋์ ์ถ๊ฐ๋ฉ๋๋ค. ์์ธ๊ฐ ๋ฐ์ํ๋ฉด ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ๋ฐ์ํฉ๋๋ค. llvm-stress.cpp 690
- V1023 [CWE-460] ์์ ์๊ฐ ์๋ ํฌ์ธํฐ๊ฐ 'emplace_back' ๋ฉ์๋๋ฅผ ํตํด '์์ ์' ์ปจํ ์ด๋์ ์ถ๊ฐ๋ฉ๋๋ค. ์์ธ๊ฐ ๋ฐ์ํ๋ฉด ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ๋ฐ์ํฉ๋๋ค. llvm-stress.cpp 691
- V1023 [CWE-460] ์์ ์๊ฐ ์๋ ํฌ์ธํฐ๊ฐ 'emplace_back' ๋ฉ์๋๋ฅผ ํตํด '์์ ์' ์ปจํ ์ด๋์ ์ถ๊ฐ๋ฉ๋๋ค. ์์ธ๊ฐ ๋ฐ์ํ๋ฉด ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ๋ฐ์ํฉ๋๋ค. llvm-stress.cpp 692
- V1023 [CWE-460] ์์ ์๊ฐ ์๋ ํฌ์ธํฐ๊ฐ 'emplace_back' ๋ฉ์๋๋ฅผ ํตํด '์์ ์' ์ปจํ ์ด๋์ ์ถ๊ฐ๋ฉ๋๋ค. ์์ธ๊ฐ ๋ฐ์ํ๋ฉด ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ๋ฐ์ํฉ๋๋ค. llvm-stress.cpp 693
- V1023 [CWE-460] ์์ ์๊ฐ ์๋ ํฌ์ธํฐ๊ฐ 'emplace_back' ๋ฉ์๋๋ฅผ ํตํด '์์ ์' ์ปจํ ์ด๋์ ์ถ๊ฐ๋ฉ๋๋ค. ์์ธ๊ฐ ๋ฐ์ํ๋ฉด ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ๋ฐ์ํฉ๋๋ค. llvm-stress.cpp 694
- V1023 [CWE-460] ์์ ์๊ฐ ์๋ ํฌ์ธํฐ๊ฐ 'emplace_back' ๋ฉ์๋๋ฅผ ํตํด 'Operands' ์ปจํ ์ด๋์ ์ถ๊ฐ๋ฉ๋๋ค. ์์ธ๊ฐ ๋ฐ์ํ๋ฉด ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ๋ฐ์ํฉ๋๋ค. GlobalISelEmitter.cpp 1911
- V1023 [CWE-460] ์์ ์๊ฐ ์๋ ํฌ์ธํฐ๊ฐ 'emplace_back' ๋ฉ์๋์ ์ํด 'Stash' ์ปจํ ์ด๋์ ์ถ๊ฐ๋ฉ๋๋ค. ์์ธ๊ฐ ๋ฐ์ํ๋ฉด ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ๋ฐ์ํฉ๋๋ค. GlobalISelEmitter.cpp 2100
- V1023 [CWE-460] ์์ ์๊ฐ ์๋ ํฌ์ธํฐ๊ฐ 'emplace_back' ๋ฉ์๋๋ฅผ ํตํด 'Matchers' ์ปจํ ์ด๋์ ์ถ๊ฐ๋ฉ๋๋ค. ์์ธ๊ฐ ๋ฐ์ํ๋ฉด ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ๋ฐ์ํฉ๋๋ค. GlobalISelEmitter.cpp 2702
๊ฒฐ๋ก
์ด 60๋ฒ์ ๊ฒฝ๊ณ ๋ฅผ ๋ฐ๋ นํ๊ณ ์ค๋จํ์ต๋๋ค. PVS-Studio ๋ถ์๊ธฐ๊ฐ LLVM์์ ๊ฐ์งํ๋ ๋ค๋ฅธ ๊ฒฐํจ์ด ์์ต๋๊น? ๋ค, ์์ด์. ๊ทธ๋ฌ๋ ๊ธฐ์ฌ์ ์ฝ๋ ์กฐ๊ฐ์ ์์ฑํ๊ณ ์์ ๋๋ ๋ฆ์ ์ ๋ , ์๋ ์คํ๋ ค ๋ฐค์ด์๊ณ , ์ด์ ๋ ํ๋ฃจ๋ผ๊ณ ๋ถ๋ฅผ ์๊ฐ์ด๋ผ๊ณ ๊ฒฐ์ ํ์ต๋๋ค.
์ด ๋ด์ฉ์ด ํฅ๋ฏธ๋ก์ฐ์ จ๊ธฐ๋ฅผ ๋ฐ๋ผ๋ฉฐ PVS-Studio ๋ถ์๊ธฐ๋ฅผ ์ฌ์ฉํด ๋ณด์๊ธธ ๋ฐ๋๋๋ค.
๋ถ์๊ธฐ๋ฅผ ๋ค์ด๋ก๋ํ๊ณ ์ง๋ขฐ์ฐพ๊ธฐ ํค๋ฅผ ์ป์ ์ ์์ต๋๋ค.
๊ฐ์ฅ ์ค์ํ ๊ฒ์ ์ ์ ๋ถ์์ ์ ๊ธฐ์ ์ผ๋ก ์ฌ์ฉํ๋ ๊ฒ์ ๋๋ค. ์ผํ์ฑ ํ์ธ, ์ ์ ๋ถ์ ๋ฐฉ๋ฒ๋ก ์ ๋์คํํ๊ธฐ ์ํด ์ฐ๋ฆฌ๊ฐ ์ํํ๋ PVS-Studio๋ ์ผ๋ฐ์ ์ธ ์๋๋ฆฌ์ค๊ฐ ์๋๋๋ค.
์ฝ๋์ ํ์ง๊ณผ ์์ ์ฑ์ ํฅ์์ํค๋ ๋ฐ ํ์ด์ด ์๊ธฐ๋ฅผ ๋ฐ๋๋๋ค!
์ด ๊ธฐ์ฌ๋ฅผ ์์ด๊ถ ์ฒญ์ค๊ณผ ๊ณต์ ํ๋ ค๋ฉด ๋ฒ์ญ ๋งํฌ์ธ Andrey Karpov๋ฅผ ์ฌ์ฉํ์ญ์์ค.
์ถ์ฒ : habr.com