mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-14 19:49:36 +00:00
[analyzer] Move zero-size allocation checks to optin.portability.
This is a new checker package. It contains checkers that highlight well-documented implementation-defined behavior. Such checkers are only useful to developers that intend to write portable code. Code that is only compiled for a single platform should be allowed to rely on this platform's specific documented behavior. rdar://problem/30545046 Differential Revision: https://reviews.llvm.org/D34102 llvm-svn: 306396
This commit is contained in:
parent
4e6eed8566
commit
7caff0e9e1
@ -38,6 +38,11 @@ def CoreAlpha : Package<"core">, InPackage<Alpha>, Hidden;
|
||||
// default. Such checkers belong in the alpha package.
|
||||
def OptIn : Package<"optin">;
|
||||
|
||||
// In the Portability package reside checkers for finding code that relies on
|
||||
// implementation-defined behavior. Such checks are wanted for cross-platform
|
||||
// development, but unwanted for developers who target only a single platform.
|
||||
def PortabilityOptIn : Package<"portability">, InPackage<OptIn>;
|
||||
|
||||
def Nullability : Package<"nullability">;
|
||||
|
||||
def Cplusplus : Package<"cplusplus">;
|
||||
@ -416,7 +421,7 @@ def GenericTaintChecker : Checker<"TaintPropagation">,
|
||||
|
||||
let ParentPackage = Unix in {
|
||||
|
||||
def UnixAPIChecker : Checker<"API">,
|
||||
def UnixAPIMisuseChecker : Checker<"API">,
|
||||
HelpText<"Check calls to various UNIX/Posix functions">,
|
||||
DescFile<"UnixAPIChecker.cpp">;
|
||||
|
||||
@ -754,3 +759,14 @@ def CloneChecker : Checker<"CloneChecker">,
|
||||
|
||||
} // end "clone"
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Portability checkers.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
let ParentPackage = PortabilityOptIn in {
|
||||
|
||||
def UnixAPIPortabilityChecker : Checker<"UnixAPI">,
|
||||
HelpText<"Finds implementation-defined behavior in UNIX/Posix functions">,
|
||||
DescFile<"UnixAPIChecker.cpp">;
|
||||
|
||||
} // end optin.portability
|
||||
|
@ -45,6 +45,8 @@ class UnixAPIChecker : public Checker< check::PreStmt<CallExpr> > {
|
||||
mutable Optional<uint64_t> Val_O_CREAT;
|
||||
|
||||
public:
|
||||
DefaultBool CheckMisuse, CheckPortability;
|
||||
|
||||
void checkPreStmt(const CallExpr *CE, CheckerContext &C) const;
|
||||
|
||||
void CheckOpen(CheckerContext &C, const CallExpr *CE) const;
|
||||
@ -437,29 +439,42 @@ void UnixAPIChecker::checkPreStmt(const CallExpr *CE,
|
||||
if (FName.empty())
|
||||
return;
|
||||
|
||||
SubChecker SC =
|
||||
llvm::StringSwitch<SubChecker>(FName)
|
||||
.Case("open", &UnixAPIChecker::CheckOpen)
|
||||
.Case("openat", &UnixAPIChecker::CheckOpenAt)
|
||||
.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("__builtin_alloca_with_align",
|
||||
&UnixAPIChecker::CheckAllocaWithAlignZero)
|
||||
.Case("valloc", &UnixAPIChecker::CheckVallocZero)
|
||||
.Default(nullptr);
|
||||
|
||||
if (SC)
|
||||
(this->*SC)(C, CE);
|
||||
if (CheckMisuse) {
|
||||
if (SubChecker SC =
|
||||
llvm::StringSwitch<SubChecker>(FName)
|
||||
.Case("open", &UnixAPIChecker::CheckOpen)
|
||||
.Case("openat", &UnixAPIChecker::CheckOpenAt)
|
||||
.Case("pthread_once", &UnixAPIChecker::CheckPthreadOnce)
|
||||
.Default(nullptr)) {
|
||||
(this->*SC)(C, CE);
|
||||
}
|
||||
}
|
||||
if (CheckPortability) {
|
||||
if (SubChecker SC =
|
||||
llvm::StringSwitch<SubChecker>(FName)
|
||||
.Case("calloc", &UnixAPIChecker::CheckCallocZero)
|
||||
.Case("malloc", &UnixAPIChecker::CheckMallocZero)
|
||||
.Case("realloc", &UnixAPIChecker::CheckReallocZero)
|
||||
.Case("reallocf", &UnixAPIChecker::CheckReallocfZero)
|
||||
.Cases("alloca", "__builtin_alloca",
|
||||
&UnixAPIChecker::CheckAllocaZero)
|
||||
.Case("__builtin_alloca_with_align",
|
||||
&UnixAPIChecker::CheckAllocaWithAlignZero)
|
||||
.Case("valloc", &UnixAPIChecker::CheckVallocZero)
|
||||
.Default(nullptr)) {
|
||||
(this->*SC)(C, CE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Registration.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
void ento::registerUnixAPIChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<UnixAPIChecker>();
|
||||
}
|
||||
#define REGISTER_CHECKER(Name) \
|
||||
void ento::registerUnixAPI##Name##Checker(CheckerManager &mgr) { \
|
||||
mgr.registerChecker<UnixAPIChecker>()->Check##Name = true; \
|
||||
}
|
||||
|
||||
REGISTER_CHECKER(Misuse)
|
||||
REGISTER_CHECKER(Portability)
|
||||
|
@ -1,4 +1,5 @@
|
||||
// RUN: %clang_analyze_cc1 -triple x86_64-unknown-unknown -analyzer-checker=alpha.security.MallocOverflow,unix -verify %s
|
||||
// RUN: %clang_analyze_cc1 -triple x86_64-unknown-unknown -analyzer-checker=alpha.security.MallocOverflow,unix,optin.portability -DPORTABILITY -verify %s
|
||||
|
||||
typedef __typeof__(sizeof(int)) size_t;
|
||||
extern void *malloc(size_t);
|
||||
@ -32,5 +33,8 @@ static int table_build_1(struct table *t) {
|
||||
}
|
||||
|
||||
void *f(int n) {
|
||||
return malloc(n * 0 * sizeof(int)); // expected-warning {{Call to 'malloc' has an allocation size of 0 bytes}}
|
||||
return malloc(n * 0 * sizeof(int));
|
||||
#ifdef PORTABILITY
|
||||
// expected-warning@-2{{Call to 'malloc' has an allocation size of 0 bytes}}
|
||||
#endif
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,unix.API,osx.API %s -analyzer-store=region -analyzer-output=plist -analyzer-eagerly-assume -analyzer-config faux-bodies=true -analyzer-config path-diagnostics-alternate=false -fblocks -verify -o %t.plist
|
||||
// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,unix.API,osx.API,optin.portability %s -analyzer-store=region -analyzer-output=plist -analyzer-eagerly-assume -analyzer-config faux-bodies=true -analyzer-config path-diagnostics-alternate=false -fblocks -verify -o %t.plist
|
||||
// RUN: FileCheck --input-file=%t.plist %s
|
||||
// RUN: mkdir -p %t.dir
|
||||
// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.API,osx.API -analyzer-output=html -analyzer-config faux-bodies=true -fblocks -o %t.dir %s
|
||||
// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.API,osx.API,optin.portability -analyzer-output=html -analyzer-config faux-bodies=true -fblocks -o %t.dir %s
|
||||
// RUN: rm -fR %t.dir
|
||||
struct _opaque_pthread_once_t {
|
||||
long __sig;
|
||||
|
Loading…
Reference in New Issue
Block a user