forked from OSchip/llvm-project
[analyzer] Look through SubstNonTypeTemplateParmExprs.
We were treating this like a CXXDefaultArgExpr, but SubstNonTypeTemplateParmExpr actually appears when a template is instantiated, i.e. we have all the information necessary to evaluate it. This allows us to inline functions like llvm::array_lengthof. <rdar://problem/11949235> llvm-svn: 160846
This commit is contained in:
parent
de76c92b15
commit
41c98d9dc3
|
@ -96,6 +96,9 @@ SVal Environment::getSVal(const EnvironmentEntry &Entry,
|
|||
case Stmt::CXXBindTemporaryExprClass:
|
||||
E = cast<CXXBindTemporaryExpr>(E)->getSubExpr();
|
||||
continue;
|
||||
case Stmt::SubstNonTypeTemplateParmExprClass:
|
||||
E = cast<SubstNonTypeTemplateParmExpr>(E)->getReplacement();
|
||||
continue;
|
||||
case Stmt::ObjCStringLiteralClass: {
|
||||
MemRegionManager &MRMgr = svalBuilder.getRegionManager();
|
||||
const ObjCStringLiteral *SL = cast<ObjCStringLiteral>(E);
|
||||
|
|
|
@ -528,7 +528,6 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
|
|||
|
||||
// We don't handle default arguments either yet, but we can fake it
|
||||
// for now by just skipping them.
|
||||
case Stmt::SubstNonTypeTemplateParmExprClass:
|
||||
case Stmt::CXXDefaultArgExprClass:
|
||||
break;
|
||||
|
||||
|
@ -622,6 +621,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
|
|||
case Stmt::StringLiteralClass:
|
||||
case Stmt::ObjCStringLiteralClass:
|
||||
case Stmt::CXXBindTemporaryExprClass:
|
||||
case Stmt::SubstNonTypeTemplateParmExprClass:
|
||||
case Stmt::CXXNullPtrLiteralExprClass: {
|
||||
Bldr.takeNodes(Pred);
|
||||
ExplodedNodeSet preVisit;
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
// RUN: %clang_cc1 -analyze -analyzer-checker=core -fblocks -verify %s
|
||||
// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -fblocks -verify %s
|
||||
|
||||
void clang_analyzer_eval(bool);
|
||||
|
||||
// Do not crash on this templated code which uses a block.
|
||||
typedef void (^my_block)(void);
|
||||
|
@ -27,3 +29,16 @@ int main(){
|
|||
Mf m;
|
||||
m.I();
|
||||
}
|
||||
|
||||
|
||||
// <rdar://problem/11949235>
|
||||
template<class T, unsigned N>
|
||||
inline unsigned array_lengthof(T (&)[N]) {
|
||||
return N;
|
||||
}
|
||||
|
||||
void testNonTypeTemplateInstantiation() {
|
||||
const char *S[] = { "a", "b" };
|
||||
clang_analyzer_eval(array_lengthof(S) == 2); // expected-warning{{TRUE}}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue