bug is APFloat assignment

I am getting a segfault when assigning one APFloat to another, as in:

APFloat APF1(APFloat::IEEEdouble());

APFloat APF2 = APF1;

APFloat is a wrapper class that wraps either an IEEEFloat or a DoubleAPFloat. A union called Storage in APFloat contains the underlying object, which is one of those two types. The assignment APF2 = APF1 ends up calling APFloat::Storage::operator=() to copy the underlying object, which in this is an IEEEFloat, so we call IEEEFloat::operator=(). This assignment operator uses the semantics field of the LHS to decide whether it needs to free any storage being used by the LHS before assigning the RHS over it. But in this case the LHS is a newly constructed IEEEFloat, with semantics == 0, hence the crash.

This seems like a bug to me, but seems surprising not to have been already encountered. Am I missing something?

-Alan

Just tried it; seems to work fine. What assignment? “APFloat APF2 = APF1;” calls the copy constructor, not the assignment operator. -Eli

Sorry, I abbreviated the “test case” a little too much.

APF2 is actually defined separately. And it’s in a union, which avoids the issue that there is no APFloat(void). So it’s something like:

union U {

U() {}

~U() {}

APFloat APF2;

} u;

int main(int argc, char **argv) {

APFloat APF1(APFloat::IEEEdouble());

u.APF2 = APF1;

u.APF2.print(dbgs());

}

So this is a little more nuanced than I thought. I think the design is that it should not be possible to construct an APFloat without semantics, and this union thing circumvents that. I still think it’s a bug, but fairly easy to avoid: either properly construct APF2, or avoid assignment.

-Alan

It's an issue that's intrinsic to how unions interact with
constructors, I think. The standard even mentions it:

    "Note: In general, one must use explicit destructor calls and
placement new-expression to change the active member of a union."

Cheers.

Tim.