Index: lib/StaticAnalyzer/Checkers/MallocChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -160,10 +160,11 @@ { public: MallocChecker() - : II_malloc(nullptr), II_free(nullptr), II_realloc(nullptr), - II_calloc(nullptr), II_valloc(nullptr), II_reallocf(nullptr), - II_strndup(nullptr), II_strdup(nullptr), II_kmalloc(nullptr), - II_if_nameindex(nullptr), II_if_freenameindex(nullptr) {} + : II_alloca(nullptr), II_alloca_builtin(nullptr), II_malloc(nullptr), + II_free(nullptr), II_realloc(nullptr), II_calloc(nullptr), + II_valloc(nullptr), II_reallocf(nullptr), II_strndup(nullptr), + II_strdup(nullptr), II_kmalloc(nullptr), II_if_nameindex(nullptr), + II_if_freenameindex(nullptr) {} /// In pessimistic mode, the checker assumes that it does not know which /// functions might free the memory. @@ -218,9 +219,11 @@ mutable std::unique_ptr BT_BadFree[CK_NumCheckKinds]; mutable std::unique_ptr BT_MismatchedDealloc; mutable std::unique_ptr BT_OffsetFree[CK_NumCheckKinds]; - mutable IdentifierInfo *II_malloc, *II_free, *II_realloc, *II_calloc, - *II_valloc, *II_reallocf, *II_strndup, *II_strdup, - *II_kmalloc, *II_if_nameindex, *II_if_freenameindex; + mutable std::unique_ptr BT_ZerroAllocation[CK_NumCheckKinds]; + mutable IdentifierInfo *II_alloca, *II_alloca_builtin, *II_malloc, *II_free, + *II_realloc, *II_calloc, *II_valloc, *II_reallocf, + *II_strndup, *II_strdup, *II_kmalloc, *II_if_nameindex, + *II_if_freenameindex; mutable Optional KernelZeroFlagVal; void initIdentifierInfo(ASTContext &C) const; @@ -252,22 +255,24 @@ MemoryOperationKind MemKind) const; bool isStandardNewDelete(const FunctionDecl *FD, ASTContext &C) const; ///@} + + /// \brief Perform a zero-allocation check. + ProgramStateRef BasicAllocationCheck(CheckerContext &C, const CallExpr *CE, + const unsigned AllocationSizeArg, + ProgramStateRef State) const; + ProgramStateRef MallocMemReturnsAttr(CheckerContext &C, const CallExpr *CE, - const OwnershipAttr* Att) const; + const OwnershipAttr* Att, + ProgramStateRef State) const; static ProgramStateRef MallocMemAux(CheckerContext &C, const CallExpr *CE, - const Expr *SizeEx, SVal Init, - ProgramStateRef State, - AllocationFamily Family = AF_Malloc) { - return MallocMemAux(C, CE, - State->getSVal(SizeEx, C.getLocationContext()), - Init, State, Family); - } - + const Expr *SizeEx, SVal Init, + ProgramStateRef State, + AllocationFamily Family = AF_Malloc); static ProgramStateRef MallocMemAux(CheckerContext &C, const CallExpr *CE, - SVal SizeEx, SVal Init, - ProgramStateRef State, - AllocationFamily Family = AF_Malloc); + SVal SizeEx, SVal Init, + ProgramStateRef State, + AllocationFamily Family = AF_Malloc); // Check if this malloc() for special flags. At present that means M_ZERO or // __GFP_ZERO (in which case, treat it like calloc). @@ -281,7 +286,8 @@ AllocationFamily Family = AF_Malloc); ProgramStateRef FreeMemAttr(CheckerContext &C, const CallExpr *CE, - const OwnershipAttr* Att) const; + const OwnershipAttr* Att, + ProgramStateRef State) const; ProgramStateRef FreeMemAux(CheckerContext &C, const CallExpr *CE, ProgramStateRef state, unsigned Num, bool Hold, @@ -295,8 +301,10 @@ bool ReturnsNullOnFailure = false) const; ProgramStateRef ReallocMem(CheckerContext &C, const CallExpr *CE, - bool FreesMemOnFailure) const; - static ProgramStateRef CallocMem(CheckerContext &C, const CallExpr *CE); + bool FreesMemOnFailure, + ProgramStateRef State) const; + static ProgramStateRef CallocMem(CheckerContext &C, const CallExpr *CE, + ProgramStateRef State); ///\brief Check if the memory associated with this symbol was released. bool isReleased(SymbolRef Sym, CheckerContext &C) const; @@ -337,6 +345,8 @@ ///@} static bool SummarizeValue(raw_ostream &os, SVal V); static bool SummarizeRegion(raw_ostream &os, const MemRegion *MR); + void ReportZeroByteAllocation(CheckerContext &C, ProgramStateRef FalseState, + const Expr *Arg, const Expr *AllocExpr) const; void ReportBadFree(CheckerContext &C, SVal ArgVal, SourceRange Range, const Expr *DeallocExpr) const; void ReportMismatchedDealloc(CheckerContext &C, SourceRange Range, @@ -497,6 +507,8 @@ void MallocChecker::initIdentifierInfo(ASTContext &Ctx) const { if (II_malloc) return; + II_alloca = &Ctx.Idents.get("alloca"); + II_alloca_builtin = &Ctx.Idents.get("__builtin_alloca"); II_malloc = &Ctx.Idents.get("malloc"); II_free = &Ctx.Idents.get("free"); II_realloc = &Ctx.Idents.get("realloc"); @@ -545,9 +557,10 @@ } if (Family == AF_Malloc && CheckAlloc) { - if (FunI == II_malloc || FunI == II_realloc || FunI == II_reallocf || - FunI == II_calloc || FunI == II_valloc || FunI == II_strdup || - FunI == II_strndup || FunI == II_kmalloc) + if (FunI == II_alloca || FunI == II_alloca_builtin || FunI == II_malloc || + FunI == II_realloc || FunI == II_reallocf || FunI == II_calloc || + FunI == II_valloc || FunI == II_strdup || FunI == II_strndup || + FunI == II_kmalloc) return true; } @@ -710,6 +723,9 @@ if (FunI == II_malloc) { if (CE->getNumArgs() < 1) return; + else if (CE->getNumArgs() == 1) + State = BasicAllocationCheck(C, CE, 0, State); + if (CE->getNumArgs() < 3) { State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State); } else if (CE->getNumArgs() == 3) { @@ -731,20 +747,30 @@ if (CE->getNumArgs() < 1) return; State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State); + State = BasicAllocationCheck(C, CE, 0, State); } else if (FunI == II_realloc) { - State = ReallocMem(C, CE, false); + State = ReallocMem(C, CE, false, State); + // TODO: Will be uncommented when 'realloc' is handled properly (see + // D6178 for details). + // State = BasicAllocationCheck(C, CE, 1, State); } else if (FunI == II_reallocf) { - State = ReallocMem(C, CE, true); + State = ReallocMem(C, CE, true, State); + // TODO: Will be uncommented when 'realloc' is handled properly (see + // D6178 for details). + // State = BasicAllocationCheck(C, CE, 1, State); } else if (FunI == II_calloc) { - State = CallocMem(C, CE); + State = CallocMem(C, CE, State); + State = BasicAllocationCheck(C, CE, 0, State); + State = BasicAllocationCheck(C, CE, 1, State); } else if (FunI == II_free) { State = FreeMemAux(C, CE, State, 0, false, ReleasedAllocatedMemory); } else if (FunI == II_strdup) { State = MallocUpdateRefState(C, CE, State); } else if (FunI == II_strndup) { State = MallocUpdateRefState(C, CE, State); - } - else if (isStandardNewDelete(FD, C.getASTContext())) { + } else if (FunI == II_alloca || FunI == II_alloca_builtin) { + State = BasicAllocationCheck(C, CE, 0, State); + } else if (isStandardNewDelete(FD, C.getASTContext())) { // Process direct calls to operator new/new[]/delete/delete[] functions // as distinct from new/new[]/delete/delete[] expressions that are // processed by the checkPostStmt callbacks for CXXNewExpr and @@ -778,11 +804,11 @@ for (const auto *I : FD->specific_attrs()) { switch (I->getOwnKind()) { case OwnershipAttr::Returns: - State = MallocMemReturnsAttr(C, CE, I); + State = MallocMemReturnsAttr(C, CE, I, State); break; case OwnershipAttr::Takes: case OwnershipAttr::Holds: - State = FreeMemAttr(C, CE, I); + State = FreeMemAttr(C, CE, I, State); break; } } @@ -790,6 +816,41 @@ C.addTransition(State); } +// Performs a 0-sized allocations check. +ProgramStateRef MallocChecker::BasicAllocationCheck(CheckerContext &C, + const CallExpr *CE, + const unsigned AllocationSizeArg, + ProgramStateRef State) const { + if (!State) + return nullptr; + + const Expr *Arg = CE->getArg(AllocationSizeArg); + + Optional DefArgVal = + State->getSVal(Arg, C.getLocationContext()).getAs(); + + if (!DefArgVal) + return State; + + // Check if the allocation size is 0. + ProgramStateRef TrueState, FalseState; + SValBuilder &SvalBuilder = C.getSValBuilder(); + DefinedSVal Zero = + SvalBuilder.makeZeroVal(Arg->getType()).castAs(); + + std::tie(TrueState, FalseState) = + State->assume(SvalBuilder.evalEQ(State, *DefArgVal, Zero)); + + if (TrueState && !FalseState) { + ReportZeroByteAllocation(C, FalseState, Arg, CE); + return nullptr; + } + + // Assume the value is non-zero going forward. + assert(FalseState); + return FalseState; +} + static QualType getDeepPointeeType(QualType T) { QualType Result = T, PointeeType = T->getPointeeType(); while (!PointeeType.isNull()) { @@ -919,15 +980,31 @@ ProgramStateRef MallocChecker::MallocMemReturnsAttr(CheckerContext &C, const CallExpr *CE, - const OwnershipAttr *Att) const { + const OwnershipAttr *Att, + ProgramStateRef State) const { + if (!State) + return nullptr; + if (Att->getModule() != II_malloc) return nullptr; OwnershipAttr::args_iterator I = Att->args_begin(), E = Att->args_end(); if (I != E) { - return MallocMemAux(C, CE, CE->getArg(*I), UndefinedVal(), C.getState()); + return MallocMemAux(C, CE, CE->getArg(*I), UndefinedVal(), State); } - return MallocMemAux(C, CE, UnknownVal(), UndefinedVal(), C.getState()); + return MallocMemAux(C, CE, UnknownVal(), UndefinedVal(), State); +} + +ProgramStateRef MallocChecker::MallocMemAux(CheckerContext &C, + const CallExpr *CE, + const Expr *SizeEx, SVal Init, + ProgramStateRef State, + AllocationFamily Family) { + if (!State) + return nullptr; + + return MallocMemAux(C, CE, State->getSVal(SizeEx, C.getLocationContext()), + Init, State, Family); } ProgramStateRef MallocChecker::MallocMemAux(CheckerContext &C, @@ -935,6 +1012,8 @@ SVal Size, SVal Init, ProgramStateRef State, AllocationFamily Family) { + if (!State) + return nullptr; // We expect the malloc functions to return a pointer. if (!Loc::isLocType(CE->getType())) @@ -976,6 +1055,9 @@ const Expr *E, ProgramStateRef State, AllocationFamily Family) { + if (!State) + return nullptr; + // Get the return value. SVal retVal = State->getSVal(E, C.getLocationContext()); @@ -992,11 +1074,14 @@ ProgramStateRef MallocChecker::FreeMemAttr(CheckerContext &C, const CallExpr *CE, - const OwnershipAttr *Att) const { + const OwnershipAttr *Att, + ProgramStateRef State) const { + if (!State) + return nullptr; + if (Att->getModule() != II_malloc) return nullptr; - ProgramStateRef State = C.getState(); bool ReleasedAllocated = false; for (const auto &Arg : Att->args()) { @@ -1011,15 +1096,18 @@ ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C, const CallExpr *CE, - ProgramStateRef state, + ProgramStateRef State, unsigned Num, bool Hold, bool &ReleasedAllocated, bool ReturnsNullOnFailure) const { + if (!State) + return nullptr; + if (CE->getNumArgs() < (Num + 1)) return nullptr; - return FreeMemAux(C, CE->getArg(Num), CE, state, Hold, + return FreeMemAux(C, CE->getArg(Num), CE, State, Hold, ReleasedAllocated, ReturnsNullOnFailure); } @@ -1152,6 +1240,9 @@ bool &ReleasedAllocated, bool ReturnsNullOnFailure) const { + if (!State) + return nullptr; + SVal ArgVal = State->getSVal(ArgExpr, C.getLocationContext()); if (!ArgVal.getAs()) return nullptr; @@ -1407,6 +1498,38 @@ } } +void MallocChecker::ReportZeroByteAllocation(CheckerContext &C, + ProgramStateRef FalseState, + const Expr *Arg, + const Expr *AllocExpr) const { + if (!ChecksEnabled[CK_MallocOptimistic] && + !ChecksEnabled[CK_MallocPessimistic]) + return; + + auto CheckKind = getCheckIfTracked(C, AllocExpr); + if (!CheckKind.hasValue()) + return; + + if (ExplodedNode *N = C.generateSink(FalseState)) { + + if (!BT_ZerroAllocation[*CheckKind]) + BT_ZerroAllocation[*CheckKind].reset(new BugType( + CheckNames[*CheckKind], "Zero allocation", "Memory Error")); + + SmallString<256> S; + llvm::raw_svector_ostream os(S); + os << "Call to '"; + printAllocDeallocName(os, C, AllocExpr); + os << "' has an allocation size of 0 bytes"; + BugReport *Report = + new BugReport(*BT_ZerroAllocation[*CheckKind], os.str(), N); + + Report->addRange(Arg->getSourceRange()); + bugreporter::trackNullOrUndefValue(N, Arg, *Report); + C.emitReport(Report); + } +} + void MallocChecker::ReportBadFree(CheckerContext &C, SVal ArgVal, SourceRange Range, const Expr *DeallocExpr) const { @@ -1655,14 +1778,17 @@ ProgramStateRef MallocChecker::ReallocMem(CheckerContext &C, const CallExpr *CE, - bool FreesOnFail) const { + bool FreesOnFail, + ProgramStateRef State) const { + if (!State) + return nullptr; + if (CE->getNumArgs() < 2) return nullptr; - ProgramStateRef state = C.getState(); const Expr *arg0Expr = CE->getArg(0); const LocationContext *LCtx = C.getLocationContext(); - SVal Arg0Val = state->getSVal(arg0Expr, LCtx); + SVal Arg0Val = State->getSVal(arg0Expr, LCtx); if (!Arg0Val.getAs()) return nullptr; DefinedOrUnknownSVal arg0Val = Arg0Val.castAs(); @@ -1670,7 +1796,7 @@ SValBuilder &svalBuilder = C.getSValBuilder(); DefinedOrUnknownSVal PtrEQ = - svalBuilder.evalEQ(state, arg0Val, svalBuilder.makeNull()); + svalBuilder.evalEQ(State, arg0Val, svalBuilder.makeNull()); // Get the size argument. If there is no size arg then give up. const Expr *Arg1 = CE->getArg(1); @@ -1678,20 +1804,20 @@ return nullptr; // Get the value of the size argument. - SVal Arg1ValG = state->getSVal(Arg1, LCtx); + SVal Arg1ValG = State->getSVal(Arg1, LCtx); if (!Arg1ValG.getAs()) return nullptr; DefinedOrUnknownSVal Arg1Val = Arg1ValG.castAs(); // Compare the size argument to 0. DefinedOrUnknownSVal SizeZero = - svalBuilder.evalEQ(state, Arg1Val, + svalBuilder.evalEQ(State, Arg1Val, svalBuilder.makeIntValWithPtrWidth(0, false)); ProgramStateRef StatePtrIsNull, StatePtrNotNull; - std::tie(StatePtrIsNull, StatePtrNotNull) = state->assume(PtrEQ); + std::tie(StatePtrIsNull, StatePtrNotNull) = State->assume(PtrEQ); ProgramStateRef StateSizeIsZero, StateSizeNotZero; - std::tie(StateSizeIsZero, StateSizeNotZero) = state->assume(SizeZero); + std::tie(StateSizeIsZero, StateSizeNotZero) = State->assume(SizeZero); // We only assume exceptional states if they are definitely true; if the // state is under-constrained, assume regular realloc behavior. bool PrtIsNull = StatePtrIsNull && !StatePtrNotNull; @@ -1711,7 +1837,7 @@ // Get the from and to pointer symbols as in toPtr = realloc(fromPtr, size). assert(!PrtIsNull); SymbolRef FromPtr = arg0Val.getAsSymbol(); - SVal RetVal = state->getSVal(CE, LCtx); + SVal RetVal = State->getSVal(CE, LCtx); SymbolRef ToPtr = RetVal.getAsSymbol(); if (!FromPtr || !ToPtr) return nullptr; @@ -1731,7 +1857,7 @@ // Default behavior. if (ProgramStateRef stateFree = - FreeMemAux(C, CE, state, 0, false, ReleasedAllocated)) { + FreeMemAux(C, CE, State, 0, false, ReleasedAllocated)) { ProgramStateRef stateRealloc = MallocMemAux(C, CE, CE->getArg(1), UnknownVal(), stateFree); @@ -1755,20 +1881,23 @@ return nullptr; } -ProgramStateRef MallocChecker::CallocMem(CheckerContext &C, const CallExpr *CE){ +ProgramStateRef MallocChecker::CallocMem(CheckerContext &C, const CallExpr *CE, + ProgramStateRef State) { + if (!State) + return nullptr; + if (CE->getNumArgs() < 2) return nullptr; - ProgramStateRef state = C.getState(); SValBuilder &svalBuilder = C.getSValBuilder(); const LocationContext *LCtx = C.getLocationContext(); - SVal count = state->getSVal(CE->getArg(0), LCtx); - SVal elementSize = state->getSVal(CE->getArg(1), LCtx); - SVal TotalSize = svalBuilder.evalBinOp(state, BO_Mul, count, elementSize, + SVal count = State->getSVal(CE->getArg(0), LCtx); + SVal elementSize = State->getSVal(CE->getArg(1), LCtx); + SVal TotalSize = svalBuilder.evalBinOp(State, BO_Mul, count, elementSize, svalBuilder.getContext().getSizeType()); SVal zeroVal = svalBuilder.makeZeroVal(svalBuilder.getContext().CharTy); - return MallocMemAux(C, CE, TotalSize, zeroVal, state); + return MallocMemAux(C, CE, TotalSize, zeroVal, State); } LeakInfo Index: lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp +++ lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp @@ -30,7 +30,7 @@ namespace { class UnixAPIChecker : public Checker< check::PreStmt > { - mutable std::unique_ptr BT_open, BT_pthreadOnce, BT_mallocZero; + mutable std::unique_ptr BT_open, BT_pthreadOnce; mutable Optional Val_O_CREAT; public: @@ -38,25 +38,10 @@ void CheckOpen(CheckerContext &C, const CallExpr *CE) const; void CheckPthreadOnce(CheckerContext &C, const CallExpr *CE) const; - void CheckCallocZero(CheckerContext &C, const CallExpr *CE) const; - void CheckMallocZero(CheckerContext &C, const CallExpr *CE) const; - void CheckReallocZero(CheckerContext &C, const CallExpr *CE) const; - void CheckReallocfZero(CheckerContext &C, const CallExpr *CE) const; - void CheckAllocaZero(CheckerContext &C, const CallExpr *CE) const; - void CheckVallocZero(CheckerContext &C, const CallExpr *CE) const; typedef void (UnixAPIChecker::*SubChecker)(CheckerContext &, const CallExpr *) const; private: - bool ReportZeroByteAllocation(CheckerContext &C, - ProgramStateRef falseState, - const Expr *arg, - const char *fn_name) const; - void BasicAllocationCheck(CheckerContext &C, - const CallExpr *CE, - const unsigned numArgs, - const unsigned sizeArg, - const char *fn) const; void LazyInitialize(std::unique_ptr &BT, const char *name) const { if (BT) return; @@ -206,144 +191,6 @@ } //===----------------------------------------------------------------------===// -// "calloc", "malloc", "realloc", "reallocf", "alloca" and "valloc" -// with allocation size 0 -//===----------------------------------------------------------------------===// -// FIXME: Eventually these should be rolled into the MallocChecker, but right now -// they're more basic and valuable for widespread use. - -// Returns true if we try to do a zero byte allocation, false otherwise. -// Fills in trueState and falseState. -static bool IsZeroByteAllocation(ProgramStateRef state, - const SVal argVal, - ProgramStateRef *trueState, - ProgramStateRef *falseState) { - std::tie(*trueState, *falseState) = - state->assume(argVal.castAs()); - - return (*falseState && !*trueState); -} - -// Generates an error report, indicating that the function whose name is given -// will perform a zero byte allocation. -// Returns false if an error occurred, true otherwise. -bool UnixAPIChecker::ReportZeroByteAllocation(CheckerContext &C, - ProgramStateRef falseState, - const Expr *arg, - const char *fn_name) const { - ExplodedNode *N = C.generateSink(falseState); - if (!N) - return false; - - LazyInitialize(BT_mallocZero, - "Undefined allocation of 0 bytes (CERT MEM04-C; CWE-131)"); - - SmallString<256> S; - llvm::raw_svector_ostream os(S); - os << "Call to '" << fn_name << "' has an allocation size of 0 bytes"; - BugReport *report = new BugReport(*BT_mallocZero, os.str(), N); - - report->addRange(arg->getSourceRange()); - bugreporter::trackNullOrUndefValue(N, arg, *report); - C.emitReport(report); - - return true; -} - -// Does a basic check for 0-sized allocations suitable for most of the below -// functions (modulo "calloc") -void UnixAPIChecker::BasicAllocationCheck(CheckerContext &C, - const CallExpr *CE, - const unsigned numArgs, - const unsigned sizeArg, - const char *fn) const { - // Sanity check for the correct number of arguments - if (CE->getNumArgs() != numArgs) - return; - - // Check if the allocation size is 0. - ProgramStateRef state = C.getState(); - ProgramStateRef trueState = nullptr, falseState = nullptr; - const Expr *arg = CE->getArg(sizeArg); - SVal argVal = state->getSVal(arg, C.getLocationContext()); - - if (argVal.isUnknownOrUndef()) - return; - - // Is the value perfectly constrained to zero? - if (IsZeroByteAllocation(state, argVal, &trueState, &falseState)) { - (void) ReportZeroByteAllocation(C, falseState, arg, fn); - return; - } - // Assume the value is non-zero going forward. - assert(trueState); - if (trueState != state) - C.addTransition(trueState); -} - -void UnixAPIChecker::CheckCallocZero(CheckerContext &C, - const CallExpr *CE) const { - unsigned int nArgs = CE->getNumArgs(); - if (nArgs != 2) - return; - - ProgramStateRef state = C.getState(); - ProgramStateRef trueState = nullptr, falseState = nullptr; - - unsigned int i; - for (i = 0; i < nArgs; i++) { - const Expr *arg = CE->getArg(i); - SVal argVal = state->getSVal(arg, C.getLocationContext()); - if (argVal.isUnknownOrUndef()) { - if (i == 0) - continue; - else - return; - } - - if (IsZeroByteAllocation(state, argVal, &trueState, &falseState)) { - if (ReportZeroByteAllocation(C, falseState, arg, "calloc")) - return; - else if (i == 0) - continue; - else - return; - } - } - - // Assume the value is non-zero going forward. - assert(trueState); - if (trueState != state) - C.addTransition(trueState); -} - -void UnixAPIChecker::CheckMallocZero(CheckerContext &C, - const CallExpr *CE) const { - BasicAllocationCheck(C, CE, 1, 0, "malloc"); -} - -void UnixAPIChecker::CheckReallocZero(CheckerContext &C, - const CallExpr *CE) const { - BasicAllocationCheck(C, CE, 2, 1, "realloc"); -} - -void UnixAPIChecker::CheckReallocfZero(CheckerContext &C, - const CallExpr *CE) const { - BasicAllocationCheck(C, CE, 2, 1, "reallocf"); -} - -void UnixAPIChecker::CheckAllocaZero(CheckerContext &C, - const CallExpr *CE) const { - BasicAllocationCheck(C, CE, 1, 0, "alloca"); -} - -void UnixAPIChecker::CheckVallocZero(CheckerContext &C, - const CallExpr *CE) const { - BasicAllocationCheck(C, CE, 1, 0, "valloc"); -} - - -//===----------------------------------------------------------------------===// // Central dispatch function. //===----------------------------------------------------------------------===// @@ -361,12 +208,6 @@ llvm::StringSwitch(FName) .Case("open", &UnixAPIChecker::CheckOpen) .Case("pthread_once", &UnixAPIChecker::CheckPthreadOnce) - .Case("calloc", &UnixAPIChecker::CheckCallocZero) - .Case("malloc", &UnixAPIChecker::CheckMallocZero) - .Case("realloc", &UnixAPIChecker::CheckReallocZero) - .Case("reallocf", &UnixAPIChecker::CheckReallocfZero) - .Cases("alloca", "__builtin_alloca", &UnixAPIChecker::CheckAllocaZero) - .Case("valloc", &UnixAPIChecker::CheckVallocZero) .Default(nullptr); if (SC) Index: test/Analysis/malloc.c =================================================================== --- test/Analysis/malloc.c +++ test/Analysis/malloc.c @@ -5,6 +5,7 @@ void clang_analyzer_eval(int); typedef __typeof(sizeof(int)) size_t; +void *alloca(size_t); void *malloc(size_t); void *valloc(size_t); void free(void *); @@ -949,6 +950,100 @@ } // ---------------------------------------------------------------------------- +// Test zero-sized allocations. +void testMallocZero() { + char* foo = malloc(0); // expected-warning{{Call to 'malloc()' has an allocation size of 0 bytes}} + free(foo); +} + +void testMallocZeroNoWarn(size_t size) { + char* foo = malloc(size); // no-warning + free(foo); +} + +void testMallocPathZero(int i) { + if (!i) { + char* foo = malloc(i); // expected-warning{{Call to 'malloc()' has an allocation size of 0 bytes}} + free(foo); + } +} + +void testCallocZero(void) { + char *foo = calloc(0, 0); // expected-warning{{Call to 'calloc()' has an allocation size of 0 bytes}} + free(foo); +} + +void testCalloc1Zero(void) { + char *foo = calloc(0, 42); // expected-warning{{Call to 'calloc()' has an allocation size of 0 bytes}} + free(foo); +} + +void testCalloc2Zero(void) { + char *foo = calloc(42, 0); // expected-warning{{Call to 'calloc()' has an allocation size of 0 bytes}} + free(foo); +} + +void testCalloc1Unknown2Zero(int *i, int j) { + char *foo = calloc(*(i+j), 0); // expected-warning{{Call to 'calloc()' has an allocation size of 0 bytes}} + free(foo); +} + +void testCallocZeroNoWarn(size_t nmemb, size_t size) { + char *foo = calloc(nmemb, size); // no-warning + free(foo); +} +/* +// TODO: Will be uncommented when 'realloc' is handled properly (see D6178 for +// details). +void testReallocZero(char *ptr) { + char *foo = realloc(ptr, 0); // TODO:expected-warning{{Call to 'realloc()' has an allocation size of 0 bytes}} + free(foo); +} +*/ +void testReallocZeroNoWarn(char *ptr, size_t size) { + char *foo = realloc(ptr, size); // no-warning + free(foo); +} +/* +// TODO: Will be uncommented when 'realloc' is handled properly (see D6178 for +// details). +void testReallocfZero(char *ptr) { + char *foo = reallocf(ptr, 0); // TODO:expected-warning{{Call to 'reallocf()' has an allocation size of 0 bytes}} + free(foo); +} +*/ +void testReallocfZeroNoWarn(char *ptr, size_t size) { + char *foo = reallocf(ptr, size); // no-warning + free(foo); +} + +void testAllocaZero() { + char *foo = alloca(0); // expected-warning{{Call to 'alloca()' has an allocation size of 0 bytes}} +} + +void testAllocaZeroNoWarn(size_t sz) { + char *foo = alloca(sz); // no-warning +} + +void testBuiltinAllocaZero() { + char *foo2 = __builtin_alloca(0); // expected-warning{{Call to '__builtin_alloca()' has an allocation size of 0 bytes}} +} + +void testBuiltinAllocaZeroNoWarn(size_t sz) { + char *foo2 = __builtin_alloca(sz); // no-warning +} + +void testVallocZero() { + char *foo = valloc(0); // expected-warning{{Call to 'valloc()' has an allocation size of 0 bytes}} + free(foo); +} + +void testVallocZeroNoWarn(size_t sz) { + char *foo = valloc(sz); // no-warning + free(foo); +} + +// ---------------------------------------------------------------------------- // Test the system library functions to which the pointer can escape. // This tests false positive suppression. Index: test/Analysis/unix-fns.c =================================================================== --- test/Analysis/unix-fns.c +++ test/Analysis/unix-fns.c @@ -10,14 +10,6 @@ typedef struct _opaque_pthread_once_t __darwin_pthread_once_t; typedef __darwin_pthread_once_t pthread_once_t; int pthread_once(pthread_once_t *, void (*)(void)); -typedef long unsigned int __darwin_size_t; -typedef __darwin_size_t size_t; -void *calloc(size_t, size_t); -void *malloc(size_t); -void *realloc(void *, size_t); -void *reallocf(void *, size_t); -void *alloca(size_t); -void *valloc(size_t); typedef union { struct _os_object_s *_os_obj; struct dispatch_object_s *_do; @@ -77,98 +69,6 @@ pthread_once(&pred, test_pthread_once_aux); // no-warning } -// PR 2899 - warn of zero-sized allocations to malloc(). -void pr2899() { - char* foo = malloc(0); // expected-warning{{Call to 'malloc' has an allocation size of 0 bytes}} - for (unsigned i = 0; i < 100; i++) { - foo[i] = 0; - } -} -void pr2899_nowarn(size_t size) { - char* foo = malloc(size); // no-warning - for (unsigned i = 0; i < 100; i++) { - foo[i] = 0; - } -} -void test_calloc(void) { - char *foo = calloc(0, 42); // expected-warning{{Call to 'calloc' has an allocation size of 0 bytes}} - for (unsigned i = 0; i < 100; i++) { - foo[i] = 0; - } -} -void test_calloc2(void) { - char *foo = calloc(42, 0); // expected-warning{{Call to 'calloc' has an allocation size of 0 bytes}} - for (unsigned i = 0; i < 100; i++) { - foo[i] = 0; - } -} -void test_calloc_nowarn(size_t nmemb, size_t size) { - char *foo = calloc(nmemb, size); // no-warning - for (unsigned i = 0; i < 100; i++) { - foo[i] = 0; - } -} -void test_realloc(char *ptr) { - char *foo = realloc(ptr, 0); // expected-warning{{Call to 'realloc' has an allocation size of 0 bytes}} - for (unsigned i = 0; i < 100; i++) { - foo[i] = 0; - } -} -void test_reallocf(char *ptr) { - char *foo = reallocf(ptr, 0); // expected-warning{{Call to 'reallocf' has an allocation size of 0 bytes}} - for (unsigned i = 0; i < 100; i++) { - foo[i] = 0; - } -} -void test_realloc_nowarn(char *ptr, size_t size) { - char *foo = realloc(ptr, size); // no-warning - for (unsigned i = 0; i < 100; i++) { - foo[i] = 0; - } -} -void test_reallocf_nowarn(char *ptr, size_t size) { - char *foo = reallocf(ptr, size); // no-warning - for (unsigned i = 0; i < 100; i++) { - foo[i] = 0; - } -} -void test_alloca() { - char *foo = alloca(0); // expected-warning{{Call to 'alloca' has an allocation size of 0 bytes}} - for(unsigned i = 0; i < 100; i++) { - foo[i] = 0; - } -} -void test_alloca_nowarn(size_t sz) { - char *foo = alloca(sz); // no-warning - for(unsigned i = 0; i < 100; i++) { - foo[i] = 0; - } -} -void test_builtin_alloca() { - char *foo2 = __builtin_alloca(0); // expected-warning{{Call to 'alloca' has an allocation size of 0 bytes}} - for(unsigned i = 0; i < 100; i++) { - foo2[i] = 0; - } -} -void test_builtin_alloca_nowarn(size_t sz) { - char *foo2 = __builtin_alloca(sz); // no-warning - for(unsigned i = 0; i < 100; i++) { - foo2[i] = 0; - } -} -void test_valloc() { - char *foo = valloc(0); // expected-warning{{Call to 'valloc' has an allocation size of 0 bytes}} - for(unsigned i = 0; i < 100; i++) { - foo[i] = 0; - } -} -void test_valloc_nowarn(size_t sz) { - char *foo = valloc(sz); // no-warning - for(unsigned i = 0; i < 100; i++) { - foo[i] = 0; - } -} - // Test dispatch_once being a macro that wraps a call to _dispatch_once, which in turn // calls the real dispatch_once. @@ -190,460 +90,21 @@ dispatch_sync(queue, ^(void){ if (q) { *p = 1; // expected-warning {{null pointer}} - } - }); -} - -// Test inlining if dispatch_once. -void test_inline_dispatch_once() { - static dispatch_once_t pred; - int *p = 0; - dispatch_once(&pred, ^(void) { - *p = 1; // expected-warning {{null}} - }); -} - -// CHECK: diagnostics -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line50 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line50 -// CHECK-NEXT: col5 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line52 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line52 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line52 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line52 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line52 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line52 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line52 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line52 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line52 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Assuming 'fd' is not equal to 0 -// CHECK-NEXT: message -// CHECK-NEXT: Assuming 'fd' is not equal to 0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line52 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line52 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line55 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line55 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line55 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line55 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line55 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line55 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line55 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line55 -// CHECK-NEXT: col19 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line55 -// CHECK-NEXT: col25 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to 'open' requires a third argument when the 'O_CREAT' flag is set -// CHECK-NEXT: message -// CHECK-NEXT: Call to 'open' requires a third argument when the 'O_CREAT' flag is set -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionCall to 'open' requires a third argument when the 'O_CREAT' flag is set -// CHECK-NEXT: categoryUnix API -// CHECK-NEXT: typeImproper use of 'open' -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contexttest_open -// CHECK-NEXT: issue_hash6 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line55 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line61 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line61 -// CHECK-NEXT: col17 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line62 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line62 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line62 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line62 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line62 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line62 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line62 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line62 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line62 -// CHECK-NEXT: col52 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line62 -// CHECK-NEXT: col64 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line62 -// CHECK-NEXT: col52 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line62 -// CHECK-NEXT: col66 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line62 -// CHECK-NEXT: col72 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to 'dispatch_once' uses the local variable 'pred' for the predicate value. Using such transient memory for the predicate is potentially dangerous. Perhaps you intended to declare the variable as 'static'? -// CHECK-NEXT: message -// CHECK-NEXT: Call to 'dispatch_once' uses the local variable 'pred' for the predicate value. Using such transient memory for the predicate is potentially dangerous. Perhaps you intended to declare the variable as 'static'? -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionCall to 'dispatch_once' uses the local variable 'pred' for the predicate value. Using such transient memory for the predicate is potentially dangerous. Perhaps you intended to declare the variable as 'static'? -// CHECK-NEXT: categoryAPI Misuse (Apple) -// CHECK-NEXT: typeImproper use of 'dispatch_once' -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contexttest_dispatch_once -// CHECK-NEXT: issue_hash2 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line62 -// CHECK-NEXT: col52 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line72 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line72 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line73 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line73 -// CHECK-NEXT: col14 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line73 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line73 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line73 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to 'pthread_once' uses the local variable 'pred' for the "control" value. Using such transient memory for the control value is potentially dangerous. Perhaps you intended to declare the variable as 'static'? -// CHECK-NEXT: message -// CHECK-NEXT: Call to 'pthread_once' uses the local variable 'pred' for the "control" value. Using such transient memory for the control value is potentially dangerous. Perhaps you intended to declare the variable as 'static'? -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionCall to 'pthread_once' uses the local variable 'pred' for the "control" value. Using such transient memory for the control value is potentially dangerous. Perhaps you intended to declare the variable as 'static'? -// CHECK-NEXT: categoryUnix API -// CHECK-NEXT: typeImproper use of 'pthread_once' -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contexttest_pthread_once -// CHECK-NEXT: issue_hash2 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line73 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: + } + }); +} + +// Test inlining if dispatch_once. +void test_inline_dispatch_once() { + static dispatch_once_t pred; + int *p = 0; + dispatch_once(&pred, ^(void) { + *p = 1; // expected-warning {{null}} + }); +} + +// CHECK: diagnostics +// CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: path // CHECK-NEXT: @@ -655,26 +116,26 @@ // CHECK-NEXT: start // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line82 +// CHECK-NEXT: line42 // CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line82 -// CHECK-NEXT: col6 +// CHECK-NEXT: line42 +// CHECK-NEXT: col5 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: end // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line82 -// CHECK-NEXT: col15 +// CHECK-NEXT: line44 +// CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line82 -// CHECK-NEXT: col20 +// CHECK-NEXT: line44 +// CHECK-NEXT: col4 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: @@ -682,52 +143,6 @@ // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line82 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line82 -// CHECK-NEXT: col22 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line82 -// CHECK-NEXT: col22 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to 'malloc' has an allocation size of 0 bytes -// CHECK-NEXT: message -// CHECK-NEXT: Call to 'malloc' has an allocation size of 0 bytes -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionCall to 'malloc' has an allocation size of 0 bytes -// CHECK-NEXT: categoryUnix API -// CHECK-NEXT: typeUndefined allocation of 0 bytes (CERT MEM04-C; CWE-131) -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextpr2899 -// CHECK-NEXT: issue_hash1 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line82 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: // CHECK-NEXT: kindcontrol // CHECK-NEXT: edges // CHECK-NEXT: @@ -735,26 +150,26 @@ // CHECK-NEXT: start // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line94 +// CHECK-NEXT: line44 // CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line94 -// CHECK-NEXT: col6 +// CHECK-NEXT: line44 +// CHECK-NEXT: col4 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: end // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line94 -// CHECK-NEXT: col15 +// CHECK-NEXT: line44 +// CHECK-NEXT: col7 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line94 -// CHECK-NEXT: col20 +// CHECK-NEXT: line44 +// CHECK-NEXT: col7 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: @@ -765,48 +180,31 @@ // CHECK-NEXT: kindevent // CHECK-NEXT: location // CHECK-NEXT: -// CHECK-NEXT: line94 -// CHECK-NEXT: col15 +// CHECK-NEXT: line44 +// CHECK-NEXT: col7 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: ranges // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line94 -// CHECK-NEXT: col22 +// CHECK-NEXT: line44 +// CHECK-NEXT: col7 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line94 -// CHECK-NEXT: col22 +// CHECK-NEXT: line44 +// CHECK-NEXT: col9 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: depth0 // CHECK-NEXT: extended_message -// CHECK-NEXT: Call to 'calloc' has an allocation size of 0 bytes +// CHECK-NEXT: Assuming 'fd' is not equal to 0 // CHECK-NEXT: message -// CHECK-NEXT: Call to 'calloc' has an allocation size of 0 bytes +// CHECK-NEXT: Assuming 'fd' is not equal to 0 // CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionCall to 'calloc' has an allocation size of 0 bytes -// CHECK-NEXT: categoryUnix API -// CHECK-NEXT: typeUndefined allocation of 0 bytes (CERT MEM04-C; CWE-131) -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contexttest_calloc -// CHECK-NEXT: issue_hash1 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line94 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: kindcontrol // CHECK-NEXT: edges @@ -815,26 +213,26 @@ // CHECK-NEXT: start // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line100 -// CHECK-NEXT: col3 +// CHECK-NEXT: line44 +// CHECK-NEXT: col7 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line100 -// CHECK-NEXT: col6 +// CHECK-NEXT: line44 +// CHECK-NEXT: col7 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: end // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line100 -// CHECK-NEXT: col15 +// CHECK-NEXT: line47 +// CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line100 -// CHECK-NEXT: col20 +// CHECK-NEXT: line47 +// CHECK-NEXT: col4 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: @@ -842,52 +240,6 @@ // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line100 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line100 -// CHECK-NEXT: col26 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line100 -// CHECK-NEXT: col26 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to 'calloc' has an allocation size of 0 bytes -// CHECK-NEXT: message -// CHECK-NEXT: Call to 'calloc' has an allocation size of 0 bytes -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionCall to 'calloc' has an allocation size of 0 bytes -// CHECK-NEXT: categoryUnix API -// CHECK-NEXT: typeUndefined allocation of 0 bytes (CERT MEM04-C; CWE-131) -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contexttest_calloc2 -// CHECK-NEXT: issue_hash1 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line100 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: // CHECK-NEXT: kindcontrol // CHECK-NEXT: edges // CHECK-NEXT: @@ -895,26 +247,26 @@ // CHECK-NEXT: start // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line112 +// CHECK-NEXT: line47 // CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line112 -// CHECK-NEXT: col6 +// CHECK-NEXT: line47 +// CHECK-NEXT: col4 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: end // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line112 -// CHECK-NEXT: col15 +// CHECK-NEXT: line47 +// CHECK-NEXT: col8 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line112 -// CHECK-NEXT: col21 +// CHECK-NEXT: line47 +// CHECK-NEXT: col11 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: @@ -925,42 +277,42 @@ // CHECK-NEXT: kindevent // CHECK-NEXT: location // CHECK-NEXT: -// CHECK-NEXT: line112 -// CHECK-NEXT: col15 +// CHECK-NEXT: line47 +// CHECK-NEXT: col8 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: ranges // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line112 -// CHECK-NEXT: col28 +// CHECK-NEXT: line47 +// CHECK-NEXT: col19 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line112 -// CHECK-NEXT: col28 +// CHECK-NEXT: line47 +// CHECK-NEXT: col25 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: depth0 // CHECK-NEXT: extended_message -// CHECK-NEXT: Call to 'realloc' has an allocation size of 0 bytes +// CHECK-NEXT: Call to 'open' requires a third argument when the 'O_CREAT' flag is set // CHECK-NEXT: message -// CHECK-NEXT: Call to 'realloc' has an allocation size of 0 bytes +// CHECK-NEXT: Call to 'open' requires a third argument when the 'O_CREAT' flag is set // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: descriptionCall to 'realloc' has an allocation size of 0 bytes +// CHECK-NEXT: descriptionCall to 'open' requires a third argument when the 'O_CREAT' flag is set // CHECK-NEXT: categoryUnix API -// CHECK-NEXT: typeUndefined allocation of 0 bytes (CERT MEM04-C; CWE-131) +// CHECK-NEXT: typeImproper use of 'open' // CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contexttest_realloc -// CHECK-NEXT: issue_hash1 +// CHECK-NEXT: issue_contexttest_open +// CHECK-NEXT: issue_hash6 // CHECK-NEXT: location // CHECK-NEXT: -// CHECK-NEXT: line112 -// CHECK-NEXT: col15 +// CHECK-NEXT: line47 +// CHECK-NEXT: col8 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: @@ -975,26 +327,26 @@ // CHECK-NEXT: start // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line118 +// CHECK-NEXT: line53 // CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line118 -// CHECK-NEXT: col6 +// CHECK-NEXT: line53 +// CHECK-NEXT: col17 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: end // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line118 -// CHECK-NEXT: col15 +// CHECK-NEXT: line54 +// CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line118 -// CHECK-NEXT: col22 +// CHECK-NEXT: line54 +// CHECK-NEXT: col4 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: @@ -1002,52 +354,6 @@ // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line118 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line118 -// CHECK-NEXT: col29 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line118 -// CHECK-NEXT: col29 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to 'reallocf' has an allocation size of 0 bytes -// CHECK-NEXT: message -// CHECK-NEXT: Call to 'reallocf' has an allocation size of 0 bytes -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionCall to 'reallocf' has an allocation size of 0 bytes -// CHECK-NEXT: categoryUnix API -// CHECK-NEXT: typeUndefined allocation of 0 bytes (CERT MEM04-C; CWE-131) -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contexttest_reallocf -// CHECK-NEXT: issue_hash1 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line118 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: // CHECK-NEXT: kindcontrol // CHECK-NEXT: edges // CHECK-NEXT: @@ -1055,26 +361,26 @@ // CHECK-NEXT: start // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line136 +// CHECK-NEXT: line54 // CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line136 -// CHECK-NEXT: col6 +// CHECK-NEXT: line54 +// CHECK-NEXT: col4 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: end // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line136 -// CHECK-NEXT: col15 +// CHECK-NEXT: line54 +// CHECK-NEXT: col8 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line136 -// CHECK-NEXT: col20 +// CHECK-NEXT: line54 +// CHECK-NEXT: col9 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: @@ -1082,52 +388,6 @@ // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line136 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line136 -// CHECK-NEXT: col22 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line136 -// CHECK-NEXT: col22 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to 'alloca' has an allocation size of 0 bytes -// CHECK-NEXT: message -// CHECK-NEXT: Call to 'alloca' has an allocation size of 0 bytes -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionCall to 'alloca' has an allocation size of 0 bytes -// CHECK-NEXT: categoryUnix API -// CHECK-NEXT: typeUndefined allocation of 0 bytes (CERT MEM04-C; CWE-131) -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contexttest_alloca -// CHECK-NEXT: issue_hash1 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line136 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: // CHECK-NEXT: kindcontrol // CHECK-NEXT: edges // CHECK-NEXT: @@ -1135,26 +395,26 @@ // CHECK-NEXT: start // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line148 -// CHECK-NEXT: col3 +// CHECK-NEXT: line54 +// CHECK-NEXT: col8 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line148 -// CHECK-NEXT: col6 +// CHECK-NEXT: line54 +// CHECK-NEXT: col9 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: end // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line148 -// CHECK-NEXT: col16 +// CHECK-NEXT: line54 +// CHECK-NEXT: col52 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line148 -// CHECK-NEXT: col31 +// CHECK-NEXT: line54 +// CHECK-NEXT: col64 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: @@ -1165,42 +425,42 @@ // CHECK-NEXT: kindevent // CHECK-NEXT: location // CHECK-NEXT: -// CHECK-NEXT: line148 -// CHECK-NEXT: col16 +// CHECK-NEXT: line54 +// CHECK-NEXT: col52 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: ranges // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line148 -// CHECK-NEXT: col33 +// CHECK-NEXT: line54 +// CHECK-NEXT: col66 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line148 -// CHECK-NEXT: col33 +// CHECK-NEXT: line54 +// CHECK-NEXT: col72 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: depth0 // CHECK-NEXT: extended_message -// CHECK-NEXT: Call to 'alloca' has an allocation size of 0 bytes +// CHECK-NEXT: Call to 'dispatch_once' uses the local variable 'pred' for the predicate value. Using such transient memory for the predicate is potentially dangerous. Perhaps you intended to declare the variable as 'static'? // CHECK-NEXT: message -// CHECK-NEXT: Call to 'alloca' has an allocation size of 0 bytes +// CHECK-NEXT: Call to 'dispatch_once' uses the local variable 'pred' for the predicate value. Using such transient memory for the predicate is potentially dangerous. Perhaps you intended to declare the variable as 'static'? // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: descriptionCall to 'alloca' has an allocation size of 0 bytes -// CHECK-NEXT: categoryUnix API -// CHECK-NEXT: typeUndefined allocation of 0 bytes (CERT MEM04-C; CWE-131) +// CHECK-NEXT: descriptionCall to 'dispatch_once' uses the local variable 'pred' for the predicate value. Using such transient memory for the predicate is potentially dangerous. Perhaps you intended to declare the variable as 'static'? +// CHECK-NEXT: categoryAPI Misuse (Apple) +// CHECK-NEXT: typeImproper use of 'dispatch_once' // CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contexttest_builtin_alloca -// CHECK-NEXT: issue_hash1 +// CHECK-NEXT: issue_contexttest_dispatch_once +// CHECK-NEXT: issue_hash2 // CHECK-NEXT: location // CHECK-NEXT: -// CHECK-NEXT: line148 -// CHECK-NEXT: col16 +// CHECK-NEXT: line54 +// CHECK-NEXT: col52 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: @@ -1215,26 +475,26 @@ // CHECK-NEXT: start // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line160 +// CHECK-NEXT: line64 // CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line160 -// CHECK-NEXT: col6 +// CHECK-NEXT: line64 +// CHECK-NEXT: col16 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: end // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line160 -// CHECK-NEXT: col15 +// CHECK-NEXT: line65 +// CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line160 -// CHECK-NEXT: col20 +// CHECK-NEXT: line65 +// CHECK-NEXT: col14 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: @@ -1245,42 +505,42 @@ // CHECK-NEXT: kindevent // CHECK-NEXT: location // CHECK-NEXT: -// CHECK-NEXT: line160 -// CHECK-NEXT: col15 +// CHECK-NEXT: line65 +// CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: ranges // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line160 -// CHECK-NEXT: col22 +// CHECK-NEXT: line65 +// CHECK-NEXT: col16 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line160 -// CHECK-NEXT: col22 +// CHECK-NEXT: line65 +// CHECK-NEXT: col20 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: depth0 // CHECK-NEXT: extended_message -// CHECK-NEXT: Call to 'valloc' has an allocation size of 0 bytes +// CHECK-NEXT: Call to 'pthread_once' uses the local variable 'pred' for the "control" value. Using such transient memory for the control value is potentially dangerous. Perhaps you intended to declare the variable as 'static'? // CHECK-NEXT: message -// CHECK-NEXT: Call to 'valloc' has an allocation size of 0 bytes +// CHECK-NEXT: Call to 'pthread_once' uses the local variable 'pred' for the "control" value. Using such transient memory for the control value is potentially dangerous. Perhaps you intended to declare the variable as 'static'? // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: descriptionCall to 'valloc' has an allocation size of 0 bytes +// CHECK-NEXT: descriptionCall to 'pthread_once' uses the local variable 'pred' for the "control" value. Using such transient memory for the control value is potentially dangerous. Perhaps you intended to declare the variable as 'static'? // CHECK-NEXT: categoryUnix API -// CHECK-NEXT: typeUndefined allocation of 0 bytes (CERT MEM04-C; CWE-131) +// CHECK-NEXT: typeImproper use of 'pthread_once' // CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contexttest_valloc -// CHECK-NEXT: issue_hash1 +// CHECK-NEXT: issue_contexttest_pthread_once +// CHECK-NEXT: issue_hash2 // CHECK-NEXT: location // CHECK-NEXT: -// CHECK-NEXT: line160 -// CHECK-NEXT: col15 +// CHECK-NEXT: line65 +// CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: @@ -1295,12 +555,12 @@ // CHECK-NEXT: start // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line183 +// CHECK-NEXT: line83 // CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line183 +// CHECK-NEXT: line83 // CHECK-NEXT: col17 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -1308,12 +568,12 @@ // CHECK-NEXT: end // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line184 +// CHECK-NEXT: line84 // CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line184 +// CHECK-NEXT: line84 // CHECK-NEXT: col15 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -1325,7 +585,7 @@ // CHECK-NEXT: kindevent // CHECK-NEXT: location // CHECK-NEXT: -// CHECK-NEXT: line184 +// CHECK-NEXT: line84 // CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -1333,12 +593,12 @@ // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line184 +// CHECK-NEXT: line84 // CHECK-NEXT: col17 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line184 +// CHECK-NEXT: line84 // CHECK-NEXT: col21 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -1359,7 +619,7 @@ // CHECK-NEXT: issue_hash2 // CHECK-NEXT: location // CHECK-NEXT: -// CHECK-NEXT: line184 +// CHECK-NEXT: line84 // CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -1371,7 +631,7 @@ // CHECK-NEXT: kindevent // CHECK-NEXT: location // CHECK-NEXT: -// CHECK-NEXT: line189 +// CHECK-NEXT: line89 // CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -1379,12 +639,12 @@ // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line189 +// CHECK-NEXT: line89 // CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line189 +// CHECK-NEXT: line89 // CHECK-NEXT: col8 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -1404,12 +664,12 @@ // CHECK-NEXT: start // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line189 +// CHECK-NEXT: line89 // CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line189 +// CHECK-NEXT: line89 // CHECK-NEXT: col5 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -1417,12 +677,12 @@ // CHECK-NEXT: end // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line190 +// CHECK-NEXT: line90 // CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line190 +// CHECK-NEXT: line90 // CHECK-NEXT: col15 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -1438,12 +698,12 @@ // CHECK-NEXT: start // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line190 +// CHECK-NEXT: line90 // CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line190 +// CHECK-NEXT: line90 // CHECK-NEXT: col15 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -1451,12 +711,12 @@ // CHECK-NEXT: end // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line190 +// CHECK-NEXT: line90 // CHECK-NEXT: col24 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line190 +// CHECK-NEXT: line90 // CHECK-NEXT: col24 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -1468,7 +728,7 @@ // CHECK-NEXT: kindevent // CHECK-NEXT: location // CHECK-NEXT: -// CHECK-NEXT: line190 +// CHECK-NEXT: line90 // CHECK-NEXT: col24 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -1476,12 +736,12 @@ // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line190 +// CHECK-NEXT: line90 // CHECK-NEXT: col24 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line194 +// CHECK-NEXT: line94 // CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -1497,7 +757,7 @@ // CHECK-NEXT: kindevent // CHECK-NEXT: location // CHECK-NEXT: -// CHECK-NEXT: line190 +// CHECK-NEXT: line90 // CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -1505,12 +765,12 @@ // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line190 +// CHECK-NEXT: line90 // CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line194 +// CHECK-NEXT: line94 // CHECK-NEXT: col4 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -1526,7 +786,7 @@ // CHECK-NEXT: kindevent // CHECK-NEXT: location // CHECK-NEXT: -// CHECK-NEXT: line190 +// CHECK-NEXT: line90 // CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -1534,12 +794,12 @@ // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line190 +// CHECK-NEXT: line90 // CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line194 +// CHECK-NEXT: line94 // CHECK-NEXT: col4 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -1555,7 +815,7 @@ // CHECK-NEXT: kindevent // CHECK-NEXT: location // CHECK-NEXT: -// CHECK-NEXT: line190 +// CHECK-NEXT: line90 // CHECK-NEXT: col24 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -1573,12 +833,12 @@ // CHECK-NEXT: start // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line190 +// CHECK-NEXT: line90 // CHECK-NEXT: col24 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line190 +// CHECK-NEXT: line90 // CHECK-NEXT: col24 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -1586,12 +846,12 @@ // CHECK-NEXT: end // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line191 +// CHECK-NEXT: line91 // CHECK-NEXT: col4 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line191 +// CHECK-NEXT: line91 // CHECK-NEXT: col5 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -1607,12 +867,12 @@ // CHECK-NEXT: start // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line191 +// CHECK-NEXT: line91 // CHECK-NEXT: col4 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line191 +// CHECK-NEXT: line91 // CHECK-NEXT: col5 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -1620,12 +880,12 @@ // CHECK-NEXT: end // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line191 +// CHECK-NEXT: line91 // CHECK-NEXT: col8 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line191 +// CHECK-NEXT: line91 // CHECK-NEXT: col8 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -1637,7 +897,7 @@ // CHECK-NEXT: kindevent // CHECK-NEXT: location // CHECK-NEXT: -// CHECK-NEXT: line191 +// CHECK-NEXT: line91 // CHECK-NEXT: col8 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -1645,12 +905,12 @@ // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line191 +// CHECK-NEXT: line91 // CHECK-NEXT: col8 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line191 +// CHECK-NEXT: line91 // CHECK-NEXT: col8 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -1670,12 +930,12 @@ // CHECK-NEXT: start // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line191 +// CHECK-NEXT: line91 // CHECK-NEXT: col8 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line191 +// CHECK-NEXT: line91 // CHECK-NEXT: col8 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -1683,12 +943,12 @@ // CHECK-NEXT: end // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line192 +// CHECK-NEXT: line92 // CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line192 +// CHECK-NEXT: line92 // CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -1704,12 +964,12 @@ // CHECK-NEXT: start // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line192 +// CHECK-NEXT: line92 // CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line192 +// CHECK-NEXT: line92 // CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -1717,12 +977,12 @@ // CHECK-NEXT: end // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line192 +// CHECK-NEXT: line92 // CHECK-NEXT: col6 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line192 +// CHECK-NEXT: line92 // CHECK-NEXT: col6 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -1734,7 +994,7 @@ // CHECK-NEXT: kindevent // CHECK-NEXT: location // CHECK-NEXT: -// CHECK-NEXT: line192 +// CHECK-NEXT: line92 // CHECK-NEXT: col6 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -1742,12 +1002,12 @@ // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line192 +// CHECK-NEXT: line92 // CHECK-NEXT: col4 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line192 +// CHECK-NEXT: line92 // CHECK-NEXT: col4 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -1765,7 +1025,7 @@ // CHECK-NEXT: typeDereference of null pointer // CHECK-NEXT: location // CHECK-NEXT: -// CHECK-NEXT: line192 +// CHECK-NEXT: line92 // CHECK-NEXT: col6 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -1781,12 +1041,12 @@ // CHECK-NEXT: start // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line199 +// CHECK-NEXT: line99 // CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line199 +// CHECK-NEXT: line99 // CHECK-NEXT: col8 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -1794,12 +1054,12 @@ // CHECK-NEXT: end // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line200 +// CHECK-NEXT: line100 // CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line200 +// CHECK-NEXT: line100 // CHECK-NEXT: col5 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -1811,7 +1071,7 @@ // CHECK-NEXT: kindevent // CHECK-NEXT: location // CHECK-NEXT: -// CHECK-NEXT: line200 +// CHECK-NEXT: line100 // CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -1819,12 +1079,12 @@ // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line200 +// CHECK-NEXT: line100 // CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line200 +// CHECK-NEXT: line100 // CHECK-NEXT: col8 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -1844,12 +1104,12 @@ // CHECK-NEXT: start // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line200 +// CHECK-NEXT: line100 // CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line200 +// CHECK-NEXT: line100 // CHECK-NEXT: col5 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -1857,12 +1117,12 @@ // CHECK-NEXT: end // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line201 +// CHECK-NEXT: line101 // CHECK-NEXT: col24 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line201 +// CHECK-NEXT: line101 // CHECK-NEXT: col24 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -1874,7 +1134,7 @@ // CHECK-NEXT: kindevent // CHECK-NEXT: location // CHECK-NEXT: -// CHECK-NEXT: line201 +// CHECK-NEXT: line101 // CHECK-NEXT: col24 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -1882,12 +1142,12 @@ // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line201 +// CHECK-NEXT: line101 // CHECK-NEXT: col24 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line203 +// CHECK-NEXT: line103 // CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -1903,7 +1163,7 @@ // CHECK-NEXT: kindevent // CHECK-NEXT: location // CHECK-NEXT: -// CHECK-NEXT: line201 +// CHECK-NEXT: line101 // CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -1911,12 +1171,12 @@ // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line201 +// CHECK-NEXT: line101 // CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line203 +// CHECK-NEXT: line103 // CHECK-NEXT: col4 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -1932,7 +1192,7 @@ // CHECK-NEXT: kindevent // CHECK-NEXT: location // CHECK-NEXT: -// CHECK-NEXT: line175 +// CHECK-NEXT: line75 // CHECK-NEXT: col1 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -1950,12 +1210,12 @@ // CHECK-NEXT: start // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line175 +// CHECK-NEXT: line75 // CHECK-NEXT: col1 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line175 +// CHECK-NEXT: line75 // CHECK-NEXT: col6 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -1963,12 +1223,12 @@ // CHECK-NEXT: end // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line177 +// CHECK-NEXT: line77 // CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line177 +// CHECK-NEXT: line77 // CHECK-NEXT: col15 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -1980,7 +1240,7 @@ // CHECK-NEXT: kindevent // CHECK-NEXT: location // CHECK-NEXT: -// CHECK-NEXT: line177 +// CHECK-NEXT: line77 // CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -1988,12 +1248,12 @@ // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line177 +// CHECK-NEXT: line77 // CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line177 +// CHECK-NEXT: line77 // CHECK-NEXT: col33 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -2009,7 +1269,7 @@ // CHECK-NEXT: kindevent // CHECK-NEXT: location // CHECK-NEXT: -// CHECK-NEXT: line177 +// CHECK-NEXT: line77 // CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -2017,12 +1277,12 @@ // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line177 +// CHECK-NEXT: line77 // CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line177 +// CHECK-NEXT: line77 // CHECK-NEXT: col33 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -2038,7 +1298,7 @@ // CHECK-NEXT: kindevent // CHECK-NEXT: location // CHECK-NEXT: -// CHECK-NEXT: line201 +// CHECK-NEXT: line101 // CHECK-NEXT: col24 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -2056,12 +1316,12 @@ // CHECK-NEXT: start // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line201 +// CHECK-NEXT: line101 // CHECK-NEXT: col24 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line201 +// CHECK-NEXT: line101 // CHECK-NEXT: col24 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -2069,12 +1329,12 @@ // CHECK-NEXT: end // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line202 +// CHECK-NEXT: line102 // CHECK-NEXT: col4 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line202 +// CHECK-NEXT: line102 // CHECK-NEXT: col4 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -2090,12 +1350,12 @@ // CHECK-NEXT: start // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line202 +// CHECK-NEXT: line102 // CHECK-NEXT: col4 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line202 +// CHECK-NEXT: line102 // CHECK-NEXT: col4 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -2103,12 +1363,12 @@ // CHECK-NEXT: end // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line202 +// CHECK-NEXT: line102 // CHECK-NEXT: col7 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line202 +// CHECK-NEXT: line102 // CHECK-NEXT: col7 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -2120,7 +1380,7 @@ // CHECK-NEXT: kindevent // CHECK-NEXT: location // CHECK-NEXT: -// CHECK-NEXT: line202 +// CHECK-NEXT: line102 // CHECK-NEXT: col7 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -2128,12 +1388,12 @@ // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line202 +// CHECK-NEXT: line102 // CHECK-NEXT: col5 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line202 +// CHECK-NEXT: line102 // CHECK-NEXT: col5 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -2151,7 +1411,7 @@ // CHECK-NEXT: typeDereference of null pointer // CHECK-NEXT: location // CHECK-NEXT: -// CHECK-NEXT: line202 +// CHECK-NEXT: line102 // CHECK-NEXT: col7 // CHECK-NEXT: file0 // CHECK-NEXT: