On 06/03/2019 02:50, Segher Boessenkool wrote:
> On Tue, Mar 05, 2019 at 09:36:56PM +0100, David Brown wrote:
>> On 05/03/2019 19:37, Segher Boessenkool wrote:
>>> On Mon, Mar 04, 2019 at 09:45:37PM +0100, David Brown wrote:
>>>> void foo(void) {
>>>>     char key[20];
>>>>     strcpy(key, "Top secret");
>>>>     usekey(key);
>>>>     memset(key, 0, sizeof(key));
>>>>     {
>>>>         typedef struct { char x[20]; } XS;
>>>>         XS *p = (XS *) key;
>>>>         asm("" : "+m" (*p));
>>>>     }
>>>> }
>>>
>>> You need to use "asm volatile" here.  In principle GCC can see all the
>>> outputs of the asm are dead and delete all of the asm, otherwise.  But
>>> you don't need an output for *p (or inout as you wrote), just an input
>>> is fine.
>>
>> There are no outputs from this asm - only an input.
> 
> "+m" is an output.  There is only one colon before it, and besides, "+"
> is only allowed on outputs.
> 

My apologies - I had copied this from the wrong function in my code.
The "+m" makes this an input and an output - which in fact is good
enough here, since it forces the memset to be completed before the empty
asm code is run.  But it does mean the "output" should be used or it
risks being removed by the optimiser (when the "volatile" is omitted).

The asm line should have been:

        asm("" :: "m" (*p));

That makes it an input-only asm, which is automatically volatile.  It
may also aid optimisation in some cases, since the compiler knows the
value of "key" is unchanged after the assembly (unlike after the first
version of the asm).

Reply via email to