<div class="gmail_quote">On Thu, Aug 16, 2012 at 9:21 AM, Hans Wennborg <span dir="ltr"><<a href="mailto:hans@chromium.org" target="_blank">hans@chromium.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="im">On Thu, Aug 16, 2012 at 5:09 PM, Jordan Rose <<a href="mailto:jordan_rose@apple.com">jordan_rose@apple.com</a>> wrote:<br>
> I'm trying to wrap my head around what this means and failing. 'int *a = *a'?<br>
<br>
</div>That isn't as sneaky as the reference case, because "*a" on the<br>
right-hand side has type int, so you'd get a warning about trying to<br>
initialize a pointer with an int.<br>
<br>
The self-initialized reference case is also extra bad because we know<br>
it's going to be invalid forever since it cannot be changed. A badly<br>
initialized pointer can at least be made valid later.<br>
<div class="im"><br>
> I wouldn't worry about the 'a(b), b(a)' case. Or rather, the issue is that 'b' is uninitialized in 'a(b)', and it doesn't really matter if it's given a valid initialization later.<br>

<br>
</div>Yeah, you're right. The reason I've got both a(b) and b(a) in there is<br>
because otherwise there'd be an error about one of them not getting<br>
initialized in the constructor.<br>
<div class="im"><br>
> I'm not so familiar with this part of Sema, but the diff looks reasonable.<br>
<br>
</div>Thanks! Anyone else who'd like to take a look?</blockquote><div><br></div><div>LGTM, modulo a couple of small things:</div><div> </div><div><div>> @@ -6309,13 +6312,13 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init,</div>
<div>>    }</div><div>>  </div><div>>    // Check for self-references within variable initializers.</div><div>> -  // Variables declared within a function/method body are handled</div><div>> -  // by a dataflow analysis.</div>
<div>> +  // Variables declared within a function/method body (except for references)</div><div>> +  // are handled by a dataflow analysis.</div><div>>    // Record types initialized by initializer list are handled here.</div>
<div>>    // Initialization by constructors are handled in TryConstructorInitialization.</div><div>> -  if (!VDecl->hasLocalStorage() &&</div><div>> -      (isa<InitListExpr>(Init) || !VDecl->getType()->isRecordType()))</div>
<div>> -    CheckSelfReference(RealDecl, Init);</div><div>> +  if (!VDecl->hasLocalStorage() || VDecl->getType()->isReferenceType())</div><div>> +    if (isa<InitListExpr>(Init) || !VDecl->getType()->isRecordType())</div>
<div>> +      CheckSelfReference(RealDecl, Init);</div></div><div><br></div><div>'&&' instead of nested 'if's? It might be clearer to reuse !isTrackedVar() (from Analysis/UninitializedValues.cpp) here, but I'm happy for the patch to go in either way.</div>
<div><br></div><div>> +++ b/test/SemaCXX/convert-to-bool.cpp</div><div><div>> @@ -62,6 +62,5 @@ struct C {</div><div>>  </div><div>>  void test_copy_init_conversions(C c) {</div><div>>    A &a = c; // expected-error{{no viable conversion from 'C' to 'A'}}</div>
<div>> -  B &b = b; // okay</div><div>> +  B &b = b; // okay expected-warning{{variable 'b' is uninitialized when used within its own initialization}}</div></div><div><br></div><div>Your warning found a bug in the test! I'm pretty sure this intended to say: B &b = c;</div>
</div>