Jakob, I think this exactly what's happening. I debugged the
resolveReferences for the ADD down into the resolve of TSFlags. It
calls VarInit::getFieldInit for the "Val" field of "foo".
The code is:
Init *VarInit::getFieldInit(Record &R, const RecordVal *RV,
const std::string &FieldName) const {
if (isa<RecordRecTy>(getType()))
if (const RecordVal *Val = R.getValue(VarName)) {
if (RV != Val && (RV || isa<UnsetInit>(Val->getValue())))
return 0;
Init *TheInit = Val->getValue();
assert(TheInit != this && "Infinite loop detected!");
if (Init *I = TheInit->getFieldInit(R, RV, FieldName)) // ***
return I;
else
return 0;
}
return 0;
}
The line marked with *** doesn't evaluate TheInit as a TernOpInit
correctly. It goes to the Init base class of getFieldInit and returns
0.
Do we need to add a getFieldInit method on TernOpInit to evaluate the
!if() and return the requested field of the result ("Val" in this
case) ?
On Thu, Jan 31, 2013 at 9:35 AM, Jakob Stoklund Olesen <stoklund at
2pi.dk> wrote:>
> On Jan 31, 2013, at 9:27 AM, Sean Silva <silvas at purdue.edu> wrote:
>
>> An extra call to resolveReferences after setting the value in the
>> `let` does fix this, but I'm not sure that it is the right fix. The
>> attached hackish patch seems to fix up a reduced version of the test
>> case you gave here (I haven't run a full battery of tests on it, so
it
>> might cause other failures).
>>
>> Jakob, any idea about what the "right" fix is here?
>
> Sorry, no.
>
> I do recall seeing similar problems in the past where the ternary operators
weren't properly evaluated, but left as TernOpInits in the final Records.
>
> I don't know of any use case where that would make sense, particularly
since other operators get evaluated. Are they even in use in the tree?
>
> /jakob
>