[cfe-commits] r50364 - in /cfe/trunk: include/clang/AST/CFG.h lib/AST/CFG.cpp

Ted Kremenek kremenek at apple.com
Mon Apr 28 11:00:46 PDT 2008


Author: kremenek
Date: Mon Apr 28 13:00:46 2008
New Revision: 50364

URL: http://llvm.org/viewvc/llvm-project?rev=50364&view=rev
Log:
Bug fix in CFG::getBlockEdgeImpl(): Use a BumpPtrAllocator to allocate
std::pair<CFGBlock*, CFGBlock*> that have an 8-byte alignment for use with
ProgramPoint. This fixes a bug reported by Argiris where using std::set<> on
Windows would result in a 4-byte alignment, not an 8-byte alignment.

Fixes: <rdar://problem/5892265>

Modified:
    cfe/trunk/include/clang/AST/CFG.h
    cfe/trunk/lib/AST/CFG.cpp

Modified: cfe/trunk/include/clang/AST/CFG.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/CFG.h?rev=50364&r1=50363&r2=50364&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/CFG.h (original)
+++ cfe/trunk/include/clang/AST/CFG.h Mon Apr 28 13:00:46 2008
@@ -281,7 +281,7 @@
   //===--------------------------------------------------------------------===//
 
   CFG() : Entry(NULL), Exit(NULL), IndirectGotoBlock(NULL), NumBlockIDs(0), 
-          BlkExprMap(NULL), BlkEdgeSet(NULL) {};
+          BlkExprMap(NULL), BlkEdgeSet(NULL), Allocator(NULL) {};
   
   ~CFG();
     
@@ -298,13 +298,16 @@
   //  block-level expressions and their "statement number" in the CFG.
   void*     BlkExprMap;
   
-  /// BlkEdgeSet - An opaque pointer to prevent inclusion of <set>.
+  /// BlkEdgeSet - An opaque pointer to prevent inclusion of FoldingSet.h.
   ///  The set contains std::pair<CFGBlock*,CFGBlock*> objects that have
   ///  stable references for use by the 'BlockEdge' class.  This set is intended
   ///  to be sparse, as it only contains edges whether both the source
   ///  and destination block have multiple successors/predecessors.
   void*     BlkEdgeSet;
   
+  /// Alloc - An internal allocator used for BlkEdgeSet.
+  void*     Allocator;
+  
   friend class BlockEdge;
   
   /// getBlockEdgeImpl - Utility method used by the class BlockEdge.  The CFG

Modified: cfe/trunk/lib/AST/CFG.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/CFG.cpp?rev=50364&r1=50363&r2=50364&view=diff

==============================================================================
--- cfe/trunk/lib/AST/CFG.cpp (original)
+++ cfe/trunk/lib/AST/CFG.cpp Mon Apr 28 13:00:46 2008
@@ -21,11 +21,10 @@
 #include "llvm/Support/GraphWriter.h"
 #include "llvm/Support/Streams.h"
 #include "llvm/Support/Compiler.h"
-#include <set>
+#include <llvm/Support/Allocator.h>
 #include <iomanip>
 #include <algorithm>
 #include <sstream>
-#include <iostream>
 
 using namespace clang;
 
@@ -115,14 +114,20 @@
   
   // FIXME: Add support for ObjC-specific control-flow structures.
   
-  CFGBlock* VisitObjCForCollectionStmt(ObjCForCollectionStmt* Terminator) {
+  // NYS == Not Yet Supported
+  CFGBlock* NYS() {
     badCFG = true;
     return Block;
   }
   
-  CFGBlock* VisitObjCAtTryStmt(ObjCAtTryStmt* Terminator) {
-    badCFG = true;
-    return Block;
+  CFGBlock* VisitObjCForCollectionStmt(ObjCForCollectionStmt* S){ return NYS();}
+  CFGBlock* VisitObjCAtTryStmt(ObjCAtTryStmt* S) { return NYS(); }
+  CFGBlock* VisitObjCAtCatchStmt(ObjCAtCatchStmt* S) { return NYS(); }
+  CFGBlock* VisitObjCAtFinallyStmt(ObjCAtFinallyStmt* S) { return NYS(); }
+  CFGBlock* VisitObjCAtThrowStmt(ObjCAtThrowStmt* S) { return NYS(); }
+
+  CFGBlock* VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt* S){
+    return NYS();
   }
   
 private:
@@ -1150,21 +1155,77 @@
   }
 }
 
-typedef std::set<std::pair<CFGBlock*,CFGBlock*> > BlkEdgeSetTy;
+//===----------------------------------------------------------------------===//
+// Internal Block-Edge Set; used for modeling persistent <CFGBlock*,CFGBlock*>
+// pairs for use with ProgramPoint.
+//===----------------------------------------------------------------------===//
+
+typedef std::pair<CFGBlock*,CFGBlock*> BPairTy;
+
+namespace llvm {
+  template<> struct FoldingSetTrait<BPairTy*> {
+    static void Profile(const BPairTy* X, FoldingSetNodeID& profile) {
+      profile.AddPointer(X->first);
+      profile.AddPointer(X->second);
+    }
+  };
+}
+
+typedef llvm::FoldingSetNodeWrapper<BPairTy*> PersistPairTy;
+typedef llvm::FoldingSet<PersistPairTy> BlkEdgeSetTy;
 
 const std::pair<CFGBlock*,CFGBlock*>*
 CFG::getBlockEdgeImpl(const CFGBlock* B1, const CFGBlock* B2) {
   
+  llvm::BumpPtrAllocator*& Alloc =
+    reinterpret_cast<llvm::BumpPtrAllocator*&>(Allocator);
+  
+  if (!Alloc)
+    Alloc = new llvm::BumpPtrAllocator();
+
   BlkEdgeSetTy*& p = reinterpret_cast<BlkEdgeSetTy*&>(BlkEdgeSet);
-  if (!p) p = new BlkEdgeSetTy();
+
+  if (!p)
+    p = new BlkEdgeSetTy();
   
-  return &*(p->insert(std::make_pair(const_cast<CFGBlock*>(B1),
-                                     const_cast<CFGBlock*>(B2))).first);
+  // Profile the edges.
+  llvm::FoldingSetNodeID profile;
+  void* InsertPos;
+  
+  profile.AddPointer(B1);
+  profile.AddPointer(B2);
+  
+  PersistPairTy* V = p->FindNodeOrInsertPos(profile, InsertPos);  
+  
+  if (!V) {
+    assert (llvm::AlignOf<BPairTy>::Alignment_LessEqual_8Bytes);
+    
+    // Allocate the pair, forcing an 8-byte alignment.
+    BPairTy* pair = (BPairTy*) Alloc->Allocate(sizeof(*pair), 8);
+
+    new (pair) BPairTy(const_cast<CFGBlock*>(B1),
+                       const_cast<CFGBlock*>(B2));
+    
+    // Allocate the meta data to store the pair in the FoldingSet.
+    PersistPairTy* ppair = (PersistPairTy*) Alloc->Allocate<PersistPairTy>();
+    new (ppair) PersistPairTy(pair);
+    
+    p->InsertNode(ppair, InsertPos);
+    
+    return pair;
+  }
+  
+  return V->getValue();
 }
 
+//===----------------------------------------------------------------------===//
+// Cleanup: CFG dstor.
+//===----------------------------------------------------------------------===//
+
 CFG::~CFG() {
   delete reinterpret_cast<const BlkExprMapTy*>(BlkExprMap);
   delete reinterpret_cast<BlkEdgeSetTy*>(BlkEdgeSet);
+  delete reinterpret_cast<llvm::BumpPtrAllocator*> (Allocator);
 }
   
 //===----------------------------------------------------------------------===//
@@ -1542,9 +1603,6 @@
   GraphHelper = &H;
   llvm::ViewGraph(this,"CFG");
   GraphHelper = NULL;
-#else
-  std::cerr << "CFG::viewCFG is only available in debug builds on "
-            << "systems with Graphviz or gv!\n";
 #endif
 }
 





More information about the cfe-commits mailing list