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