<div dir="ltr">On Fri, Oct 25, 2013 at 1:10 PM, Jeffrey Yasskin <span dir="ltr">&lt;<a href="mailto:jyasskin@google.com" target="_blank">jyasskin@google.com</a>&gt;</span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">On Fri, Oct 25, 2013 at 12:50 PM, Jens Maurer &lt;<a href="mailto:Jens.Maurer@gmx.net">Jens.Maurer@gmx.net</a>&gt; wrote:<br>

&gt; On 10/25/2013 09:36 PM, John Regehr wrote:<br>
&gt;&gt;&gt; What reason do you have to believe that crypto is using any signed<br>
&gt;&gt;&gt; arithmetic?  I would not.<br>
&gt;&gt;<br>
&gt;&gt; Here&#39;s an example that&#39;s at least slightly interesting, from the latest<br>
&gt;&gt; version of LibTomCrypt:<br>
&gt;&gt;<br>
&gt;&gt; kappa[i] =<br>
&gt;&gt;           (key[pos    ] &lt;&lt; 24) ^<br>
&gt;&gt;           (key[pos + 1] &lt;&lt; 16) ^<br>
&gt;&gt;           (key[pos + 2] &lt;&lt;  8) ^<br>
&gt;&gt;           (key[pos + 3]      );<br>
&gt;&gt;<br>
&gt;&gt; key is a pointer to unsigned char. Of course, the array element becomes<br>
&gt;&gt; signed after promotion. The shift by 24 then executes an undefined<br>
&gt;&gt; behavior whenever the shifted value is &gt;127.<br>
&gt;&gt;<br>
&gt;&gt; So the interesting thing is that the developer is basically doing things<br>
&gt;&gt; right and getting hosed by the arithmetic conversions.<br>
&gt;<br>
&gt; If I&#39;m reading 5p10 correctly, this should help (and is consistently<br>
&gt; expressing intent):<br>
&gt;<br>
&gt; kappa[i] =<br>
&gt;           (key[pos    ] &lt;&lt; 24u) ^<br>
&gt;           (key[pos + 1] &lt;&lt; 16u) ^<br>
&gt;           (key[pos + 2] &lt;&lt;  8u) ^<br>
&gt;           (key[pos + 3]      );<br>
&gt;<br>
&gt; Jens<br>
<br>
</div>Nope: [expr.shift]p1 says, &quot;The type of the result is that of the<br>
promoted left operand.&quot;<br></blockquote><div><br></div><div>I believe John is correct. 5.8/1 says we perform <i>integral promotions</i> on the operands, not the <i>usual arithmetic conversions</i>. Clang, g++, and EDG agree -- the type of (unsigned char)0 &lt;&lt; 0u is int.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
However, I think p2 saves our intrepid developer in C++14: &quot;Otherwise,<br>
if E1 has a signed type and non-negative value, and E1 × 2^E2 is<br>
representable in the corresponding unsigned type of the result type,<br>
then that value, converted to the result type, is the<br>
resulting value;&quot;</blockquote><div><br></div><div>We gave this defined behavior as a DR, so I view this code has having de facto defined behavior in C++11 and C++98 too. But it&#39;s UB in C.</div><div><br></div><div>
In other words, we&#39;ve already fixed this one (for some value of &quot;fixed&quot;).</div></div></div></div>