зеркало из https://github.com/microsoft/clang-1.git
Assignments to reference variables shouldn't kill the variable.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@105452 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
64fd7e86c1
Коммит
5d55376106
|
@ -256,17 +256,21 @@ void TransferFuncs::VisitAssign(BinaryOperator* B) {
|
|||
|
||||
// Assigning to a variable?
|
||||
if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(LHS->IgnoreParens())) {
|
||||
|
||||
// Update liveness inforamtion.
|
||||
unsigned bit = AD.getIdx(DR->getDecl());
|
||||
LiveState.getDeclBit(bit) = Dead | AD.AlwaysLive.getDeclBit(bit);
|
||||
|
||||
if (AD.Observer) { AD.Observer->ObserverKill(DR); }
|
||||
|
||||
// Handle things like +=, etc., which also generate "uses"
|
||||
// of a variable. Do this just by visiting the subexpression.
|
||||
if (B->getOpcode() != BinaryOperator::Assign)
|
||||
// Assignments to references don't kill the ref's address
|
||||
if (DR->getDecl()->getType()->isReferenceType()) {
|
||||
VisitDeclRefExpr(DR);
|
||||
} else {
|
||||
// Update liveness inforamtion.
|
||||
unsigned bit = AD.getIdx(DR->getDecl());
|
||||
LiveState.getDeclBit(bit) = Dead | AD.AlwaysLive.getDeclBit(bit);
|
||||
|
||||
if (AD.Observer) { AD.Observer->ObserverKill(DR); }
|
||||
|
||||
// Handle things like +=, etc., which also generate "uses"
|
||||
// of a variable. Do this just by visiting the subexpression.
|
||||
if (B->getOpcode() != BinaryOperator::Assign)
|
||||
VisitDeclRefExpr(DR);
|
||||
}
|
||||
}
|
||||
else // Not assigning to a variable. Process LHS as usual.
|
||||
Visit(LHS);
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -verify %s
|
||||
typedef typeof(sizeof(int)) size_t;
|
||||
void malloc (size_t);
|
||||
|
||||
void f1() {
|
||||
int const &i = 3;
|
||||
|
@ -24,3 +26,31 @@ char t2 () {
|
|||
*ptr() = 'c';
|
||||
return '0';
|
||||
}
|
||||
|
||||
// Each of the tests below is repeated with pointers as well as references.
|
||||
// This is mostly a sanity check, but then again, both should work!
|
||||
char t3 () {
|
||||
char& r = ref();
|
||||
r = 'c'; // no-warning
|
||||
if (r) return r;
|
||||
return *(char*)0; // no-warning
|
||||
}
|
||||
|
||||
char t4 () {
|
||||
char* p = ptr();
|
||||
*p = 'c'; // no-warning
|
||||
if (*p) return *p;
|
||||
return *(char*)0; // no-warning
|
||||
}
|
||||
|
||||
char t5 (char& r) {
|
||||
r = 'c'; // no-warning
|
||||
if (r) return r;
|
||||
return *(char*)0; // no-warning
|
||||
}
|
||||
|
||||
char t6 (char* p) {
|
||||
*p = 'c'; // no-warning
|
||||
if (*p) return *p;
|
||||
return *(char*)0; // no-warning
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче