Don't suggest the developer use 'arc4random' instead of 'rand' when that function is not available. Fixes PR 6012.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@93508 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/CheckSecuritySyntaxOnly.cpp b/lib/Analysis/CheckSecuritySyntaxOnly.cpp
index 3214101..f4874a5 100644
--- a/lib/Analysis/CheckSecuritySyntaxOnly.cpp
+++ b/lib/Analysis/CheckSecuritySyntaxOnly.cpp
@@ -11,6 +11,7 @@
//
//===----------------------------------------------------------------------===//
+#include "clang/Basic/TargetInfo.h"
#include "clang/Analysis/PathSensitive/BugReporter.h"
#include "clang/Analysis/LocalCheckers.h"
#include "clang/AST/StmtVisitor.h"
@@ -18,6 +19,12 @@
using namespace clang;
+static bool isArc4RandomAvailable(const ASTContext &Ctx) {
+ const llvm::Triple &T = Ctx.Target.getTriple();
+ return T.getVendor() == llvm::Triple::Apple ||
+ T.getOS() == llvm::Triple::FreeBSD;
+}
+
namespace {
class WalkAST : public StmtVisitor<WalkAST> {
BugReporter &BR;
@@ -29,11 +36,14 @@
IdentifierInfo *II_random;
enum { num_setids = 6 };
IdentifierInfo *II_setid[num_setids];
+
+ const bool CheckRand;
public:
WalkAST(BugReporter &br) : BR(br),
II_gets(0), II_getpw(0), II_mktemp(0),
- II_rand(), II_random(0), II_setid() {}
+ II_rand(), II_random(0), II_setid(),
+ CheckRand(isArc4RandomAvailable(BR.getContext())) {}
// Statement visitor methods.
void VisitCallExpr(CallExpr *CE);
@@ -83,8 +93,10 @@
CheckCall_gets(CE, FD);
CheckCall_getpw(CE, FD);
CheckCall_mktemp(CE, FD);
- CheckCall_rand(CE, FD);
- CheckCall_random(CE, FD);
+ if (CheckRand) {
+ CheckCall_rand(CE, FD);
+ CheckCall_random(CE, FD);
+ }
}
// Recurse and check children.
diff --git a/test/Analysis/security-syntax-checks-no-emit.c b/test/Analysis/security-syntax-checks-no-emit.c
new file mode 100644
index 0000000..fbfeb1a
--- /dev/null
+++ b/test/Analysis/security-syntax-checks-no-emit.c
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -analyze -warn-security-syntactic %s -verify
+
+// This file complements 'security-syntax-checks.m', but tests that we omit
+// specific checks on platforms where they don't make sense.
+
+// Omit the 'rand' check since 'arc4random' is not available on Linux.
+int rand(void);
+double drand48(void);
+double erand48(unsigned short[3]);
+long jrand48(unsigned short[3]);
+void lcong48(unsigned short[7]);
+long lrand48(void);
+long mrand48(void);
+long nrand48(unsigned short[3]);
+long random(void);
+int rand_r(unsigned *);
+
+void test_rand()
+{
+ unsigned short a[7];
+ unsigned b;
+
+ rand(); // no-warning
+ drand48(); // no-warning
+ erand48(a); // no-warning
+ jrand48(a); // no-warning
+ lcong48(a); // no-warning
+ lrand48(); // no-warning
+ mrand48(); // no-warning
+ nrand48(a); // no-warning
+ rand_r(&b); // no-warning
+ random(); // no-warning
+}