<div dir="ltr"><div class="gmail_quote"><div dir="ltr">On Thu, 2 Aug 2018 at 14:41, Roman Popov via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hello,<div>I'm working on C++ interpreter that uses APSInt type to represent integers. I've just spent an hour debugging a bug the cause of which was unintuitive APSInt behavior / method signature.</div><div><br></div><div>APSInt assignments are declared as follows:</div><div><br></div><div><div>class LLVM_NODISCARD APSInt : public APInt {</div><div>...</div><div>  APSInt &operator=(APInt RHS) {<br></div><div><b>    // Retain our current sign.</b></div><div>    APInt::operator=(std::move(RHS));</div><div>    return *this;</div><div>  }</div><div><br></div><div>  APSInt &operator=(uint64_t RHS) {</div><div><b>    // Retain our current sign.</b></div><div>    APInt::operator=(RHS);</div><div>    return *this;</div><div>  }</div></div><div>...</div><div>};</div><div><br></div><div>By looking into header one may think that assignment <b>always retains the sign. </b>But this is not true, because automatically generated copy assignment will copy sign from RHS.</div></div></blockquote><div><br></div><div>Yes, APSInt's interface leaves a lot to be desired. Another trap:</div><div><br></div><div>APSInt N(123); // 123-bit unsigned APSInt, initialized to zero</div><div><br></div><div>Note that the APSInt constructor defaults to unsigned. But...</div><div><br></div><div>APSInt::get(123); // 64-bit *signed* APSInt, initialized to 123</div><div><br></div><div>... APSInt::get defaults to signed.</div><div><br></div><div><br></div><div>Also:</div><div><br></div><div>APInt N(64, 123); // 64-bit APInt, initialized to 123</div><div>APSInt N(64, 123); // 64-bit unsigned APSInt, initialized to 0</div><div><br></div><div>123 here is interpreted as an "isUnsigned" flag by the APSInt constructor.</div><div><br></div><div><br></div><div>Also:</div><div><br></div><div>APSInt X = ...;</div><div>bool k = X.isNegative(); // oops, returns true if the high bit is set, even if X is unsigned, because this calls APInt::isNegative.</div><div><br></div><div><br></div><div>Also:</div><div><br></div><div>APInt A = ...;</div><div>APSInt B = ...;</div><div>A *= A; // ok</div><div>B *= B; // ok</div><div>A *= 4; // ok</div><div>B *= 4; // error</div><div>A *= B; // ok</div><div>B *= A; // error<br></div><div><br></div><div><br></div><div>If you have the patience to clean up all the uses, I'm sure improvements to the interface would be welcomed.</div></div></div>