[SystemSafety] Critical systems Linux

Olwen Morgan olwen at phaedsys.com
Fri Nov 23 16:05:12 CET 2018


On 23/11/2018 12:33, Olivier Andrieu wrote:
>
> I’m not sure why you’re making this about the compilers. This program 
> has unequivocally an undefined behavior, so, whatever a compiler does, 
> it’s not wrong.
>
> Clang doesn’t even require an explicit warning option to point it out:
>
> |$ clang se.c se.c:14:19: warning: multiple unsequenced modifications 
> to 'i' [-Wunsequenced] PrintEvalOrder((++i), (++i), (++i)); ^ ~~ 1 
> warning generated. |

gcc gives a similar warning but still gets the compiled code wrong, AFAI 
can infer, by being gung-ho with optimisation.

As regards behaviour, AFAI can see it's not "undefined" but is covered 
by "unspecified" or "implementation-defined" behaviour (Derek Jones may 
correct me here.)

The multiple side effects on i are deliberately contrived to diagnose 
the order of evaluation of the arguments to the function call. Compile 
the following similar program with gcc:

#include <stdio.h>

static int a[3] = {0, 0, 0};

void PrintEvalOrder( int p1, int p2, int p3)
{
     printf("\np1, p2, p3 evaluated in order: p%i, p%i, p%i\n", p1, p2, p3);
     return;
}

int main(void)
{
     int i = 0;

     /* next line tests order of eval. of args to a function call */

     PrintEvalOrder((a[0]=++i), (a[1]=++i), (a[2]=++i));

     return 0;
}

and running it gives the output: "p1, p2, p3 evaluated in order: p3, p2, 
p1" , while compiling under clang and then running gives: "p1, p2, p3 
evaluated in order: p1, p2, p3".

Now, obviously, in compiling from SPARK Ada onto C, you would avoid 
usages like the above. The point I'm trying to make is that, given the 
laxness of C's definition, you cannot, AFAI can see, guarantee that any 
given subset actually steers you clear of implementation dependencies 
arising from optimisations - over which many C compilers give 
frustratingly little control.

Buy any commercial embedded C compiler and the vendors will almost all 
tell you that they pass testing using well-known validation suites 
(Plum-Hall, Perennial, and SuperTest). Yet stress test such compilers 
with Csmith, and it's by no means uncommon to encounter code generation 
errors due to faulty optimisation. Therein lies the Achilles heel of 
compiling SPARK Ada to C and compiling it with gcc.

Back in the 1990s, Programming Research Ltd. marketed a tool called QAC 
Dynamic, which aimed to augment its static checker QAC by instrumenting 
code to analyse run-time behaviour. The form of instrumentation involved 
transforming the code into a wholly applicative style, so

a = b + c

would become something like:

assign(a, add(b, c))

The trouble was that the transformation changed the behaviour of the 
program. Just a few of my pathological test programs sufficed to show 
that transformation to the applicative style changed the orders of 
evaluation of expressions and thereby invalidated the dynamic analysis. 
The instrumentation should have been transparent but it was not. If 
C-to-C translation can do that, do you feel confident that SPARK-to-C won't?

I don't.

Olwen



Olwen






-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.techfak.uni-bielefeld.de/mailman/private/systemsafety/attachments/20181123/13ea12ac/attachment-0001.html>


More information about the systemsafety mailing list