xref: /freebsd-src/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/ErrnoModeling.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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