[Cryptography] Ada vs Rust vs safer C

Florian Weimer fw at deneb.enyo.de
Sat Sep 17 13:11:59 EDT 2016


* Ron Garret:

> On Sep 17, 2016, at 8:55 AM, Florian Weimer <fw at deneb.enyo.de> wrote:
>
>>> 4.  If you really REALLY want to win big, define a new language that
>>> is just like C but where v[offset] and *(v+offset) are NOT equivalent
>>> operations, and deprecate the latter.
>> 
>> Existing compilers already track pointer provenance information, the
>> syntactic separation isn't really required.
>
> Yes, it is.  There is a significant difference between x[y] and *(x+y)
> despite the fact that the C standard specifies that these are
> equivalent constructs: in *(x+y) the offset calculation and
> dereference operation are *syntactically separable*, whereas in x[y]
> they are not.  So in the case of x[y] the compiler can know that this
> is an offset+dereference operation without having to do any analysis.
> *(x+y) is just a special case of *(f(x,y)), and figuring out whether
> or not that is equivalent to x[y] is uncomputable in general (it’s
> equivalent to the halting problem).
>
> This fact is reflected in real systems.  The following code:
>
> int main(int argc, char* argv[]) {
>   int x[100];
>   int y = x[101];
>   int z = *(x+101);
>   return y+z;
> }
>
> generates one warning under clang, not two (and zero under gcc even with -Wall).

Recent GCC generates:

t.c: In function ‘main’:
t.c:3:7: warning: ‘x[101]’ is used uninitialized in this function [-Wuninitialized]
   int y = x[101];
       ^
t.c:4:7: warning: ‘*((void *)&x+404)’ is used uninitialized in this function [-Wuninitialized]
   int z = *(x+101);
       ^
t.c:5:11: warning: ‘x[101]’ is used uninitialized in this function [-Wuninitialized]
   return y+z;
          ~^~

Not really pretty, I admit.

But if I change your example to:

int main(int argc, char* argv[]) {
  int x[100] = {0};
  int y = x[101];
  int z = *(x+102);
  return y+z;
}

GCC still warns:

t.c: In function ‘main’:
t.c:3:12: warning: array subscript is above array bounds [-Warray-bounds]
   int y = x[101];
           ~^~~~~
t.c:4:7: warning: ‘*((void *)&x+408)’ is used uninitialized in this function [-Wuninitialized]
   int z = *(x+102);
       ^

So GCC tracks both expressions and knows that they are problematic
because the subscript is out of bounds (although the GIMPLE
representation is different).  I'm not sure if the warnings are issued
from the same pass yet.


More information about the cryptography mailing list