PVS-Studio ๋ถ„์„๊ธฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ LLVM 8์—์„œ ๋ฒ„๊ทธ ์ฐพ๊ธฐ

PVS-Studio ๋ถ„์„๊ธฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ LLVM 8์—์„œ ๋ฒ„๊ทธ ์ฐพ๊ธฐ
PVS-Studio ๋ถ„์„๊ธฐ๋ฅผ ์‚ฌ์šฉํ•œ LLVM ํ”„๋กœ์ ํŠธ์˜ ๋งˆ์ง€๋ง‰ ์ฝ”๋“œ ๊ฒ€์‚ฌ ์ดํ›„ 8.0.0๋…„ ์ด์ƒ์ด ์ง€๋‚ฌ์Šต๋‹ˆ๋‹ค. PVS-Studio ๋ถ„์„๊ธฐ๊ฐ€ ์—ฌ์ „ํžˆ ์˜ค๋ฅ˜์™€ ์ž ์žฌ์ ์ธ ์ทจ์•ฝ์ ์„ ์‹๋ณ„ํ•˜๋Š” ์ตœ๊ณ ์˜ ๋„๊ตฌ์ธ์ง€ ํ™•์ธํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด LLVM XNUMX ๋ฆด๋ฆฌ์Šค์—์„œ ์ƒˆ๋กœ์šด ์˜ค๋ฅ˜๋ฅผ ํ™•์ธํ•˜๊ณ  ์ฐพ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์ž‘์„ฑํ•ด์•ผ ํ•  ๊ธฐ์‚ฌ

์†”์งํžˆ ๋งํ•ด์„œ ๋‚˜๋Š” ์ด ๊ธ€์„ ์“ฐ๊ณ  ์‹ถ์ง€ ์•Š์•˜๋‹ค. ์ด๋ฏธ ์—ฌ๋Ÿฌ ๋ฒˆ ํ™•์ธํ•œ ํ”„๋กœ์ ํŠธ์— ๋Œ€ํ•ด ๊ธ€์„ ์“ฐ๋Š” ๊ฒƒ์€ ํฅ๋ฏธ๋กญ์ง€ ์•Š์Šต๋‹ˆ๋‹ค(1, 2, 3). ์ƒˆ๋กœ์šด ๊ฒƒ์— ๋Œ€ํ•ด ์“ฐ๋Š” ๊ฒƒ์ด ๋” ์ข‹์ง€๋งŒ ์„ ํƒ์˜ ์—ฌ์ง€๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

LLVM์˜ ์ƒˆ ๋ฒ„์ „์ด ์ถœ์‹œ๋˜๊ฑฐ๋‚˜ ์—…๋ฐ์ดํŠธ๋  ๋•Œ๋งˆ๋‹ค Clang ์ •์  ๋ถ„์„๊ธฐ, ์šฐ๋ฆฌ๋Š” ๋ฉ”์ผ๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์œ ํ˜•์˜ ์งˆ๋ฌธ์„ ๋ฐ›์Šต๋‹ˆ๋‹ค:

๋ณด์„ธ์š”, Clang ์ •์  ๋ถ„์„๊ธฐ์˜ ์ƒˆ ๋ฒ„์ „์—์„œ๋Š” ์ƒˆ๋กœ์šด ์˜ค๋ฅ˜๋ฅผ ์ฐพ๋Š” ๋ฐฉ๋ฒ•์„ ๋ฐฐ์› ์Šต๋‹ˆ๋‹ค! PVS-Studio ์‚ฌ์šฉ์˜ ๊ด€๋ จ์„ฑ์ด ๊ฐ์†Œํ•˜๊ณ  ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. Clang์€ ์ด์ „๋ณด๋‹ค ๋” ๋งŽ์€ ์˜ค๋ฅ˜๋ฅผ ๋ฐœ๊ฒฌํ•˜๊ณ  PVS-Studio์˜ ๊ธฐ๋Šฅ์„ ๋”ฐ๋ผ์žก์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์— ๋Œ€ํ•ด ์–ด๋–ป๊ฒŒ ์ƒ๊ฐํ•˜์„ธ์š”?

์ด์— ๋Œ€ํ•ด ์ €๋Š” ํ•ญ์ƒ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋Œ€๋‹ตํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋„ ํ•œ๊ฐ€๋กœ์ด ์•‰์•„ ์žˆ์ง€ ์•Š์Šต๋‹ˆ๋‹ค! PVS-Studio ๋ถ„์„๊ธฐ์˜ ๊ธฐ๋Šฅ์ด ํฌ๊ฒŒ ํ–ฅ์ƒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‹ˆ ๊ฑฑ์ •ํ•˜์ง€ ๋งˆ์„ธ์š”. ์šฐ๋ฆฌ๋Š” ์ด์ „์ฒ˜๋Ÿผ ๊ณ„์†ํ•ด์„œ ์ด๋Œ์–ด ๊ฐˆ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ถˆํ–‰ํžˆ๋„ ์ด๊ฒƒ์€ ์ž˜๋ชป๋œ ๋Œ€๋‹ต์ž…๋‹ˆ๋‹ค. ๊ฑฐ๊ธฐ์—๋Š” ์ฆ๊ฑฐ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ทธ๊ฒƒ์ด ๋ฐ”๋กœ ๋‚ด๊ฐ€ ์ง€๊ธˆ ์ด ๊ธ€์„ ์“ฐ๊ณ  ์žˆ๋Š” ์ด์œ ์ด๋‹ค. ๊ทธ๋ž˜์„œ LLVM ํ”„๋กœ์ ํŠธ๋ฅผ ๋‹ค์‹œ ํ•œ๋ฒˆ ํ™•์ธํ•ด ๋ณด๋‹ˆ ๋‹ค์–‘ํ•œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ๊ฒฌ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ ๋‚˜์—๊ฒŒ ํฅ๋ฏธ๋กœ์› ๋˜ ๊ฒƒ๋“ค์„ ๋ณด์—ฌ ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค. Clang ์ •์  ๋ถ„์„๊ธฐ๋Š” ์ด๋Ÿฌํ•œ ์˜ค๋ฅ˜๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค(๋˜๋Š” Clang์˜ ๋„์›€์„ ๋ฐ›์•„ ์ด๋ฅผ ์ฐพ๋Š” ๊ฒƒ์ด ๋งค์šฐ ๋ถˆํŽธํ•ฉ๋‹ˆ๋‹ค). ํ•˜์ง€๋งŒ ์šฐ๋ฆฌ๋Š” ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฒŒ๋‹ค๊ฐ€ ๋‚˜๋Š” ์ด ๋ชจ๋“  ์˜ค๋ฅ˜๋ฅผ ์–ด๋Š ๋‚  ์ €๋…์— ๋ฐœ๊ฒฌํ•˜๊ณ  ์ ์—ˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ๊ธฐ์‚ฌ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๋ฐ ๋ช‡ ์ฃผ๊ฐ€ ๊ฑธ๋ ธ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ด ๋ชจ๋“  ๊ฒƒ์„ ํ…์ŠคํŠธ๋กœ ํ‘œํ˜„ํ•  ์ˆ˜ ์—†์—ˆ์Šต๋‹ˆ๋‹ค :).

๊ทธ๊ฑด ๊ทธ๋ ‡๊ณ , ์˜ค๋ฅ˜์™€ ์ž ์žฌ์ ์ธ ์ทจ์•ฝ์ ์„ ์‹๋ณ„ํ•˜๊ธฐ ์œ„ํ•ด PVS-Studio ๋ถ„์„๊ธฐ์—์„œ ์–ด๋–ค ๊ธฐ์ˆ ์ด ์‚ฌ์šฉ๋˜๋Š”์ง€์— ๊ด€์‹ฌ์ด ์žˆ๋‹ค๋ฉด ์ด์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ๋…ธํŠธ.

์‹ ๊ทœ ๋ฐ ๊ธฐ์กด ์ง„๋‹จ

์ด๋ฏธ ์–ธ๊ธ‰ํ•œ ๋ฐ”์™€ ๊ฐ™์ด, ์•ฝ 3๋…„ ์ „์— LLVM ํ”„๋กœ์ ํŠธ๋ฅผ ๋‹ค์‹œ ํ•œ๋ฒˆ ์ ๊ฒ€ํ•˜์—ฌ ๋ฐœ๊ฒฌ๋œ ์˜ค๋ฅ˜๋ฅผ ์ˆ˜์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ ์ด ๊ธฐ์‚ฌ์—์„œ๋Š” ์ƒˆ๋กœ์šด ์˜ค๋ฅ˜ ๋ฐฐ์น˜๋ฅผ ์ œ์‹œํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ๋ฒ„๊ทธ๊ฐ€ ๋ฐœ๊ฒฌ๋œ ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ์—ฌ๊ธฐ์—๋Š” XNUMX๊ฐ€์ง€ ์ด์œ ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค:

  1. LLVM ํ”„๋กœ์ ํŠธ๋Š” ์ง„ํ™”ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ๊ธฐ์กด ์ฝ”๋“œ๋ฅผ ๋ณ€๊ฒฝํ•˜๊ณ  ์ƒˆ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹น์—ฐํžˆ ์ˆ˜์ •๋˜๊ณ  ์ž‘์„ฑ๋œ ์ฝ”๋“œ์—๋Š” ์ƒˆ๋กœ์šด ์˜ค๋ฅ˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์ •์  ๋ถ„์„์„ ๊ฐ€๋” ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ์ •๊ธฐ์ ์œผ๋กœ ์‚ฌ์šฉํ•ด์•ผ ํ•จ์„ ๋ถ„๋ช…ํžˆ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ์šฐ๋ฆฌ ๊ธฐ์‚ฌ์—์„œ๋Š” PVS-Studio ๋ถ„์„๊ธฐ์˜ ๊ธฐ๋Šฅ์„ ์ž˜ ๋ณด์—ฌ ์ฃผ์ง€๋งŒ ์ด๋Š” ์ฝ”๋“œ ํ’ˆ์งˆ์„ ๊ฐœ์„ ํ•˜๊ณ  ์˜ค๋ฅ˜ ์ˆ˜์ • ๋น„์šฉ์„ ์ค„์ด๋Š” ๊ฒƒ๊ณผ๋Š” ์•„๋ฌด๋Ÿฐ ๊ด€๋ จ์ด ์—†์Šต๋‹ˆ๋‹ค. ์ •์  ์ฝ”๋“œ ๋ถ„์„๊ธฐ๋ฅผ ์ •๊ธฐ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜์„ธ์š”!
  2. ๊ธฐ์กด ์ง„๋‹จ์„ ๋งˆ๋ฌด๋ฆฌํ•˜๊ณ  ๊ฐœ์„ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋ถ„์„๊ธฐ๋Š” ์ด์ „ ์Šค์บ” ์ค‘์— ๋ฐœ๊ฒฌํ•˜์ง€ ๋ชปํ•œ ์˜ค๋ฅ˜๋ฅผ ์‹๋ณ„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  3. 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 ๊ฒฝ๊ณ : V501 [CWE-570] '||' ์™ผ์ชฝ๊ณผ ์˜ค๋ฅธ์ชฝ์— ๋™์ผํ•œ ํ•˜์œ„ ํ‘œํ˜„์‹ 'Name.startswith("avx512.mask.permvar.")'์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์šด์˜์ž. ์ž๋™ ์—…๊ทธ๋ ˆ์ด๋“œ.cpp 73

์ด๋ฆ„์ด ํ•˜์œ„ ๋ฌธ์ž์—ด "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 ๊ฒฝ๊ณ : V502 [CWE-783] ์•„๋งˆ๋„ '?:' ์—ฐ์‚ฐ์ž๊ฐ€ ์˜ˆ์ƒํ–ˆ๋˜ ๊ฒƒ๊ณผ ๋‹ค๋ฅธ ๋ฐฉ์‹์œผ๋กœ ์ž‘๋™ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. '?:' ์—ฐ์‚ฐ์ž๋Š” '==' ์—ฐ์‚ฐ์ž๋ณด๋‹ค ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋‚ฎ์Šต๋‹ˆ๋‹ค. PPCTargetTransformInfo.cpp 404

๋‚ด ์ƒ๊ฐ์— ์ด๊ฒƒ์€ ๋งค์šฐ ์•„๋ฆ„๋‹ค์šด ์‹ค์ˆ˜์ด๋‹ค. ๋„ค, ์ œ๊ฐ€ ์•„๋ฆ„๋‹ค์›€์— ๋Œ€ํ•ด ์ด์ƒํ•œ ์ƒ๊ฐ์„ ๊ฐ–๊ณ  ์žˆ๋‹ค๋Š” ๊ฑธ ์•Œ์•„์š” :).

์ด์ œ ๋”ฐ๋ฅด๋ฉด ์šด์˜์ž ์šฐ์„ ์ˆœ์œ„, ํ‘œํ˜„์‹์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ‰๊ฐ€๋ฉ๋‹ˆ๋‹ค.

(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 ๊ฒฝ๊ณ : V522 [CWE-476] ๋„ ํฌ์ธํ„ฐ 'LHS'์˜ ์—ญ์ฐธ์กฐ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. TGParser.cpp 2152

ํฌ์ธํ„ฐ์˜ ๊ฒฝ์šฐ ์ขŒํšŒ์ „ 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 ๊ฒฝ๊ณ : V570 'Identifier->Type' ๋ณ€์ˆ˜๋Š” ์ž์‹ ์—๊ฒŒ ํ• ๋‹น๋ฉ๋‹ˆ๋‹ค. FormatTokenLexer.cpp 249

๋ณ€์ˆ˜ ์ž์ฒด๋ฅผ ํ• ๋‹นํ•˜๋Š” ๊ฒƒ์€ ์˜๋ฏธ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ์•„๋งˆ๋„ ๊ทธ๋“ค์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์“ฐ๊ณ  ์‹ถ์—ˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

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 ๊ฒฝ๊ณ : V622 [CWE-478] 'switch' ๋ฌธ ๊ฒ€์‚ฌ๋ฅผ ๊ณ ๋ คํ•˜์„ธ์š”. ์ฒซ ๋ฒˆ์งธ 'case' ์—ฐ์‚ฐ์ž๊ฐ€ ๋ˆ„๋ฝ๋˜์—ˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. SystemZAsmParser.cpp 652

์ดˆ๋ฐ˜์—๋Š” ๋งค์šฐ ์ˆ˜์ƒํ•œ ์šด์˜์ž๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค ํ•˜๋‹ค. ์—ฌ๊ธฐ์— ๋‹ค๋ฅธ ๊ฒƒ์„ ์“ฐ๋Š” ๊ฒƒ์„ ์žŠ์—ˆ๋‚˜์š”?

์กฐ๊ฐ 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 ๊ฒฝ๊ณ : V595 [CWE-476] 'Callee' ํฌ์ธํ„ฐ๋Š” nullptr์— ๋Œ€ํ•ด ํ™•์ธ๋˜๊ธฐ ์ „์— ํ™œ์šฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋ผ์ธ ํ™•์ธ: 172, 174. AMDGPUInline.cpp 172

ํฌ์ธํ„ฐ ์ˆ˜์‹ ์ž ์ฒ˜์Œ์—๋Š” ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ ์—ญ์ฐธ์กฐ๋ฉ๋‹ˆ๋‹ค. 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 ๊ฒฝ๊ณ : V629 [CWE-190] '~(Size - 1) << 1' ํ‘œํ˜„์‹ ๊ฒ€์‚ฌ๋ฅผ ๊ณ ๋ คํ•˜์„ธ์š”. 32๋น„ํŠธ ์œ ํ˜•์œผ๋กœ์˜ ํ›„์† ํ™•์žฅ์„ ํ†ตํ•ด 64๋น„ํŠธ ๊ฐ’์˜ ๋น„ํŠธ ์ด๋™. AArch64AddressingModes.h 260

๋ฒ„๊ทธ๊ฐ€ ์•„๋‹ ์ˆ˜๋„ ์žˆ์œผ๋ฉฐ ์ฝ”๋“œ๋Š” ์˜๋„ํ•œ ๋Œ€๋กœ ์ •ํ™•ํ•˜๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋Š” ๋ถ„๋ช…ํžˆ ๋งค์šฐ ์˜์‹ฌ์Šค๋Ÿฌ์šด ๊ณณ์ด๋ฏ€๋กœ ํ™•์ธ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

๋ณ€์ˆ˜๋ฅผ ๋งํ•ด๋ณด์ž ํฌ๊ธฐ ๋Š” 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 ๊ฒฝ๊ณ : V646 [CWE-670] ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋กœ์ง์„ ๊ฒ€์‚ฌํ•ด ๋ณด์„ธ์š”. 'else' ํ‚ค์›Œ๋“œ๊ฐ€ ๋ˆ„๋ฝ๋˜์—ˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. AMDGPUAsmParser.cpp 5655

์—ฌ๊ธฐ์—๋Š” ์‹ค์ˆ˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ ๋ธ”๋ก ์ดํ›„ 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 ๋ถ„์„๊ธฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ LLVM 8์—์„œ ๋ฒ„๊ทธ ์ฐพ๊ธฐ

PVS-Studio ๊ฒฝ๊ณ : V708 [CWE-758] ์œ„ํ—˜ํ•œ ๊ตฌ์„ฑ์ด ์‚ฌ์šฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. 'FeaturesMap[Op] = FeatureMap.size()', ์—ฌ๊ธฐ์„œ 'FeaturesMap'์€ 'map' ํด๋ž˜์Šค์— ์†ํ•ฉ๋‹ˆ๋‹ค. ์ด๋กœ ์ธํ•ด ์ •์˜๋˜์ง€ ์•Š์€ ๋™์ž‘์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. RISCVCompressInstEmitter.cpp 490

๋ฌธ์ œ ๋ผ์ธ:

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] 'NType' ๋ณ€์ˆ˜์—๋Š” 1663๋ฒˆ ์—ฐ์†์œผ๋กœ ๊ฐ’์ด ํ• ๋‹น๋ฉ๋‹ˆ๋‹ค. ์•„๋งˆ๋„ ์ด๊ฒƒ์€ ์‹ค์ˆ˜์ผ ๊ฒƒ์ด๋‹ค. ๋ผ์ธ ํ™•์ธ: 1664, 1664. MachOObjectFile.cpp XNUMX

๋‚˜๋Š” ์—ฌ๊ธฐ์— ์ง„์งœ ์‹ค์ˆ˜๊ฐ€ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ถˆํ•„์š”ํ•œ ๋ฐ˜๋ณต ํ• ๋‹น์ผ ๋ฟ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์—ฌ์ „ํžˆ ์‹ค์ˆ˜์ž…๋‹ˆ๋‹ค.

๋น„์Šทํ•˜๊ฒŒ :

  • 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 ๊ฒฝ๊ณ : V547 [CWE-571] 'nextByte != 0x90' ํ‘œํ˜„์‹์€ ํ•ญ์ƒ ์ฐธ์ž…๋‹ˆ๋‹ค. X86DisassemblerDecoder.cpp 379

ํ™•์ธํ•˜๋Š” ๊ฒƒ์€ ์˜๋ฏธ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๋ณ€ํ•˜๊ธฐ ์‰ฌ์šด ๋‹ค์Œ๋ฐ”์ดํŠธ ํ•ญ์ƒ ๊ฐ’๊ณผ ๊ฐ™์ง€ ์•Š์Œ 0 X 90, ์ด๋Š” ์ด์ „ ํ™•์ธ์—์„œ ์ด์–ด์ง‘๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์ผ์ข…์˜ ๋…ผ๋ฆฌ์  ์˜ค๋ฅ˜์ž…๋‹ˆ๋‹ค.

์กฐ๊ฐ N29 - N...: ํ•ญ์ƒ ์ฐธ/๊ฑฐ์ง“ ์กฐ๊ฑด

๋ถ„์„๊ธฐ๋Š” ์ „์ฒด ์กฐ๊ฑด(V547) ๋˜๋Š” ๊ทธ ์ผ๋ถ€(V560)์€ ํ•ญ์ƒ ์ฐธ์ด๊ฑฐ๋‚˜ ๊ฑฐ์ง“์ž…๋‹ˆ๋‹ค. ์ด๋Š” ์‹ค์ œ ์˜ค๋ฅ˜๊ฐ€ ์•„๋‹ˆ๋ผ ๋‹จ์ˆœํžˆ ์—‰์„ฑํ•œ ์ฝ”๋“œ, ๋งคํฌ๋กœ ํ™•์žฅ์˜ ๊ฒฐ๊ณผ ๋“ฑ์ธ ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์‹ค์ œ ๋…ผ๋ฆฌ์  ์˜ค๋ฅ˜๋Š” ๋•Œ๋•Œ๋กœ ๋ฐœ์ƒํ•˜๋ฏ€๋กœ ์ด๋Ÿฌํ•œ ๋ชจ๋“  ๊ฒฝ๊ณ ๋ฅผ ์‚ดํŽด๋ณด๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค์Œ ์ฝ”๋“œ ์„น์…˜์€ ์˜์‹ฌ์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค.

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 ๊ฒฝ๊ณ : V560 [CWE-570] ์กฐ๊ฑด์‹์˜ ์ผ๋ถ€๊ฐ€ ํ•ญ์ƒ ๊ฑฐ์ง“์ž…๋‹ˆ๋‹ค: RegNo == 0xe. ARMDisassembler.cpp 939

์ƒ์ˆ˜ 0xE๋Š” 14์ง„์ˆ˜ ๊ฐ’ XNUMX์ž…๋‹ˆ๋‹ค. ์‹œํ—˜ ๋“ฑ๋ก ๋ฒˆํ˜ธ == 0xe ๋ง์ด ์•ˆ ๋˜๋‹ˆ๊นŒ ๋งŒ์•ฝ์— ๋“ฑ๋ก๋ฒˆํ˜ธ > 13, ๊ทธ๋Ÿฌ๋ฉด ํ•จ์ˆ˜ ์‹คํ–‰์ด ์™„๋ฃŒ๋ฉ๋‹ˆ๋‹ค.

ID V547 ๋ฐ V560์—๋Š” ๋‹ค๋ฅธ ๋งŽ์€ ๊ฒฝ๊ณ ๊ฐ€ ์žˆ์—ˆ์ง€๋งŒ V595, ๋‚˜๋Š” ์ด๋Ÿฌํ•œ ๊ฒฝ๊ณ ๋ฅผ ์—ฐ๊ตฌํ•˜๋Š” ๋ฐ ๊ด€์‹ฌ์ด ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ์‚ฌ๋ฅผ ์ž‘์„ฑํ•˜๊ธฐ์— ์ถฉ๋ถ„ํ•œ ์ž๋ฃŒ๊ฐ€ ์žˆ๋‹ค๋Š” ๊ฒƒ์€ ์ด๋ฏธ ๋ถ„๋ช…ํ–ˆ์Šต๋‹ˆ๋‹ค. :). ๋”ฐ๋ผ์„œ PVS-Studio๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ LLVM์—์„œ ์ด๋Ÿฌํ•œ ์œ ํ˜•์˜ ์˜ค๋ฅ˜๋ฅผ ์–ผ๋งˆ๋‚˜ ๋งŽ์ด ์‹๋ณ„ํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์•Œ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ์œ ๋ฐœ ์š”์ธ์„ ์—ฐ๊ตฌํ•˜๋Š” ๊ฒƒ์ด ์™œ ์ง€๋ฃจํ•œ์ง€ ์˜ˆ๋ฅผ ๋“ค์–ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๋ถ„์„๊ธฐ๋Š” ๋‹ค์Œ ์ฝ”๋“œ์— ๋Œ€ํ•ด ๊ฒฝ๊ณ ๋ฅผ ๋ฐœํ–‰ํ•˜๋Š” ๊ฒƒ์ด ์ ˆ๋Œ€์ ์œผ๋กœ ์˜ณ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด๊ฒƒ์€ ์‹ค์ˆ˜๊ฐ€ ์•„๋‹ˆ๋‹ค.

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 ๊ฒฝ๊ณ : V612 [CWE-670] ๋ฃจํ”„ ๋‚ด์˜ ๋ฌด์กฐ๊ฑด '๋ฐ˜ํ™˜'์ž…๋‹ˆ๋‹ค. R600OptimizeVectorRegisters.cpp 63

์ด๋Š” ์˜ค๋ฅ˜์ด๊ฑฐ๋‚˜ ์ฝ”๋“œ๋ฅผ ์ฝ๋Š” ํ”„๋กœ๊ทธ๋ž˜๋จธ์—๊ฒŒ ์„ค๋ช…ํ•˜๊ธฐ ์œ„ํ•œ ํŠน์ • ๊ธฐ์ˆ ์ž…๋‹ˆ๋‹ค. ์ด ๋””์ž์ธ์€ ๋‚˜์—๊ฒŒ ์•„๋ฌด๊ฒƒ๋„ ์„ค๋ช…ํ•˜์ง€ ์•Š๊ณ  ๋งค์šฐ ์˜์‹ฌ์Šค๋Ÿฌ์›Œ ๋ณด์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ์‹์œผ๋กœ ์“ฐ์ง€ ์•Š๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค :).

ํ”ผ๊ณคํ•œ? ๊ทธ๋Ÿฐ ๋‹ค์Œ ์ฐจ๋‚˜ ์ปคํ”ผ๋ฅผ ๋งŒ๋“ค ์‹œ๊ฐ„์ž…๋‹ˆ๋‹ค.

PVS-Studio ๋ถ„์„๊ธฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ LLVM 8์—์„œ ๋ฒ„๊ทธ ์ฐพ๊ธฐ

์ƒˆ๋กœ์šด ์ง„๋‹จ์œผ๋กœ ์‹๋ณ„๋œ ๊ฒฐํ•จ

์˜ค๋ž˜๋œ ์ง„๋‹จ ๊ธฐ๋Šฅ์„ 30๋ฒˆ ํ™œ์„ฑํ™”ํ•˜๋ฉด ์ถฉ๋ถ„ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ด์ œ ๋ถ„์„๊ธฐ์— ๋‚˜ํƒ€๋‚œ ์ƒˆ๋กœ์šด ์ง„๋‹จ์œผ๋กœ ์–ด๋–ค ํฅ๋ฏธ๋กœ์šด ์ ์„ ์ฐพ์„ ์ˆ˜ ์žˆ๋Š”์ง€ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด์ „ ์ฒดํฌ ๋ฌด๋Šฌ. ์ด ๊ธฐ๊ฐ„ ๋™์•ˆ ์ด 66๊ฐœ์˜ ๋ฒ”์šฉ ์ง„๋‹จ์ด C++ ๋ถ„์„๊ธฐ์— ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์กฐ๊ฐ 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 ๊ฒฝ๊ณ : V779 [CWE-561] ์—ฐ๊ฒฐํ•  ์ˆ˜ ์—†๋Š” ์ฝ”๋“œ๊ฐ€ ๊ฐ์ง€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์˜ค๋ฅ˜๊ฐ€ ์žˆ์„ ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ExecutionUtils.cpp 146

๋ณด์‹œ๋‹ค์‹œํ”ผ, ์—ฐ์‚ฐ์ž์˜ ๋‘ ์ง€์  ๋ชจ๋‘ 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 ๊ฒฝ๊ณ : V784 ๋น„ํŠธ ๋งˆ์Šคํฌ์˜ ํฌ๊ธฐ๋Š” ์ฒซ ๋ฒˆ์งธ ํ”ผ์—ฐ์‚ฐ์ž์˜ ํฌ๊ธฐ๋ณด๋‹ค ์ž‘์Šต๋‹ˆ๋‹ค. ์ด๋กœ ์ธํ•ด ๋” ๋†’์€ ๋น„ํŠธ๊ฐ€ ์†์‹ค๋ฉ๋‹ˆ๋‹ค. ๋Ÿฐํƒ€์ž„Dyld.cpp 815

๊ธฐ๋Šฅ์„ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š” 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 ๊ฒฝ๊ณ : V1028 [CWE-190] ์˜ค๋ฒ„ํ”Œ๋กœ๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. 'NumElts * Scale' ์—ฐ์‚ฐ์ž์˜ ํ”ผ์—ฐ์‚ฐ์ž๋ฅผ ๊ฒฐ๊ณผ๊ฐ€ ์•„๋‹Œ 'size_t' ์œ ํ˜•์œผ๋กœ ์บ์ŠคํŒ…ํ•˜๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•˜์„ธ์š”. X86ISelLowering.h 1577

์œ ํ˜• ๋ณ€์ˆ˜๋ฅผ ๊ณฑํ•  ๋•Œ ์˜ค๋ฒ„ํ”Œ๋กœ๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ๋ช…์‹œ์  ์œ ํ˜• ์บ์ŠคํŒ…์ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. INT. ๊ทธ๋Ÿฌ๋‚˜ ์—ฌ๊ธฐ์„œ ๋ช…์‹œ์ ์ธ ์œ ํ˜• ์บ์ŠคํŒ…์€ ์˜ค๋ฒ„ํ”Œ๋กœ๋ฅผ ๋ฐฉ์ง€ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋จผ์ € ๋ณ€์ˆ˜๊ฐ€ ๊ณฑํ•ด์ง€๊ณ  ๋‚˜์„œ์•ผ 32๋น„ํŠธ ๊ณฑ์…ˆ ๊ฒฐ๊ณผ๊ฐ€ ๋‹ค์Œ ์œ ํ˜•์œผ๋กœ ํ™•์žฅ๋ฉ๋‹ˆ๋‹ค. size_t.

์กฐ๊ฐ 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;
  }
  ....
}

V778 [CWE-682] ๋‘ ๊ฐœ์˜ ์œ ์‚ฌํ•œ ์ฝ”๋“œ ์กฐ๊ฐ์ด ๋ฐœ๊ฒฌ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์•„๋งˆ๋„ ์ด๋Š” ์˜คํƒ€์ด๋ฏ€๋กœ 'Op1' ๋Œ€์‹  'Op0' ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. InstCombineCompares.cpp 5507

์ด ์ƒˆ๋กœ์šด ํฅ๋ฏธ๋กœ์šด ์ง„๋‹จ์€ ์ฝ”๋“œ ์กฐ๊ฐ์ด ๋ณต์‚ฌ๋˜๊ณ  ๊ทธ ์•ˆ์˜ ์ผ๋ถ€ ์ด๋ฆ„์ด ๋ณ€๊ฒฝ๋˜๊ธฐ ์‹œ์ž‘ํ–ˆ์ง€๋งŒ ํ•œ ๊ณณ์—์„œ๋Š” ์ฝ”๋“œ๊ฐ€ ์ˆ˜์ •๋˜์ง€ ์•Š์€ ์ƒํ™ฉ์„ ์‹๋ณ„ํ•ฉ๋‹ˆ๋‹ค.

๋‘ ๋ฒˆ์งธ ๋ธ”๋ก์—์„œ๋Š” ๋ณ€๊ฒฝ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. 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 ๊ฒฝ๊ณ : V1001 [CWE-563] '๋ชจ๋“œ' ๋ณ€์ˆ˜๊ฐ€ ํ• ๋‹น๋˜์—ˆ์ง€๋งŒ ๊ธฐ๋Šฅ์ด ๋๋‚  ๋•Œ๊นŒ์ง€ ์‚ฌ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. SIModeRegister.cpp 48

ํ•จ์ˆ˜ ์ธ์ˆ˜์— ํด๋ž˜์Šค ๋ฉค๋ฒ„์™€ ๋™์ผํ•œ ์ด๋ฆ„์„ ์ง€์ •ํ•˜๋Š” ๊ฒƒ์€ ๋งค์šฐ ์œ„ํ—˜ํ•ฉ๋‹ˆ๋‹ค. ํ˜ผ๋ž€์Šค๋Ÿฌ์›Œ์ง€๊ธฐ๊ฐ€ ๋งค์šฐ ์‰ฝ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ ์•ž์—๋Š” ๊ทธ๋Ÿฌํ•œ ๊ฒฝ์šฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ํ‘œํ˜„์€ ์˜๋ฏธ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค:

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: ์ƒ‰์ธ ํ™•์ธ์„ ์žŠ์–ด๋ฒ„๋ ธ์Šต๋‹ˆ๋‹ค.

์ด์ „์—๋Š” ์ง„๋‹จ ํŠธ๋ฆฌ๊ฑฐ๋ง์˜ ์˜ˆ๋ฅผ ์‚ดํŽด๋ณด์•˜์Šต๋‹ˆ๋‹ค. V595. ๊ทธ ๋ณธ์งˆ์€ ํฌ์ธํ„ฐ๊ฐ€ ์ฒ˜์Œ์— ์—ญ์ฐธ์กฐ๋œ ๋‹ค์Œ ํ™•์ธ๋œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ Š์€ ์ง„๋‹จ V1004 ์˜๋ฏธ๋Š” ์ •๋ฐ˜๋Œ€์ด์ง€๋งŒ ์˜ค๋ฅ˜๋„ ๋งŽ์ด ๋“œ๋Ÿฌ๋‚ฉ๋‹ˆ๋‹ค. ํฌ์ธํ„ฐ๋ฅผ ์ฒ˜์Œ์— ํ™•์ธํ•œ ๋‹ค์Œ ์ด๋ฅผ ์žŠ์–ด๋ฒ„๋ฆฐ ์ƒํ™ฉ์„ ์‹๋ณ„ํ•ฉ๋‹ˆ๋‹ค. LLVM ๋‚ด๋ถ€์—์„œ ๋ฐœ๊ฒฌ๋œ ์ด๋Ÿฌํ•œ ์‚ฌ๋ก€๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

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

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

PVS-Studio ๊ฒฝ๊ณ : 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 ๊ฒฝ๊ณ : V1023 [CWE-460] ์†Œ์œ ์ž๊ฐ€ ์—†๋Š” ํฌ์ธํ„ฐ๊ฐ€ 'emplace_back' ๋ฉ”์†Œ๋“œ์— ์˜ํ•ด 'Strategies' ์ปจํ…Œ์ด๋„ˆ์— ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค. ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. llvm-isel-fuzzer.cpp 58

๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ปจํ…Œ์ด๋„ˆ ๋์— ์š”์†Œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ ค๋ฉด ํ‘œ์ค€::๋ฒกํ„ฐ > ๋„Œ ๊ทธ๋ƒฅ ์“ธ ์ˆ˜ ์—†์–ด 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๋Š” ์ผ๋ฐ˜์ ์ธ ์‹œ๋‚˜๋ฆฌ์˜ค๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค.

์ฝ”๋“œ์˜ ํ’ˆ์งˆ๊ณผ ์•ˆ์ •์„ฑ์„ ํ–ฅ์ƒ์‹œํ‚ค๋Š” ๋ฐ ํ–‰์šด์ด ์žˆ๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค!

PVS-Studio ๋ถ„์„๊ธฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ LLVM 8์—์„œ ๋ฒ„๊ทธ ์ฐพ๊ธฐ

์ด ๊ธฐ์‚ฌ๋ฅผ ์˜์–ด๊ถŒ ์ฒญ์ค‘๊ณผ ๊ณต์œ ํ•˜๋ ค๋ฉด ๋ฒˆ์—ญ ๋งํฌ์ธ Andrey Karpov๋ฅผ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค. PVS-Studio๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ LLVM 8์—์„œ ๋ฒ„๊ทธ ์ฐพ๊ธฐ.

์ถœ์ฒ˜ : habr.com

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€