This revision was automatically updated to reflect the committed changes.
Closed by commit rL248314: Analyzer: Teach analyzer how to handle TypeTraitExpr 
(authored by ismailp).

Changed prior to commit:
  http://reviews.llvm.org/D12482?vs=35384&id=35403#toc

Repository:
  rL LLVM

http://reviews.llvm.org/D12482

Files:
  cfe/trunk/lib/StaticAnalyzer/Core/Environment.cpp
  cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
  cfe/trunk/lib/StaticAnalyzer/Core/SValBuilder.cpp
  cfe/trunk/test/Analysis/dtor.cpp

Index: cfe/trunk/test/Analysis/dtor.cpp
===================================================================
--- cfe/trunk/test/Analysis/dtor.cpp
+++ cfe/trunk/test/Analysis/dtor.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze 
-analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config 
c++-inlining=destructors,cfg-temporary-dtors=true -Wno-null-dereference 
-Wno-inaccessible-base -verify %s
+// RUN: %clang_cc1 -analyze 
-analyzer-checker=core,unix.Malloc,debug.ExprInspection,cplusplus 
-analyzer-config c++-inlining=destructors,cfg-temporary-dtors=true 
-Wno-null-dereference -Wno-inaccessible-base -verify %s
 
 void clang_analyzer_eval(bool);
 void clang_analyzer_checkInlined(bool);
@@ -505,3 +505,38 @@
   class Foo; // expected-note{{forward declaration}}
   void f(Foo *foo) { delete foo; } // expected-warning{{deleting pointer to 
incomplete type}}
 }
+
+namespace TypeTraitExpr {
+template <bool IsSimple, typename T>
+struct copier {
+  static void do_copy(T *dest, const T *src, unsigned count);
+};
+template <typename T, typename U>
+void do_copy(T *dest, const U *src, unsigned count) {
+  const bool IsSimple = __is_trivial(T) && __is_same(T, U);
+  copier<IsSimple, T>::do_copy(dest, src, count);
+}
+struct NonTrivial {
+  int *p;
+  NonTrivial() : p(new int[1]) { p[0] = 0; }
+  NonTrivial(const NonTrivial &other) {
+    p = new int[1];
+    do_copy(p, other.p, 1);
+  }
+  NonTrivial &operator=(const NonTrivial &other) {
+    p = other.p;
+    return *this;
+  }
+  ~NonTrivial() {
+    delete[] p; // expected-warning {{free released memory}}
+  }
+};
+
+void f() {
+  NonTrivial nt1;
+  NonTrivial nt2(nt1);
+  nt1 = nt2;
+  clang_analyzer_eval(__is_trivial(NonTrivial)); // expected-warning{{FALSE}}
+  clang_analyzer_eval(__alignof(NonTrivial) > 0); // expected-warning{{TRUE}}
+}
+}
Index: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
===================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -756,7 +756,6 @@
     case Stmt::MSPropertyRefExprClass:
     case Stmt::CXXUnresolvedConstructExprClass:
     case Stmt::DependentScopeDeclRefExprClass:
-    case Stmt::TypeTraitExprClass:
     case Stmt::ArrayTypeTraitExprClass:
     case Stmt::ExpressionTraitExprClass:
     case Stmt::UnresolvedLookupExprClass:
@@ -902,7 +901,8 @@
     case Stmt::CXXPseudoDestructorExprClass:
     case Stmt::SubstNonTypeTemplateParmExprClass:
     case Stmt::CXXNullPtrLiteralExprClass:
-    case Stmt::OMPArraySectionExprClass: {
+    case Stmt::OMPArraySectionExprClass:
+    case Stmt::TypeTraitExprClass: {
       Bldr.takeNodes(Pred);
       ExplodedNodeSet preVisit;
       getCheckerManager().runCheckersForPreStmt(preVisit, Pred, S, *this);
Index: cfe/trunk/lib/StaticAnalyzer/Core/SValBuilder.cpp
===================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/SValBuilder.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Core/SValBuilder.cpp
@@ -259,6 +259,11 @@
   case Stmt::CXXBoolLiteralExprClass:
     return makeBoolVal(cast<CXXBoolLiteralExpr>(E));
 
+  case Stmt::TypeTraitExprClass: {
+    const TypeTraitExpr *TE = cast<TypeTraitExpr>(E);
+    return makeTruthVal(TE->getValue(), TE->getType());
+  }
+
   case Stmt::IntegerLiteralClass:
     return makeIntVal(cast<IntegerLiteral>(E));
 
Index: cfe/trunk/lib/StaticAnalyzer/Core/Environment.cpp
===================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/Environment.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Core/Environment.cpp
@@ -90,6 +90,7 @@
   case Stmt::CXXNullPtrLiteralExprClass:
   case Stmt::ObjCStringLiteralClass:
   case Stmt::StringLiteralClass:
+  case Stmt::TypeTraitExprClass:
     // Known constants; defer to SValBuilder.
     return svalBuilder.getConstantVal(cast<Expr>(S)).getValue();
 


Index: cfe/trunk/test/Analysis/dtor.cpp
===================================================================
--- cfe/trunk/test/Analysis/dtor.cpp
+++ cfe/trunk/test/Analysis/dtor.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-inlining=destructors,cfg-temporary-dtors=true -Wno-null-dereference -Wno-inaccessible-base -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection,cplusplus -analyzer-config c++-inlining=destructors,cfg-temporary-dtors=true -Wno-null-dereference -Wno-inaccessible-base -verify %s
 
 void clang_analyzer_eval(bool);
 void clang_analyzer_checkInlined(bool);
@@ -505,3 +505,38 @@
   class Foo; // expected-note{{forward declaration}}
   void f(Foo *foo) { delete foo; } // expected-warning{{deleting pointer to incomplete type}}
 }
+
+namespace TypeTraitExpr {
+template <bool IsSimple, typename T>
+struct copier {
+  static void do_copy(T *dest, const T *src, unsigned count);
+};
+template <typename T, typename U>
+void do_copy(T *dest, const U *src, unsigned count) {
+  const bool IsSimple = __is_trivial(T) && __is_same(T, U);
+  copier<IsSimple, T>::do_copy(dest, src, count);
+}
+struct NonTrivial {
+  int *p;
+  NonTrivial() : p(new int[1]) { p[0] = 0; }
+  NonTrivial(const NonTrivial &other) {
+    p = new int[1];
+    do_copy(p, other.p, 1);
+  }
+  NonTrivial &operator=(const NonTrivial &other) {
+    p = other.p;
+    return *this;
+  }
+  ~NonTrivial() {
+    delete[] p; // expected-warning {{free released memory}}
+  }
+};
+
+void f() {
+  NonTrivial nt1;
+  NonTrivial nt2(nt1);
+  nt1 = nt2;
+  clang_analyzer_eval(__is_trivial(NonTrivial)); // expected-warning{{FALSE}}
+  clang_analyzer_eval(__alignof(NonTrivial) > 0); // expected-warning{{TRUE}}
+}
+}
Index: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
===================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -756,7 +756,6 @@
     case Stmt::MSPropertyRefExprClass:
     case Stmt::CXXUnresolvedConstructExprClass:
     case Stmt::DependentScopeDeclRefExprClass:
-    case Stmt::TypeTraitExprClass:
     case Stmt::ArrayTypeTraitExprClass:
     case Stmt::ExpressionTraitExprClass:
     case Stmt::UnresolvedLookupExprClass:
@@ -902,7 +901,8 @@
     case Stmt::CXXPseudoDestructorExprClass:
     case Stmt::SubstNonTypeTemplateParmExprClass:
     case Stmt::CXXNullPtrLiteralExprClass:
-    case Stmt::OMPArraySectionExprClass: {
+    case Stmt::OMPArraySectionExprClass:
+    case Stmt::TypeTraitExprClass: {
       Bldr.takeNodes(Pred);
       ExplodedNodeSet preVisit;
       getCheckerManager().runCheckersForPreStmt(preVisit, Pred, S, *this);
Index: cfe/trunk/lib/StaticAnalyzer/Core/SValBuilder.cpp
===================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/SValBuilder.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Core/SValBuilder.cpp
@@ -259,6 +259,11 @@
   case Stmt::CXXBoolLiteralExprClass:
     return makeBoolVal(cast<CXXBoolLiteralExpr>(E));
 
+  case Stmt::TypeTraitExprClass: {
+    const TypeTraitExpr *TE = cast<TypeTraitExpr>(E);
+    return makeTruthVal(TE->getValue(), TE->getType());
+  }
+
   case Stmt::IntegerLiteralClass:
     return makeIntVal(cast<IntegerLiteral>(E));
 
Index: cfe/trunk/lib/StaticAnalyzer/Core/Environment.cpp
===================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/Environment.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Core/Environment.cpp
@@ -90,6 +90,7 @@
   case Stmt::CXXNullPtrLiteralExprClass:
   case Stmt::ObjCStringLiteralClass:
   case Stmt::StringLiteralClass:
+  case Stmt::TypeTraitExprClass:
     // Known constants; defer to SValBuilder.
     return svalBuilder.getConstantVal(cast<Expr>(S)).getValue();
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to