Author: Aaron Ballman Date: 2022-02-25T07:21:01-05:00 New Revision: f9e8e92cf586d9cf077139a338f062a91b8ce2d2
URL: https://github.com/llvm/llvm-project/commit/f9e8e92cf586d9cf077139a338f062a91b8ce2d2 DIFF: https://github.com/llvm/llvm-project/commit/f9e8e92cf586d9cf077139a338f062a91b8ce2d2.diff LOG: Revert "[clang][analyzer] Add modeling of 'errno'." This reverts commit 29b512ba322cb6dd2c45d5e07645e20db47fad0d. This broke several build bots: https://lab.llvm.org/buildbot/#/builders/86/builds/30183 https://lab.llvm.org/buildbot/#/builders/216/builds/488 Added: Modified: clang/include/clang/StaticAnalyzer/Checkers/Checkers.td clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt clang/lib/StaticAnalyzer/Core/MemRegion.cpp clang/test/Analysis/Inputs/system-header-simulator.h clang/test/Analysis/analyzer-enabled-checkers.c clang/test/Analysis/global-region-invalidation.c clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c Removed: clang/lib/StaticAnalyzer/Checkers/Errno.h clang/lib/StaticAnalyzer/Checkers/ErrnoModeling.cpp clang/lib/StaticAnalyzer/Checkers/ErrnoTesterChecker.cpp clang/test/Analysis/Inputs/errno_func.h clang/test/Analysis/Inputs/errno_var.h clang/test/Analysis/errno.c ################################################################################ diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td index 6b72d64950106..fae4240e9d701 100644 --- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td +++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -348,10 +348,6 @@ def NullableReturnedFromNonnullChecker : Checker<"NullableReturnedFromNonnull">, let ParentPackage = APIModeling in { -def ErrnoModeling : Checker<"Errno">, - HelpText<"Make the special value 'errno' available to other checkers.">, - Documentation<NotDocumented>; - def StdCLibraryFunctionsChecker : Checker<"StdCLibraryFunctions">, HelpText<"Improve modeling of the C standard library functions">, // Uninitialized value check is a mandatory dependency. This Checker asserts @@ -1560,11 +1556,6 @@ def StreamTesterChecker : Checker<"StreamTester">, "purposes.">, Documentation<NotDocumented>; -def ErrnoTesterChecker : Checker<"ErrnoTest">, - HelpText<"Check modeling aspects of 'errno'.">, - Dependencies<[ErrnoModeling]>, - Documentation<NotDocumented>; - def ExprInspectionChecker : Checker<"ExprInspection">, HelpText<"Check the analyzer's understanding of expressions">, Documentation<NotDocumented>; diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h index 0db6d92c63131..9f85347db5df7 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h @@ -764,8 +764,7 @@ class SymbolicRegion : public SubRegion { assert(s->getType()->isAnyPointerType() || s->getType()->isReferenceType() || s->getType()->isBlockPointerType()); - assert(isa<UnknownSpaceRegion>(sreg) || isa<HeapSpaceRegion>(sreg) || - isa<GlobalSystemSpaceRegion>(sreg)); + assert(isa<UnknownSpaceRegion>(sreg) || isa<HeapSpaceRegion>(sreg)); } public: @@ -1376,9 +1375,7 @@ class MemRegionManager { const LocationContext *LC); /// Retrieve or create a "symbolic" memory region. - /// If no memory space is specified, `UnknownSpaceRegion` will be used. - const SymbolicRegion * - getSymbolicRegion(SymbolRef Sym, const MemSpaceRegion *MemSpace = nullptr); + const SymbolicRegion* getSymbolicRegion(SymbolRef Sym); /// Return a unique symbolic region belonging to heap memory space. const SymbolicRegion *getSymbolicHeapRegion(SymbolRef sym); diff --git a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt index 15043c1c632e4..44fa2a06c3994 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt +++ b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt @@ -40,8 +40,6 @@ add_clang_library(clangStaticAnalyzerCheckers DynamicTypePropagation.cpp DynamicTypeChecker.cpp EnumCastOutOfRangeChecker.cpp - ErrnoModeling.cpp - ErrnoTesterChecker.cpp ExprInspectionChecker.cpp FixedAddressChecker.cpp FuchsiaHandleChecker.cpp diff --git a/clang/lib/StaticAnalyzer/Checkers/Errno.h b/clang/lib/StaticAnalyzer/Checkers/Errno.h deleted file mode 100644 index e564809d6bda9..0000000000000 --- a/clang/lib/StaticAnalyzer/Checkers/Errno.h +++ /dev/null @@ -1,39 +0,0 @@ -//=== Errno.h - Tracking value of 'errno'. -------------------------*- C++ -*-// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// Defines inter-checker API for using the system value 'errno'. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_ERRNO_H -#define LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_ERRNO_H - -#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" - -namespace clang { -namespace ento { -namespace errno_modeling { - -/// Returns the value of 'errno', if 'errno' was found in the AST. -llvm::Optional<SVal> getErrnoValue(ProgramStateRef State); - -/// Set value of 'errno' to any SVal, if possible. -ProgramStateRef setErrnoValue(ProgramStateRef State, - const LocationContext *LCtx, SVal Value); - -/// Set value of 'errno' to a concrete (signed) integer, if possible. -ProgramStateRef setErrnoValue(ProgramStateRef State, CheckerContext &C, - uint64_t Value); - -} // namespace errno_modeling -} // namespace ento -} // namespace clang - -#endif // LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_ERRNO_H diff --git a/clang/lib/StaticAnalyzer/Checkers/ErrnoModeling.cpp b/clang/lib/StaticAnalyzer/Checkers/ErrnoModeling.cpp deleted file mode 100644 index f61d52e6e9d6e..0000000000000 --- a/clang/lib/StaticAnalyzer/Checkers/ErrnoModeling.cpp +++ /dev/null @@ -1,253 +0,0 @@ -//=== ErrnoModeling.cpp -----------------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This defines a checker `ErrnoModeling`, which is used to make the system -// value 'errno' available to other checkers. -// The 'errno' value is stored at a special memory region that is accessible -// through the `errno_modeling` namespace. The memory region is either the -// region of `errno` itself if it is a variable, otherwise an artifically -// created region (in the system memory space). If `errno` is defined by using -// a function which returns the address of it (this is always the case if it is -// not a variable) this function is recognized and evaluated. In this way -// `errno` becomes visible to the analysis and checkers can change its value. -// -//===----------------------------------------------------------------------===// - -#include "Errno.h" -#include "clang/AST/ParentMapContext.h" -#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" -#include "clang/StaticAnalyzer/Core/Checker.h" -#include "clang/StaticAnalyzer/Core/CheckerManager.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" -#include "llvm/ADT/STLExtras.h" - -using namespace clang; -using namespace ento; - -namespace { - -// Name of the "errno" variable. -// FIXME: Is there a system where it is not called "errno" but is a variable? -const char *ErrnoVarName = "errno"; -// Names of functions that return a location of the "errno" value. -// FIXME: Are there other similar function names? -const char *ErrnoLocationFuncNames[] = {"__errno_location", "___errno", - "__errno", "_errno", "__error"}; - -class ErrnoModeling - : public Checker<check::ASTDecl<TranslationUnitDecl>, check::BeginFunction, - check::LiveSymbols, eval::Call> { -public: - void checkASTDecl(const TranslationUnitDecl *D, AnalysisManager &Mgr, - BugReporter &BR) const; - void checkBeginFunction(CheckerContext &C) const; - void checkLiveSymbols(ProgramStateRef State, SymbolReaper &SR) const; - bool evalCall(const CallEvent &Call, CheckerContext &C) const; - - // The declaration of an "errno" variable or "errno location" function. - static const Decl *ErrnoDecl; - -private: - // FIXME: Names from `ErrnoLocationFuncNames` are used to build this set. - CallDescriptionSet ErrnoLocationCalls{{"__errno_location", 0, 0}, - {"___errno", 0, 0}, - {"__errno", 0, 0}, - {"_errno", 0, 0}, - {"__error", 0, 0}}; -}; - -} // namespace - -/// Store a MemRegion that contains the 'errno' integer value. -/// The value is null if the 'errno' value was not recognized in the AST. -REGISTER_TRAIT_WITH_PROGRAMSTATE(ErrnoRegion, const void *) - -/// An internal function accessing the errno region. -/// Returns null if there isn't any associated memory region. -static const MemRegion *getErrnoRegion(ProgramStateRef State) { - return reinterpret_cast<const MemRegion *>(State->get<ErrnoRegion>()); -} - -/// Search for a variable called "errno" in the AST. -/// Return nullptr if not found. -static const VarDecl *getErrnoVar(ASTContext &ACtx) { - IdentifierInfo &II = ACtx.Idents.get(ErrnoVarName); - auto LookupRes = ACtx.getTranslationUnitDecl()->lookup(&II); - auto Found = llvm::find_if(LookupRes, [&ACtx](const Decl *D) { - if (auto *VD = dyn_cast<VarDecl>(D)) - return ACtx.getSourceManager().isInSystemHeader(VD->getLocation()) && - VD->hasExternalStorage() && - VD->getType().getCanonicalType() == ACtx.IntTy; - return false; - }); - if (Found == LookupRes.end()) - return nullptr; - - return cast<VarDecl>(*Found); -} - -/// Search for a function with a specific name that is used to return a pointer -/// to "errno". -/// Return nullptr if no such function was found. -static const FunctionDecl *getErrnoFunc(ASTContext &ACtx) { - SmallVector<const Decl *> LookupRes; - for (StringRef ErrnoName : ErrnoLocationFuncNames) { - IdentifierInfo &II = ACtx.Idents.get(ErrnoName); - llvm::append_range(LookupRes, ACtx.getTranslationUnitDecl()->lookup(&II)); - } - - auto Found = llvm::find_if(LookupRes, [&ACtx](const Decl *D) { - if (auto *FD = dyn_cast<FunctionDecl>(D)) - return ACtx.getSourceManager().isInSystemHeader(FD->getLocation()) && - FD->isExternC() && FD->getNumParams() == 0 && - FD->getReturnType().getCanonicalType() == - ACtx.getPointerType(ACtx.IntTy); - return false; - }); - if (Found == LookupRes.end()) - return nullptr; - - return cast<FunctionDecl>(*Found); -} - -const Decl *ErrnoModeling::ErrnoDecl = nullptr; - -void ErrnoModeling::checkASTDecl(const TranslationUnitDecl *D, - AnalysisManager &Mgr, BugReporter &BR) const { - // Try to find an usable `errno` value. - // It can be an external variable called "errno" or a function that returns a - // pointer to the "errno" value. This function can have diff erent names. - // The actual case is dependent on the C library implementation, we - // can only search for a match in one of these variations. - // We assume that exactly one of these cases might be true. - assert(!ErrnoDecl && "Checker should be used for one translation unit."); - - ErrnoDecl = getErrnoVar(Mgr.getASTContext()); - if (!ErrnoDecl) - ErrnoDecl = getErrnoFunc(Mgr.getASTContext()); -} - -void ErrnoModeling::checkBeginFunction(CheckerContext &C) const { - if (!C.inTopFrame()) - return; - - ASTContext &ACtx = C.getASTContext(); - ProgramStateRef State = C.getState(); - - if (const auto *ErrnoVar = dyn_cast_or_null<VarDecl>(ErrnoDecl)) { - // There is an external 'errno' variable. - // Use its memory region. - // The memory region for an 'errno'-like variable is allocated in system - // space by MemRegionManager. - const MemRegion *ErrnoR = - State->getRegion(ErrnoVar, C.getLocationContext()); - assert(ErrnoR && "Memory region should exist for the 'errno' variable."); - State = State->set<ErrnoRegion>(ErrnoR); - State = errno_modeling::setErrnoValue(State, C, 0); - C.addTransition(State); - } else if (ErrnoDecl) { - assert(isa<FunctionDecl>(ErrnoDecl) && "Invalid errno location function."); - // There is a function that returns the location of 'errno'. - // We must create a memory region for it in system space. - // Currently a symbolic region is used with an artifical symbol. - // FIXME: It is better to have a custom (new) kind of MemRegion for such - // cases. - SValBuilder &SVB = C.getSValBuilder(); - MemRegionManager &RMgr = C.getStateManager().getRegionManager(); - - const MemSpaceRegion *GlobalSystemSpace = - RMgr.getGlobalsRegion(MemRegion::GlobalSystemSpaceRegionKind); - - // Create an artifical symbol for the region. - // It is not possible to associate a statement or expression in this case. - const SymbolConjured *Sym = SVB.conjureSymbol( - nullptr, C.getLocationContext(), - ACtx.getLValueReferenceType(ACtx.IntTy), C.blockCount(), &ErrnoDecl); - - // The symbolic region is untyped, create a typed sub-region in it. - // The ElementRegion is used to make the errno region a typed region. - const MemRegion *ErrnoR = RMgr.getElementRegion( - ACtx.IntTy, SVB.makeZeroArrayIndex(), - RMgr.getSymbolicRegion(Sym, GlobalSystemSpace), C.getASTContext()); - State = State->set<ErrnoRegion>(ErrnoR); - State = errno_modeling::setErrnoValue(State, C, 0); - C.addTransition(State); - } -} - -bool ErrnoModeling::evalCall(const CallEvent &Call, CheckerContext &C) const { - // Return location of "errno" at a call to an "errno address returning" - // function. - if (ErrnoLocationCalls.contains(Call)) { - ProgramStateRef State = C.getState(); - - const MemRegion *ErrnoR = getErrnoRegion(State); - if (!ErrnoR) - return false; - - State = State->BindExpr(Call.getOriginExpr(), C.getLocationContext(), - loc::MemRegionVal{ErrnoR}); - C.addTransition(State); - return true; - } - - return false; -} - -void ErrnoModeling::checkLiveSymbols(ProgramStateRef State, - SymbolReaper &SR) const { - // The special errno region should never garbage collected. - if (const auto *ErrnoR = getErrnoRegion(State)) - SR.markLive(ErrnoR); -} - -namespace clang { -namespace ento { -namespace errno_modeling { - -Optional<SVal> getErrnoValue(ProgramStateRef State) { - const MemRegion *ErrnoR = getErrnoRegion(State); - if (!ErrnoR) - return {}; - QualType IntTy = State->getAnalysisManager().getASTContext().IntTy; - return State->getSVal(ErrnoR, IntTy); -} - -ProgramStateRef setErrnoValue(ProgramStateRef State, - const LocationContext *LCtx, SVal Value) { - const MemRegion *ErrnoR = getErrnoRegion(State); - if (!ErrnoR) - return State; - return State->bindLoc(loc::MemRegionVal{ErrnoR}, Value, LCtx); -} - -ProgramStateRef setErrnoValue(ProgramStateRef State, CheckerContext &C, - uint64_t Value) { - const MemRegion *ErrnoR = getErrnoRegion(State); - if (!ErrnoR) - return State; - return State->bindLoc( - loc::MemRegionVal{ErrnoR}, - C.getSValBuilder().makeIntVal(Value, C.getASTContext().IntTy), - C.getLocationContext()); -} - -} // namespace errno_modeling -} // namespace ento -} // namespace clang - -void ento::registerErrnoModeling(CheckerManager &mgr) { - mgr.registerChecker<ErrnoModeling>(); -} - -bool ento::shouldRegisterErrnoModeling(const CheckerManager &mgr) { - return true; -} diff --git a/clang/lib/StaticAnalyzer/Checkers/ErrnoTesterChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ErrnoTesterChecker.cpp deleted file mode 100644 index 62d536e54ec37..0000000000000 --- a/clang/lib/StaticAnalyzer/Checkers/ErrnoTesterChecker.cpp +++ /dev/null @@ -1,120 +0,0 @@ -//=== ErrnoTesterChecker.cpp ------------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This defines ErrnoTesterChecker, which is used to test functionality of the -// errno_check API. -// -//===----------------------------------------------------------------------===// - -#include "Errno.h" -#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" -#include "clang/StaticAnalyzer/Core/Checker.h" -#include "clang/StaticAnalyzer/Core/CheckerManager.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" - -using namespace clang; -using namespace ento; - -namespace { - -class ErrnoTesterChecker : public Checker<eval::Call> { -public: - bool evalCall(const CallEvent &Call, CheckerContext &C) const; - -private: - static void evalSetErrno(CheckerContext &C, const CallEvent &Call); - static void evalGetErrno(CheckerContext &C, const CallEvent &Call); - static void evalSetErrnoIfError(CheckerContext &C, const CallEvent &Call); - static void evalSetErrnoIfErrorRange(CheckerContext &C, - const CallEvent &Call); - - using EvalFn = std::function<void(CheckerContext &, const CallEvent &)>; - const CallDescriptionMap<EvalFn> TestCalls{ - {{"ErrnoTesterChecker_setErrno", 1}, &ErrnoTesterChecker::evalSetErrno}, - {{"ErrnoTesterChecker_getErrno", 0}, &ErrnoTesterChecker::evalGetErrno}, - {{"ErrnoTesterChecker_setErrnoIfError", 0}, - &ErrnoTesterChecker::evalSetErrnoIfError}, - {{"ErrnoTesterChecker_setErrnoIfErrorRange", 0}, - &ErrnoTesterChecker::evalSetErrnoIfErrorRange}}; -}; - -} // namespace - -void ErrnoTesterChecker::evalSetErrno(CheckerContext &C, - const CallEvent &Call) { - C.addTransition(errno_modeling::setErrnoValue( - C.getState(), C.getLocationContext(), Call.getArgSVal(0))); -} - -void ErrnoTesterChecker::evalGetErrno(CheckerContext &C, - const CallEvent &Call) { - ProgramStateRef State = C.getState(); - - Optional<SVal> ErrnoVal = errno_modeling::getErrnoValue(State); - assert(ErrnoVal && "Errno value should be available."); - State = - State->BindExpr(Call.getOriginExpr(), C.getLocationContext(), *ErrnoVal); - - C.addTransition(State); -} - -void ErrnoTesterChecker::evalSetErrnoIfError(CheckerContext &C, - const CallEvent &Call) { - ProgramStateRef State = C.getState(); - SValBuilder &SVB = C.getSValBuilder(); - - ProgramStateRef StateSuccess = State->BindExpr( - Call.getOriginExpr(), C.getLocationContext(), SVB.makeIntVal(0, true)); - - ProgramStateRef StateFailure = State->BindExpr( - Call.getOriginExpr(), C.getLocationContext(), SVB.makeIntVal(1, true)); - StateFailure = errno_modeling::setErrnoValue(StateFailure, C, 11); - - C.addTransition(StateSuccess); - C.addTransition(StateFailure); -} - -void ErrnoTesterChecker::evalSetErrnoIfErrorRange(CheckerContext &C, - const CallEvent &Call) { - ProgramStateRef State = C.getState(); - SValBuilder &SVB = C.getSValBuilder(); - - ProgramStateRef StateSuccess = State->BindExpr( - Call.getOriginExpr(), C.getLocationContext(), SVB.makeIntVal(0, true)); - - ProgramStateRef StateFailure = State->BindExpr( - Call.getOriginExpr(), C.getLocationContext(), SVB.makeIntVal(1, true)); - DefinedOrUnknownSVal ErrnoVal = SVB.conjureSymbolVal( - nullptr, Call.getOriginExpr(), C.getLocationContext(), C.blockCount()); - StateFailure = StateFailure->assume(ErrnoVal, true); - assert(StateFailure && "Failed to assume on an initial value."); - StateFailure = errno_modeling::setErrnoValue( - StateFailure, C.getLocationContext(), ErrnoVal); - - C.addTransition(StateSuccess); - C.addTransition(StateFailure); -} - -bool ErrnoTesterChecker::evalCall(const CallEvent &Call, - CheckerContext &C) const { - const EvalFn *Fn = TestCalls.lookup(Call); - if (Fn) { - (*Fn)(C, Call); - return C.isDifferent(); - } - return false; -} - -void ento::registerErrnoTesterChecker(CheckerManager &Mgr) { - Mgr.registerChecker<ErrnoTesterChecker>(); -} - -bool ento::shouldRegisterErrnoTesterChecker(const CheckerManager &Mgr) { - return true; -} diff --git a/clang/lib/StaticAnalyzer/Core/MemRegion.cpp b/clang/lib/StaticAnalyzer/Core/MemRegion.cpp index 6d0b5f85d84ed..58bea12f87836 100644 --- a/clang/lib/StaticAnalyzer/Core/MemRegion.cpp +++ b/clang/lib/StaticAnalyzer/Core/MemRegion.cpp @@ -1153,12 +1153,9 @@ MemRegionManager::getBlockCodeRegion(const BlockDecl *BD, CanQualType locTy, return getSubRegion<BlockCodeRegion>(BD, locTy, AC, getCodeRegion()); } -const SymbolicRegion * -MemRegionManager::getSymbolicRegion(SymbolRef sym, - const MemSpaceRegion *MemSpace) { - if (MemSpace == nullptr) - MemSpace = getUnknownRegion(); - return getSubRegion<SymbolicRegion>(sym, MemSpace); +/// getSymbolicRegion - Retrieve or create a "symbolic" memory region. +const SymbolicRegion *MemRegionManager::getSymbolicRegion(SymbolRef sym) { + return getSubRegion<SymbolicRegion>(sym, getUnknownRegion()); } const SymbolicRegion *MemRegionManager::getSymbolicHeapRegion(SymbolRef Sym) { diff --git a/clang/test/Analysis/Inputs/errno_func.h b/clang/test/Analysis/Inputs/errno_func.h deleted file mode 100644 index a6c74b1a08d1e..0000000000000 --- a/clang/test/Analysis/Inputs/errno_func.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma clang system_header - -// Define 'errno' as a macro that calls a function. -int *__errno_location(); -#define errno (*__errno_location()) diff --git a/clang/test/Analysis/Inputs/errno_var.h b/clang/test/Analysis/Inputs/errno_var.h deleted file mode 100644 index 82b1e9bf6285d..0000000000000 --- a/clang/test/Analysis/Inputs/errno_var.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma clang system_header - -// Declare 'errno' as an extern variable in a system header. -// This may be not allowed in C99. -extern int errno; diff --git a/clang/test/Analysis/Inputs/system-header-simulator.h b/clang/test/Analysis/Inputs/system-header-simulator.h index 70345c5f4022d..b72f45a9b0e55 100644 --- a/clang/test/Analysis/Inputs/system-header-simulator.h +++ b/clang/test/Analysis/Inputs/system-header-simulator.h @@ -59,6 +59,9 @@ int feof(FILE *stream); int ferror(FILE *stream); int fileno(FILE *stream); +// Note, on some platforms errno macro gets replaced with a function call. +extern int errno; + size_t strlen(const char *); char *strcpy(char *restrict, const char *restrict); diff --git a/clang/test/Analysis/analyzer-enabled-checkers.c b/clang/test/Analysis/analyzer-enabled-checkers.c index fa306d78d5553..7437e79a498f1 100644 --- a/clang/test/Analysis/analyzer-enabled-checkers.c +++ b/clang/test/Analysis/analyzer-enabled-checkers.c @@ -6,7 +6,6 @@ // CHECK: OVERVIEW: Clang Static Analyzer Enabled Checkers List // CHECK-EMPTY: -// CHECK-NEXT: apiModeling.Errno // CHECK-NEXT: core.CallAndMessageModeling // CHECK-NEXT: apiModeling.StdCLibraryFunctions // CHECK-NEXT: apiModeling.TrustNonnull diff --git a/clang/test/Analysis/errno.c b/clang/test/Analysis/errno.c deleted file mode 100644 index c2697d8891b19..0000000000000 --- a/clang/test/Analysis/errno.c +++ /dev/null @@ -1,58 +0,0 @@ -// RUN: %clang_analyze_cc1 -verify %s \ -// RUN: -analyzer-checker=core \ -// RUN: -analyzer-checker=apiModeling.Errno \ -// RUN: -analyzer-checker=debug.ExprInspection \ -// RUN: -analyzer-checker=debug.ErrnoTest \ -// RUN: -DERRNO_HEADER=\"Inputs/errno_var.h\" - -// RUN: %clang_analyze_cc1 -verify %s \ -// RUN: -analyzer-checker=core \ -// RUN: -analyzer-checker=apiModeling.Errno \ -// RUN: -analyzer-checker=debug.ExprInspection \ -// RUN: -analyzer-checker=debug.ErrnoTest \ -// RUN: -DERRNO_HEADER=\"Inputs/errno_func.h\" - -#include ERRNO_HEADER - -void clang_analyzer_eval(int); -void ErrnoTesterChecker_setErrno(int); -int ErrnoTesterChecker_getErrno(); -int ErrnoTesterChecker_setErrnoIfError(); -int ErrnoTesterChecker_setErrnoIfErrorRange(); - -void something(); - -void test() { - // Test if errno is initialized. - clang_analyzer_eval(errno == 0); // expected-warning{{TRUE}} - - ErrnoTesterChecker_setErrno(1); - // Test if errno was recognized and changed. - clang_analyzer_eval(errno == 1); // expected-warning{{TRUE}} - clang_analyzer_eval(ErrnoTesterChecker_getErrno() == 1); // expected-warning{{TRUE}} - - something(); - - // Test if errno was invalidated. - clang_analyzer_eval(errno); // expected-warning{{UNKNOWN}} - clang_analyzer_eval(ErrnoTesterChecker_getErrno()); // expected-warning{{UNKNOWN}} -} - -void testRange(int X) { - if (X > 0) { - ErrnoTesterChecker_setErrno(X); - clang_analyzer_eval(errno > 0); // expected-warning{{TRUE}} - } -} - -void testIfError() { - if (ErrnoTesterChecker_setErrnoIfError()) - clang_analyzer_eval(errno == 11); // expected-warning{{TRUE}} -} - -void testIfErrorRange() { - if (ErrnoTesterChecker_setErrnoIfErrorRange()) { - clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}} - clang_analyzer_eval(errno == 1); // expected-warning{{FALSE}} expected-warning{{TRUE}} - } -} diff --git a/clang/test/Analysis/global-region-invalidation.c b/clang/test/Analysis/global-region-invalidation.c index 123f51fe633d7..74ff72cfae00d 100644 --- a/clang/test/Analysis/global-region-invalidation.c +++ b/clang/test/Analysis/global-region-invalidation.c @@ -1,15 +1,8 @@ -// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -disable-free -verify %s \ -// RUN: -analyzer-checker=core,deadcode,alpha.security.taint,debug.TaintTest,debug.ExprInspection \ -// RUN: -DERRNO_HEADER=\"Inputs/errno_var.h\" %s - -// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -disable-free -verify %s \ -// RUN: -analyzer-checker=core,deadcode,alpha.security.taint,debug.TaintTest,debug.ExprInspection \ -// RUN: -DERRNO_HEADER=\"Inputs/errno_func.h\" +// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -disable-free -analyzer-checker=core,deadcode,alpha.security.taint,debug.TaintTest,debug.ExprInspection -verify %s void clang_analyzer_eval(int); // Note, we do need to include headers here, since the analyzer checks if the function declaration is located in a system header. -#include ERRNO_HEADER #include "Inputs/system-header-simulator.h" // Test that system header does not invalidate the internal global. diff --git a/clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c b/clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c index f00e10a0f056f..a64ec4a71487a 100644 --- a/clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c +++ b/clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c @@ -21,7 +21,6 @@ // CHECK-NEXT: alpha.unix.Stream // CHECK-NEXT: apiModeling.StdCLibraryFunctions // CHECK-NEXT: alpha.unix.StdCLibraryFunctionArgs -// CHECK-NEXT: apiModeling.Errno // CHECK-NEXT: apiModeling.TrustNonnull // CHECK-NEXT: apiModeling.TrustReturnsNonnull // CHECK-NEXT: apiModeling.llvm.CastValue _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits