<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><br><div><div>On Jul 31, 2012, at 9:34 AM, Jordan Rose wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div>Author: jrose<br>Date: Tue Jul 31 11:34:07 2012<br>New Revision: 161051<br><br>URL: <a href="http://llvm.org/viewvc/llvm-project?rev=161051&view=rev">http://llvm.org/viewvc/llvm-project?rev=161051&view=rev</a><br>Log:<br>[analyzer] Getting an lvalue for a reference field still requires a load.<br><br>This was causing a crash in our array-to-pointer logic, since the region<br>was clearly not an array.<br><br>PR13440 / <<a href="rdar://problem/11977113">rdar://problem/11977113</a>><br><br>Modified:<br>    cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp<br>    cfe/trunk/test/Analysis/reference.cpp<br><br>Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=161051&r1=161050&r2=161051&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=161051&r1=161050&r2=161051&view=diff</a><br>==============================================================================<br>--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)<br>+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Tue Jul 31 11:34:07 2012<br>@@ -1522,10 +1522,17 @@<br><br>   // For all other cases, compute an lvalue.    <br>   SVal L = state->getLValue(field, baseExprVal);<br>-  if (M->isGLValue())<br>+  if (M->isGLValue()) {<br>+    if (field->getType()->isReferenceType()) {<br>+      if (const MemRegion *R = L.getAsRegion())<br>+        L = state->getSVal(R);<br>+      else<br>+        L = UnknownVal();<br>+    }<br></div></blockquote><div><br></div>This could be factored out somewhere. There other places where we add same special handling of references. Ex in the same source file:</div><div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; color: rgb(75, 144, 115); ">// For references, the '<span style="text-decoration: underline">lvalue</span>' is the pointer address stored in the</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; color: rgb(75, 144, 115); "><span style="color: #000000">    </span>// reference region.</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; ">    <span style="color: #951067">if</span> (VD->getType()->isReferenceType()) {</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; ">      <span style="color: #951067">if</span> (<span style="color: #951067">const</span> <span style="color: #006243">MemRegion</span> *R = V.getAsRegion())</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; ">        V = state->getSVal(R);</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; ">      <span style="color: #951067">else</span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; ">        V = UnknownVal();</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; ">    }</div><div><br></div></div><div><br><blockquote type="cite"><div>+<br>     Bldr.generateNode(M, Pred, state->BindExpr(M, LCtx, L), false, 0,<br>                       ProgramPoint::PostLValueKind);<br>-  else {<br>+  } else {<br>     Bldr.takeNodes(Pred);<br>     evalLoad(Dst, M, M, Pred, state, L);<br>     Bldr.addNodes(Dst);<br><br>Modified: cfe/trunk/test/Analysis/reference.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/reference.cpp?rev=161051&r1=161050&r2=161051&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/reference.cpp?rev=161051&r1=161050&r2=161051&view=diff</a><br>==============================================================================<br>--- cfe/trunk/test/Analysis/reference.cpp (original)<br>+++ cfe/trunk/test/Analysis/reference.cpp Tue Jul 31 11:34:07 2012<br>@@ -1,4 +1,6 @@<br>-// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core -analyzer-store=region -analyzer-constraints=range -verify -Wno-null-dereference %s<br>+// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core,debug.ExprInspection -analyzer-store=region -analyzer-constraints=range -verify -Wno-null-dereference %s<br>+<br>+void clang_analyzer_eval(bool);<br><br> typedef typeof(sizeof(int)) size_t;<br> void malloc (size_t);<br>@@ -55,3 +57,36 @@<br>   if (*p) return *p;<br>   return *(char*)0; // no-warning<br> }<br>+<br>+<br>+// PR13440 / <<a href="rdar://problem/11977113">rdar://problem/11977113</a>><br>+// Test that the array-to-pointer decay works for array references as well.<br>+// More generally, when we want an lvalue for a reference field, we still need<br>+// to do one level of load.<br>+namespace PR13440 {<br>+  typedef int T[1];<br>+  struct S {<br>+    T &x;<br>+<br>+    int *m() { return x; }<br>+  };<br>+<br>+  struct S2 {<br>+    int (&x)[1];<br>+<br>+    int *m() { return x; }<br>+  };<br>+<br>+  void test() {<br>+    int a[1];<br>+    S s = { a };<br>+    S2 s2 = { a };<br>+<br>+    if (s.x != a) return;<br>+    if (s2.x != a) return;<br>+<br>+    a[0] = 42;<br>+    clang_analyzer_eval(s.x[0] == 42); // expected-warning{{TRUE}}<br>+    clang_analyzer_eval(s2.x[0] == 42); // expected-warning{{TRUE}}<br>+  }<br>+}<br><br><br>_______________________________________________<br>cfe-commits mailing list<br><a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br><a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br></div></blockquote></div><br></body></html>