[cfe-commits] [PATCH] CallExprs returning references can be lvalues

Jordy Rose jediknil at belkadan.com
Thu Jun 3 00:24:19 PDT 2010


Resubmitting the second half of this patch, which notes that assigning to
a reference does not kill its old value. Chris gave me commit access
tonight, so I'll commit it tomorrow if there are no objections, since Ted
and Zhongxing already looked it over. (Just thought I'd give it one last
chance.)
-------------- next part --------------
Index: lib/Analysis/LiveVariables.cpp
===================================================================
--- lib/Analysis/LiveVariables.cpp	(revision 105255)
+++ lib/Analysis/LiveVariables.cpp	(working copy)
@@ -256,17 +256,21 @@
 
   // Assigning to a variable?
   if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(LHS->IgnoreParens())) {
+    // 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);
 
-    // Update liveness inforamtion.
-    unsigned bit = AD.getIdx(DR->getDecl());
-    LiveState.getDeclBit(bit) = Dead | AD.AlwaysLive.getDeclBit(bit);
+      if (AD.Observer) { AD.Observer->ObserverKill(DR); }
 
-    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);
+      // 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);
Index: test/Analysis/reference.cpp
===================================================================
--- test/Analysis/reference.cpp	(revision 105384)
+++ test/Analysis/reference.cpp	(working copy)
@@ -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 @@
   *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
+}


More information about the cfe-commits mailing list