[cfe-commits] r165743 - in /cfe/trunk/lib: Analysis/BodyFarm.cpp StaticAnalyzer/Checkers/OSAtomicChecker.cpp

Ted Kremenek kremenek at apple.com
Thu Oct 11 13:58:18 PDT 2012


Author: kremenek
Date: Thu Oct 11 15:58:18 2012
New Revision: 165743

URL: http://llvm.org/viewvc/llvm-project?rev=165743&view=rev
Log:
Switch over to BodyFarm implementation of OSAtomicCompareAndSwap and
objc_atomicCompareAndSwap.

Modified:
    cfe/trunk/lib/Analysis/BodyFarm.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/OSAtomicChecker.cpp

Modified: cfe/trunk/lib/Analysis/BodyFarm.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/BodyFarm.cpp?rev=165743&r1=165742&r2=165743&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/BodyFarm.cpp (original)
+++ cfe/trunk/lib/Analysis/BodyFarm.cpp Thu Oct 11 15:58:18 2012
@@ -16,6 +16,7 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/Decl.h"
+#include "clang/AST/ExprObjC.h"
 #include "BodyFarm.h"
 
 using namespace clang;
@@ -49,6 +50,13 @@
   /// Create a new BinaryOperator representing a simple assignment.
   BinaryOperator *makeAssignment(const Expr *LHS, const Expr *RHS, QualType Ty);
   
+  /// Create a new BinaryOperator representing a comparison.
+  BinaryOperator *makeComparison(const Expr *LHS, const Expr *RHS,
+                                 BinaryOperator::Opcode Op);
+  
+  /// Create a new compound stmt using the provided statements.
+  CompoundStmt *makeCompound(ArrayRef<Stmt*>);
+  
   /// Create a new DeclRefExpr for the referenced variable.
   DeclRefExpr *makeDeclRefExpr(const VarDecl *D);
   
@@ -58,9 +66,18 @@
   /// Create an implicit cast for an integer conversion.
   ImplicitCastExpr *makeIntegralCast(const Expr *Arg, QualType Ty);
   
+  /// Create an implicit cast to a builtin boolean type.
+  ImplicitCastExpr *makeIntegralCastToBoolean(const Expr *Arg);
+  
   // Create an implicit cast for lvalue-to-rvaluate conversions.
   ImplicitCastExpr *makeLvalueToRvalue(const Expr *Arg, QualType Ty);
   
+  /// Create an Objective-C bool literal.
+  ObjCBoolLiteralExpr *makeObjCBool(bool Val);
+  
+  /// Create a Return statement.
+  ReturnStmt *makeReturn(const Expr *RetVal);
+  
 private:
   ASTContext &C;
 };
@@ -73,6 +90,24 @@
                                OK_Ordinary, SourceLocation(), false);
 }
 
+BinaryOperator *ASTMaker::makeComparison(const Expr *LHS, const Expr *RHS,
+                                         BinaryOperator::Opcode Op) {
+  assert(BinaryOperator::isLogicalOp(Op) ||
+         BinaryOperator::isComparisonOp(Op));
+  return new (C) BinaryOperator(const_cast<Expr*>(LHS),
+                                const_cast<Expr*>(RHS),
+                                Op,
+                                C.getLogicalOperationType(),
+                                VK_RValue,
+                                OK_Ordinary, SourceLocation(), false);
+}
+
+CompoundStmt *ASTMaker::makeCompound(ArrayRef<Stmt *> Stmts) {
+  return new (C) CompoundStmt(C, const_cast<Stmt**>(Stmts.data()),
+                              Stmts.size(),
+                              SourceLocation(), SourceLocation());
+}
+
 DeclRefExpr *ASTMaker::makeDeclRefExpr(const VarDecl *D) {
   DeclRefExpr *DR =
     DeclRefExpr::Create(/* Ctx = */ C,
@@ -101,6 +136,20 @@
                                   const_cast<Expr*>(Arg), 0, VK_RValue);
 }
 
+ImplicitCastExpr *ASTMaker::makeIntegralCastToBoolean(const Expr *Arg) {
+  return ImplicitCastExpr::Create(C, C.BoolTy, CK_IntegralToBoolean,
+                                  const_cast<Expr*>(Arg), 0, VK_RValue);
+}
+
+ObjCBoolLiteralExpr *ASTMaker::makeObjCBool(bool Val) {
+  QualType Ty = C.getBOOLDecl() ? C.getBOOLType() : C.ObjCBuiltinBoolTy;
+  return new (C) ObjCBoolLiteralExpr(Val, Ty, SourceLocation());
+}
+
+ReturnStmt *ASTMaker::makeReturn(const Expr *RetVal) {
+  return new (C) ReturnStmt(SourceLocation(), const_cast<Expr*>(RetVal), 0);
+}
+
 //===----------------------------------------------------------------------===//
 // Creation functions for faux ASTs.
 //===----------------------------------------------------------------------===//
@@ -163,9 +212,8 @@
   // (3) Create the compound statement.
   Stmt *Stmts[2];
   Stmts[0] = B;
-  Stmts[1] = CE;  
-  CompoundStmt *CS = new (C) CompoundStmt(C, Stmts, 2, SourceLocation(),
-                                          SourceLocation());
+  Stmts[1] = CE;
+  CompoundStmt *CS = M.makeCompound(ArrayRef<Stmt*>(Stmts, 2));
   
   // (4) Create the 'if' condition.
   ImplicitCastExpr *LValToRval =
@@ -213,6 +261,71 @@
   return CE;
 }
 
+static Stmt *create_OSAtomicCompareAndSwap(ASTContext &C, const FunctionDecl *D)
+{
+  // There are exactly 3 arguments.
+  if (D->param_size() != 3)
+    return 0;
+  
+  // Body for:
+  //   if (oldValue == *theValue) {
+  //    *theValue = newValue;
+  //    return YES;
+  //   }
+  //   else return NO;
+  
+  const ParmVarDecl *OldValue = D->getParamDecl(0);
+  QualType OldValueTy = OldValue->getType();
+
+  const ParmVarDecl *NewValue = D->getParamDecl(1);
+  QualType NewValueTy = NewValue->getType();
+  
+  assert(OldValueTy == NewValueTy);
+  
+  const ParmVarDecl *TheValue = D->getParamDecl(2);
+  QualType TheValueTy = TheValue->getType();
+  const PointerType *PT = TheValueTy->getAs<PointerType>();
+  if (!PT)
+    return 0;
+  QualType PointeeTy = PT->getPointeeType();
+  
+  ASTMaker M(C);
+  // Construct the comparison.
+  Expr *Comparison =
+    M.makeComparison(
+      M.makeLvalueToRvalue(M.makeDeclRefExpr(OldValue), OldValueTy),
+      M.makeLvalueToRvalue(
+        M.makeDereference(
+          M.makeLvalueToRvalue(M.makeDeclRefExpr(TheValue), TheValueTy),
+          PointeeTy),
+        PointeeTy),
+      BO_EQ);
+
+  // Construct the body of the IfStmt.
+  Stmt *Stmts[2];
+  Stmts[0] =
+    M.makeAssignment(
+      M.makeDereference(
+        M.makeLvalueToRvalue(M.makeDeclRefExpr(TheValue), TheValueTy),
+        PointeeTy),
+      M.makeLvalueToRvalue(M.makeDeclRefExpr(NewValue), NewValueTy),
+      NewValueTy);
+  Stmts[1] =
+    M.makeReturn(M.makeIntegralCastToBoolean(M.makeObjCBool(true)));
+  CompoundStmt *Body = M.makeCompound(ArrayRef<Stmt*>(Stmts, 2));
+  
+  // Construct the else clause.
+  Stmt *Else =
+    M.makeReturn(M.makeIntegralCastToBoolean(M.makeObjCBool(false)));
+  
+  /// Construct the If.
+  Stmt *If =
+    new (C) IfStmt(C, SourceLocation(), 0, Comparison, Body,
+                   SourceLocation(), Else);
+  
+  return If;  
+}
+
 Stmt *BodyFarm::getBody(const FunctionDecl *D) {
   D = D->getCanonicalDecl();
   
@@ -228,17 +341,21 @@
   StringRef Name = D->getName();
   if (Name.empty())
     return 0;
-  
-  FunctionFarmer FF =
-    llvm::StringSwitch<FunctionFarmer>(Name)
-      .Case("dispatch_sync", create_dispatch_sync)
-      .Case("dispatch_once", create_dispatch_once)
-      .Default(NULL);
-  
-  if (FF) {
-    Val = FF(C, D);
+
+  FunctionFarmer FF;
+
+  if (Name.startswith("OSAtomicCompareAndSwap") ||
+      Name.startswith("objc_atomicCompareAndSwap")) {
+    FF = create_OSAtomicCompareAndSwap;
+  }
+  else {
+    FF = llvm::StringSwitch<FunctionFarmer>(Name)
+          .Case("dispatch_sync", create_dispatch_sync)
+          .Case("dispatch_once", create_dispatch_once)
+        .Default(NULL);
   }
   
+  if (FF) { Val = FF(C, D); }
   return Val.getValue();
 }
 

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/OSAtomicChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/OSAtomicChecker.cpp?rev=165743&r1=165742&r2=165743&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/OSAtomicChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/OSAtomicChecker.cpp Thu Oct 11 15:58:18 2012
@@ -212,5 +212,5 @@
 }
 
 void ento::registerOSAtomicChecker(CheckerManager &mgr) {
-  mgr.registerChecker<OSAtomicChecker>();
+  //  mgr.registerChecker<OSAtomicChecker>();
 }





More information about the cfe-commits mailing list