]> granicus.if.org Git - clang/commitdiff
Don't suggest the developer use 'arc4random' instead of 'rand' when that function...
authorTed Kremenek <kremenek@apple.com>
Fri, 15 Jan 2010 08:20:31 +0000 (08:20 +0000)
committerTed Kremenek <kremenek@apple.com>
Fri, 15 Jan 2010 08:20:31 +0000 (08:20 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@93508 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/CheckSecuritySyntaxOnly.cpp
test/Analysis/security-syntax-checks-no-emit.c [new file with mode: 0644]

index 3214101c6485ac129c4a28ba6398884519fa1427..f4874a5dfe4cd4467e9a8219196c22c296f374a0 100644 (file)
@@ -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"
 
 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 @@ class WalkAST : public StmtVisitor<WalkAST> {
   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 @@ void WalkAST::VisitCallExpr(CallExpr *CE) {
     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 (file)
index 0000000..fbfeb1a
--- /dev/null
@@ -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
+}