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:
Jordy Rose 2010-06-04 01:14:56 +00:00
Родитель 64fd7e86c1
Коммит 5d55376106
2 изменённых файлов: 44 добавлений и 10 удалений

Просмотреть файл

@ -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
}