Analyzer: Teach analyzer how to handle TypeTraitExpr
Summary: `TypeTraitExpr`s are not supported by the ExprEngine today. Analyzer creates a sink, and aborts the block. Therefore, certain bugs that involve type traits intrinsics cannot be detected (see PR24710). This patch creates boolean `SVal`s for `TypeTraitExpr`s, which are evaluated by the compiler. Test within the patch is a summary of PR24710. Reviewers: zaks.anna, dcoughlin, krememek Subscribers: cfe-commits Differential Revision: http://reviews.llvm.org/D12482 llvm-svn: 248314
This commit is contained in:
parent
66aa3a7f9e
commit
d60db64e7d
|
@ -90,6 +90,7 @@ SVal Environment::getSVal(const EnvironmentEntry &Entry,
|
|||
case Stmt::CXXNullPtrLiteralExprClass:
|
||||
case Stmt::ObjCStringLiteralClass:
|
||||
case Stmt::StringLiteralClass:
|
||||
case Stmt::TypeTraitExprClass:
|
||||
// Known constants; defer to SValBuilder.
|
||||
return svalBuilder.getConstantVal(cast<Expr>(S)).getValue();
|
||||
|
||||
|
|
|
@ -756,7 +756,6 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
|
|||
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 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
|
|||
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);
|
||||
|
|
|
@ -259,6 +259,11 @@ Optional<SVal> SValBuilder::getConstantVal(const Expr *E) {
|
|||
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));
|
||||
|
||||
|
|
|
@ -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 @@ namespace Incomplete {
|
|||
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}}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue