зеркало из https://github.com/microsoft/clang-1.git
[analyzer] Handle reference parameters with default values.
r175026 added support for default values, but didn't take reference parameters into account, which expect the default argument to be an lvalue. Use createTemporaryRegionIfNeeded if we can evaluate the default expr as an rvalue but the expected result is an lvalue. Fixes the most recent report of PR12915. The original report predates default argument support, so that can't be it. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@176042 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
59c900304a
Коммит
fbdbed3bde
|
@ -685,7 +685,8 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
|
|||
StmtNodeBuilder Bldr2(PreVisit, Tmp, *currBldrCtx);
|
||||
|
||||
const LocationContext *LCtx = Pred->getLocationContext();
|
||||
const Expr *ArgE = cast<CXXDefaultArgExpr>(S)->getExpr();
|
||||
const CXXDefaultArgExpr *DefaultE = cast<CXXDefaultArgExpr>(S);
|
||||
const Expr *ArgE = DefaultE->getExpr();
|
||||
|
||||
// Avoid creating and destroying a lot of APSInts.
|
||||
SVal V;
|
||||
|
@ -700,7 +701,9 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
|
|||
else
|
||||
V = State->getSVal(ArgE, LCtx);
|
||||
|
||||
State = State->BindExpr(S, LCtx, V);
|
||||
State = State->BindExpr(DefaultE, LCtx, V);
|
||||
if (DefaultE->isGLValue())
|
||||
State = createTemporaryRegionIfNeeded(State, LCtx, DefaultE);
|
||||
Bldr2.generateNode(S, *I, State);
|
||||
}
|
||||
|
||||
|
|
|
@ -1578,7 +1578,7 @@ static Optional<SVal> getConstValue(SValBuilder &SVB, const VarDecl *VD) {
|
|||
return None;
|
||||
|
||||
llvm::APSInt Result;
|
||||
if (Init->EvaluateAsInt(Result, Ctx))
|
||||
if (!Init->isGLValue() && Init->EvaluateAsInt(Result, Ctx))
|
||||
return SVB.makeIntVal(Result);
|
||||
|
||||
if (Init->isNullPointerConstant(Ctx, Expr::NPC_ValueDependentIsNotNull))
|
||||
|
|
|
@ -9,4 +9,11 @@ id foo(int x) {
|
|||
static id p = foo(1);
|
||||
clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
||||
const int &globalInt = 42;
|
||||
|
||||
void testGlobal() {
|
||||
// FIXME: Should be TRUE, but should at least not crash.
|
||||
clang_analyzer_eval(globalInt == 42); // expected-warning{{UNKNOWN}}
|
||||
}
|
||||
|
|
|
@ -260,6 +260,15 @@ namespace DefaultArgs {
|
|||
clang_analyzer_eval(complicatedExprUser(1) == 1); // expected-warning{{TRUE}}
|
||||
clang_analyzer_eval(complicatedExprUser() == 84); // expected-warning{{TRUE}}
|
||||
}
|
||||
|
||||
int defaultReference(const int &input = 42) {
|
||||
return input;
|
||||
}
|
||||
|
||||
void testReference() {
|
||||
clang_analyzer_eval(defaultReference(1) == 1); // expected-warning{{TRUE}}
|
||||
clang_analyzer_eval(defaultReference() == 42); // expected-warning{{TRUE}}
|
||||
}
|
||||
}
|
||||
|
||||
namespace OperatorNew {
|
||||
|
|
Загрузка…
Ссылка в новой задаче