181ad6265SDimitry Andric //=== ErrnoModeling.h - Tracking value of 'errno'. -----------------*- C++ -*-// 281ad6265SDimitry Andric // 381ad6265SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 481ad6265SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 581ad6265SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 681ad6265SDimitry Andric // 781ad6265SDimitry Andric //===----------------------------------------------------------------------===// 881ad6265SDimitry Andric // 981ad6265SDimitry Andric // Defines inter-checker API for using the system value 'errno'. 1081ad6265SDimitry Andric // 1181ad6265SDimitry Andric //===----------------------------------------------------------------------===// 1281ad6265SDimitry Andric 1381ad6265SDimitry Andric #ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_ERRNOMODELING_H 1481ad6265SDimitry Andric #define LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_ERRNOMODELING_H 1581ad6265SDimitry Andric 1681ad6265SDimitry Andric #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" 1781ad6265SDimitry Andric #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" 1881ad6265SDimitry Andric #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" 19bdd1243dSDimitry Andric #include <optional> 2081ad6265SDimitry Andric 2181ad6265SDimitry Andric namespace clang { 2281ad6265SDimitry Andric namespace ento { 2381ad6265SDimitry Andric namespace errno_modeling { 2481ad6265SDimitry Andric 25bdd1243dSDimitry Andric /// Describe how reads and writes of \c errno are handled by the checker. 2681ad6265SDimitry Andric enum ErrnoCheckState : unsigned { 2781ad6265SDimitry Andric /// We do not know anything about 'errno'. 28bdd1243dSDimitry Andric /// Read and write is always allowed. 2981ad6265SDimitry Andric Irrelevant = 0, 3081ad6265SDimitry Andric 3181ad6265SDimitry Andric /// Value of 'errno' should be checked to find out if a previous function call 3281ad6265SDimitry Andric /// has failed. 33bdd1243dSDimitry Andric /// When this state is set \c errno must be read by the program before a next 34bdd1243dSDimitry Andric /// standard function call or other overwrite of \c errno follows, otherwise 35bdd1243dSDimitry Andric /// a bug report is emitted. 3681ad6265SDimitry Andric MustBeChecked = 1, 3781ad6265SDimitry Andric 3881ad6265SDimitry Andric /// Value of 'errno' is not allowed to be read, it can contain an unspecified 3981ad6265SDimitry Andric /// value. 40bdd1243dSDimitry Andric /// When this state is set \c errno is not allowed to be read by the program 41bdd1243dSDimitry Andric /// until it is overwritten or invalidated. 4281ad6265SDimitry Andric MustNotBeChecked = 2 4381ad6265SDimitry Andric }; 4481ad6265SDimitry Andric 4581ad6265SDimitry Andric /// Returns the value of 'errno', if 'errno' was found in the AST. 46bdd1243dSDimitry Andric std::optional<SVal> getErrnoValue(ProgramStateRef State); 4781ad6265SDimitry Andric 4881ad6265SDimitry Andric /// Returns the errno check state, \c Errno_Irrelevant if 'errno' was not found 4981ad6265SDimitry Andric /// (this is not the only case for that value). 5081ad6265SDimitry Andric ErrnoCheckState getErrnoState(ProgramStateRef State); 5181ad6265SDimitry Andric 5281ad6265SDimitry Andric /// Returns the location that points to the \c MemoryRegion where the 'errno' 53bdd1243dSDimitry Andric /// value is stored. Returns \c std::nullopt if 'errno' was not found. Otherwise 54bdd1243dSDimitry Andric /// it always returns a valid memory region in the system global memory space. 55bdd1243dSDimitry Andric std::optional<Loc> getErrnoLoc(ProgramStateRef State); 5681ad6265SDimitry Andric 5781ad6265SDimitry Andric /// Set value of 'errno' to any SVal, if possible. 5881ad6265SDimitry Andric /// The errno check state is set always when the 'errno' value is set. 5981ad6265SDimitry Andric ProgramStateRef setErrnoValue(ProgramStateRef State, 6081ad6265SDimitry Andric const LocationContext *LCtx, SVal Value, 6181ad6265SDimitry Andric ErrnoCheckState EState); 6281ad6265SDimitry Andric 6381ad6265SDimitry Andric /// Set value of 'errno' to a concrete (signed) integer, if possible. 6481ad6265SDimitry Andric /// The errno check state is set always when the 'errno' value is set. 6581ad6265SDimitry Andric ProgramStateRef setErrnoValue(ProgramStateRef State, CheckerContext &C, 6681ad6265SDimitry Andric uint64_t Value, ErrnoCheckState EState); 6781ad6265SDimitry Andric 6881ad6265SDimitry Andric /// Set the errno check state, do not modify the errno value. 6981ad6265SDimitry Andric ProgramStateRef setErrnoState(ProgramStateRef State, ErrnoCheckState EState); 7081ad6265SDimitry Andric 71bdd1243dSDimitry Andric /// Clear state of errno (make it irrelevant). 72bdd1243dSDimitry Andric ProgramStateRef clearErrnoState(ProgramStateRef State); 73bdd1243dSDimitry Andric 74*0fca6ea1SDimitry Andric /// Determine if `Call` is a call to an internal function that returns the 75*0fca6ea1SDimitry Andric /// location of `errno` (in environments where errno is accessed this way). 76*0fca6ea1SDimitry Andric bool isErrnoLocationCall(const CallEvent &Call); 7781ad6265SDimitry Andric 7881ad6265SDimitry Andric /// Create a NoteTag that displays the message if the 'errno' memory region is 7981ad6265SDimitry Andric /// marked as interesting, and resets the interestingness. 8081ad6265SDimitry Andric const NoteTag *getErrnoNoteTag(CheckerContext &C, const std::string &Message); 8181ad6265SDimitry Andric 82bdd1243dSDimitry Andric /// Set errno state for the common case when a standard function is successful. 83bdd1243dSDimitry Andric /// Set \c ErrnoCheckState to \c MustNotBeChecked (the \c errno value is not 845f757f3fSDimitry Andric /// affected). 85bdd1243dSDimitry Andric ProgramStateRef setErrnoForStdSuccess(ProgramStateRef State, CheckerContext &C); 86bdd1243dSDimitry Andric 87bdd1243dSDimitry Andric /// Set errno state for the common case when a standard function fails. 88bdd1243dSDimitry Andric /// Set \c errno value to be not equal to zero and \c ErrnoCheckState to 89bdd1243dSDimitry Andric /// \c Irrelevant . The irrelevant errno state ensures that no related bug 90bdd1243dSDimitry Andric /// report is emitted later and no note tag is needed. 91bdd1243dSDimitry Andric /// \arg \c ErrnoSym Value to be used for \c errno and constrained to be 92bdd1243dSDimitry Andric /// non-zero. 93bdd1243dSDimitry Andric ProgramStateRef setErrnoForStdFailure(ProgramStateRef State, CheckerContext &C, 94bdd1243dSDimitry Andric NonLoc ErrnoSym); 95bdd1243dSDimitry Andric 96bdd1243dSDimitry Andric /// Set errno state for the common case when a standard function indicates 97bdd1243dSDimitry Andric /// failure only by \c errno. Sets \c ErrnoCheckState to \c MustBeChecked, and 98bdd1243dSDimitry Andric /// invalidates the errno region (clear of previous value). 99bdd1243dSDimitry Andric /// \arg \c InvalE Expression that causes invalidation of \c errno. 100bdd1243dSDimitry Andric ProgramStateRef setErrnoStdMustBeChecked(ProgramStateRef State, 101bdd1243dSDimitry Andric CheckerContext &C, const Expr *InvalE); 102bdd1243dSDimitry Andric 10381ad6265SDimitry Andric } // namespace errno_modeling 10481ad6265SDimitry Andric } // namespace ento 10581ad6265SDimitry Andric } // namespace clang 10681ad6265SDimitry Andric 10781ad6265SDimitry Andric #endif // LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_ERRNOMODELING_H 108