Added support for handling pointers to containers that wasn't handled.

 - jim

Index: test/Analysis/iterators.cpp
===================================================================
--- test/Analysis/iterators.cpp (revision 127607)
+++ test/Analysis/iterators.cpp (working copy)
@@ -5,8 +5,7 @@

 void fum(std::vector<int>::iterator t);

-void foo1()
-{
+void foo1() {
   // iterators that are defined but not initialized
   std::vector<int>::iterator it2;
   fum(it2); // expected-warning{{Use of iterator that is not defined}}
@@ -64,8 +63,7 @@
 }

 // work with using namespace
-void foo2()
-{
+void foo2() {
   using namespace std;

   vector<int> v;
@@ -78,8 +76,7 @@
 }

 // using reserve eliminates some warnings
-void foo3()
-{
+void foo3() {
   std::vector<long> v;
   std::vector<long>::iterator b = v.begin();
   v.reserve( 100 );
@@ -94,8 +91,7 @@
 }

 // check on copying one iterator to another
-void foo4()
-{
+void foo4() {
   std::vector<float> v, vv;
   std::vector<float>::iterator it = v.begin();
   *it;  // no-warning
@@ -103,3 +99,14 @@
*it; // expected-warning{{Attempt to use an iterator made invalid by copying another container to its container}}
 }

+// check for pointers to containers as well
+void foo5() {
+  std::vector<short> v, *vp;
+  vp = &v;
+  std::vector<short>::iterator it;
+  it = vp->begin();
+  *it;  // no-warning
+  vp->insert( it, 1 );
+ *it; // expected-warning{{Attempt to use an iterator made invalid by call to 'insert'.}}
+}
+
Index: lib/StaticAnalyzer/Checkers/IteratorsChecker.cpp
===================================================================
--- lib/StaticAnalyzer/Checkers/IteratorsChecker.cpp    (revision 127607)
+++ lib/StaticAnalyzer/Checkers/IteratorsChecker.cpp    (working copy)
@@ -197,6 +197,8 @@
 }

 static RefKind getTemplateKind(QualType T) {
+  if ( isa<PointerType>(T) )
+    T = T->getPointeeType();
   if (const TemplateSpecializationType *tsp =
       T->getAs<TemplateSpecializationType>()) {
     return getTemplateKind(tsp);
@@ -266,7 +268,10 @@
   if (const CallExpr *CE = dyn_cast<CallExpr>(rexp)) {
     // Handle MemberCall.
     if (const MemberExpr *ME = dyn_cast<MemberExpr>(CE->getCallee())) {
-      const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ME->getBase());
+      const Expr *exp = ME->getBase();
+      if (isa<ImplicitCastExpr>(exp))
+        exp = dyn_cast<ImplicitCastExpr>(exp)->getSubExpr();
+      const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(exp);
       if (!DRE)
         return state;
       // Verify that the type is std::vector<T>.
@@ -549,8 +554,11 @@
   const MemberExpr *ME = dyn_cast<MemberExpr>(MCE->getCallee());
   if (!ME)
     return;
+  const Expr *exp = ME->getBase();
+  if (isa<ImplicitCastExpr>(exp))
+    exp = dyn_cast<ImplicitCastExpr>(exp)->getSubExpr();
   // Make sure we have the right kind of container.
-  const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ME->getBase());
+  const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(exp);
   if (!DRE || getTemplateKind(DRE->getType()) != VectorKind)
     return;
   SVal tsv = C.getState()->getSVal(DRE);

Attachment: itptr.patch
Description: Binary data

_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to