[cfe-dev] Missing warning when binding to const ref?

Daniel Dilts diltsman at gmail.com
Tue Apr 7 21:20:40 PDT 2015


So, it would be something like:
If MaterializeTemporaryExpr and assign result to a reference that persists
beyond the scope of the function
Then generate a warning

Something like that?  I am not an expert on this; could someone else
comment on the reasonableness of this?

On Tue, Apr 7, 2015 at 8:55 PM, Nikola Smiljanic <popizdeh at gmail.com> wrote:

> We just ran into this in production, but as you can imagine it was much
> harder to spot. It only happened in optimized code. It was hidden behind
> templates and one member of the class would try to bind a const ref to int
> to something that was an enum. Combine that with mfc hash map and results
> are spectacular :)
>
> Looking at ast dump I can see MaterializeTemporaryExpr. Couldn't we just
> check that one of function's or constructor's arguments is coming from it?
>
> On Wed, Apr 8, 2015 at 1:41 PM, Daniel Dilts <diltsman at gmail.com> wrote:
>
>> Ah!  I finally see where your issue is.  This problem is probably better
>> suited for static code analysis.  For a trivial example like this you can
>> pretty quickly track down what is wrong, but for the more general case I
>> don't imagine that this being a check that can be done quickly enough for a
>> compiler warning.
>>
>> On Tue, Apr 7, 2015 at 8:04 PM, Nikola Smiljanic <popizdeh at gmail.com>
>> wrote:
>>
>>> I should have made a better comment, the types are different! Parameter
>>> needs to be implicitly converted to int, and we're binding a a const ref to
>>> this temp object whose lifetime ends once S is constructed. Unless I'm
>>> mistaken.
>>>
>>> On Wed, Apr 8, 2015 at 1:01 PM, Daniel Dilts <diltsman at gmail.com> wrote:
>>>
>>>>
>>>>
>>>> On Tue, Apr 7, 2015 at 6:11 PM, Nikola Smiljanic <popizdeh at gmail.com>
>>>> wrote:
>>>>
>>>>> I'm surprised this doesn't produce a warning:
>>>>>
>>>>> struct S
>>>>> {
>>>>> S(const int& i) : i(i) {}
>>>>> const int& i;
>>>>> };
>>>>>
>>>>> void foo(long l)
>>>>> {
>>>>> S s(l); // binding a const ref to temporary
>>>>> }
>>>>>
>>>>> int main()
>>>>> {
>>>>> foo(1l);
>>>>> }
>>>>>
>>>>>
>>>>> Why would that produce a warning?  You can bind an r-value to a const
>>>> l-value reference.  And, function foo takes the parameter by value, so it
>>>> is passing an l-value to the constructor of S.
>>>>
>>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20150407/d29e551c/attachment.html>


More information about the cfe-dev mailing list