<html><body bgcolor="#FFFFFF"><div><br><br><br></div><div><br>On Nov 13, 2008, at 6:43 PM, Zhongxing Xu <<a href="mailto:xuzhongxing@gmail.com">xuzhongxing@gmail.com</a>> wrote:<br><br></div><div></div><blockquote type="cite"><div><br><br><div class="gmail_quote">On Fri, Nov 14, 2008 at 10:31 AM, Ted Kremenek <span dir="ltr"><<a href="mailto:kremenek@apple.com"><a href="mailto:kremenek@apple.com">kremenek@apple.com</a></a>></span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<div style=""><br><div><div>On Nov 13, 2008, at 6:03 PM, Zhongxing Xu wrote:</div><br><blockquote type="cite"><span style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;">The standard does not specify any information about this conversion. The compiler interprets E1[E2] as *(E1+E2).</span></blockquote>
<div><br></div><div>That's right.  That's what the C standard says too. (section <a href="http://6.5.2.1" target="_blank">6.5.2.1</a>).</div><br><blockquote type="cite"><span style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;"> The sign does not affect the way that the machine does 'add' (or 'sub'). (The sign only affects some operations, c.f. LLVM instructions)</span></blockquote>
</div><div><br></div><div>I'm skeptical that the choice of signed-ness or bitwidth is arbitrary when handling E2, but I could be wrong.  Since the standard says that E1[E2] is the same as *(E1 + E2) than we probably need to perform any implicit type conversions that would be done by Sema if the expression was literally written that way.  The other option is to look at what compiler does (llvm-gcc for example).</div>
<div><br></div><div>For example:</div><div><br></div><div><div><div>void f(int *p) {</div><div>  short i = 0;</div><div>  unsigned short i_u = 0;  </div><div>  int j = 0;</div><div>  unsigned j_u = 0;</div><div>  long long k = 0;</div>
<div><br></div><div>  int x;</div><div>  x = *(p + i);</div><div>  x += *(p + j);</div><div>  x += *(p + i_u);</div><div>  x += *(p + j_u);</div><div>  x += *(p + k);</div><div>  </div><div>  return x;</div><div>}</div></div>
<div><br></div><div>The -ast-dump (without the DeclStmts) is:</div><div><br></div><div><div><div>  (BinaryOperator 0x21088f0 <line:9:3, col:14> 'int' '='</div><div>    (DeclRefExpr 0x2108810 <col:3> 'int' Var='x' 0x21087c0)</div>
<div>    (UnaryOperator 0x21088d0 <col:7, col:14> 'int' prefix '*'</div><div>      (ParenExpr 0x21088b0 <col:8, col:14> 'int *'</div><div>        (BinaryOperator 0x2108890 <col:9, col:13> 'int *' '+'</div>
<div>          (DeclRefExpr 0x2108830 <col:9> 'int *' ParmVar='p' 0x21084a0)</div><div><b>          (ImplicitCastExpr 0x2108870 <col:13> 'int'</b></div><div>            (DeclRefExpr 0x2108850 <col:13> 'short' Var='i' 0x21042e0))))))</div>
<div>  (CompoundAssignOperator 0x21089d0 <line:10:3, col:15> 'int' '+=' ComputeTy='int'</div><div>    (DeclRefExpr 0x2108910 <col:3> 'int' Var='x' 0x21087c0)</div><div>    (UnaryOperator 0x21089b0 <col:8, col:15> 'int' prefix '*'</div>
<div>      (ParenExpr 0x2108990 <col:9, col:15> 'int *'</div><div>        (BinaryOperator 0x2108970 <col:10, col:14> 'int *' '+'</div><div>          (DeclRefExpr 0x2108930 <col:10> 'int *' ParmVar='p' 0x21084a0)</div>
<div>          (DeclRefExpr 0x2108950 <col:14> 'int' Var='j' 0x2108630)))))</div><div>  (CompoundAssignOperator 0x2108ad0 <line:11:3, col:17> 'int' '+=' ComputeTy='int'</div>
<div>    (DeclRefExpr 0x21089f0 <col:3> 'int' Var='x' 0x21087c0)</div><div>    (UnaryOperator 0x2108ab0 <col:8, col:17> 'int' prefix '*'</div><div>      (ParenExpr 0x2108a90 <col:9, col:17> 'int *'</div>
<div>        (BinaryOperator 0x2108a70 <col:10, col:14> 'int *' '+'</div><div>          (DeclRefExpr 0x2108a10 <col:10> 'int *' ParmVar='p' 0x21084a0)</div><div><b>          (ImplicitCastExpr 0x2108a50 <col:14> 'int'</b></div>
<div>            (DeclRefExpr 0x2108a30 <col:14> 'unsigned short' Var='i_u' 0x21085a0))))))</div><div>  (CompoundAssignOperator 0x2108bb0 <line:12:3, col:17> 'int' '+=' ComputeTy='int'</div>
<div>    (DeclRefExpr 0x2108af0 <col:3> 'int' Var='x' 0x21087c0)</div><div>    (UnaryOperator 0x2108b90 <col:8, col:17> 'int' prefix '*'</div><div>      (ParenExpr 0x2108b70 <col:9, col:17> 'int *'</div>
<div>        (BinaryOperator 0x2108b50 <col:10, col:14> 'int *' '+'</div><div>          (DeclRefExpr 0x2108b10 <col:10> 'int *' ParmVar='p' 0x21084a0)</div><div>          (DeclRefExpr 0x2108b30 <col:14> 'unsigned int' Var='j_u' 0x21086a0)))))</div>
<div>  (CompoundAssignOperator 0x2108c90 <line:13:3, col:15> 'int' '+=' ComputeTy='int'</div><div>    (DeclRefExpr 0x2108bd0 <col:3> 'int' Var='x' 0x21087c0)</div><div>    (UnaryOperator 0x2108c70 <col:8, col:15> 'int' prefix '*'</div>
<div>      (ParenExpr 0x2108c50 <col:9, col:15> 'int *'</div><div>        (BinaryOperator 0x2108c30 <col:10, col:14> 'int *' '+'</div><div>          (DeclRefExpr 0x2108bf0 <col:10> 'int *' ParmVar='p' 0x21084a0)</div>
<div>          (DeclRefExpr 0x2108c10 <col:14> 'long long' Var='k' 0x2108730)))))</div><div><br></div><div>It appears that a promotion and sign change is done for 'short' and 'unsigned short' to int, but there are no conversions otherwise.  Is this correct?  Surely the compiler does some kind of promotion/truncation when doing pointer arithmetic.</div>
</div></div></div></div></blockquote></div><br>Is this the rule:<br> - if the bitwidth of E2 is the same as the pointer, do the arithmetic.<br> - if the bitwidth of E2 is different from the pointer, trunc or ext it to the same width of the pointer. Signed-ness affects the ext operation. Then do the arithmetic.<br>
</div></blockquote><br><div>I'm not certain.  Note that the 'long long' value 'k' was not truncated.  Is this a Sema bug, or is this the correct behavior?  For this target LongLongWidth is 64, the bit width for 'int' is 32, and the bit width for a pointer is (I believe) 32 bits as well.</div></body></html>