Coder Social home page Coder Social logo

description of “volatile” in “Procedure Call Standard for the Arm 64-bit Architecture (AArch64)” is inconsistent with the C standard about abi-aa HOT 11 CLOSED

arm-software avatar arm-software commented on August 24, 2024
description of “volatile” in “Procedure Call Standard for the Arm 64-bit Architecture (AArch64)” is inconsistent with the C standard

from abi-aa.

Comments (11)

nsz-arm avatar nsz-arm commented on August 24, 2024

conforming iso c code cannot distinguish between ignoring volatile or not on an automatic variable whose address is never taken, assuming automatic variables are not accessed in ways unknown to the implementation. "What constitutes an access to an object that has volatile-qualified type is implementation-defined." So ignoring volatile in the specified case can be a valid implementation.

note that the example code has undefined behaviour as it does an lvalue conversion on an uninitialized automatic variable whose address is never taken, so any translation of f is valid.

from abi-aa.

rearnsha avatar rearnsha commented on August 24, 2024

Technically, I think the statement is unnecessary and it is more of an observation. As such, a footnote might be better. I'd also observe that even if the address of a volatile object is taken, then if the compiler can prove that the address never leaks into another object that is not itself automatic, then it should be free to treat it as if the address were not taken.

from abi-aa.

armask avatar armask commented on August 24, 2024

conforming iso c code cannot distinguish between ignoring volatile or not on an automatic variable whose address is never taken, assuming automatic variables are not accessed in ways unknown to the implementation.

Whether C code can distinguish or not is irrelevant (please, quote the standard if you believe otherwise), furthermore, this assumption makes no sense since it directly contradicts the ISO C11 standard, that says

An object that has volatile-qualified type may be modified in ways unknown to the implementation or have other unknown side effects. Therefore any expression referring to such an object shall be evaluated strictly according to the rules of the abstract machine, as described in 5.1.2.3.

That is with respect to access to volatile objects the implementation must follow the abstract machine:

The least requirements on a conforming implementation are:
— Accesses to volatile objects are evaluated strictly according to the rules of the abstract machine.
— […]
This is the observable behavior of the program.

Yes, the ISO C11 standard says

What constitutes an access to an object that has volatile-qualified type is implementation-defined.

but “implementation-defined” simply means that each conforming implementation needs to specify “how the choice is made”. For example,
https://docs.microsoft.com/en-us/cpp/c-language/qualifiers-access-to-volatile-objects:

Any reference to a volatile-qualified type is an access.

or for GCC https://github.com/gcc-mirror/gcc/blob/master/gcc/doc/implement-c.texi#L539:

In most expressions, it is intuitively obvious what is a read and what is a write.
[…] If it is a scalar type, or on most targets an aggregate type whose only member object is of a scalar type, or a union type whose member objects are of scalar types, the expression is interpreted by GCC as a read of the volatile object; in the other cases, the expression is only evaluated for its side effects.

from abi-aa.

nsz-arm avatar nsz-arm commented on August 24, 2024

conforming iso c code cannot distinguish between ignoring volatile or not on an automatic variable whose address is never taken, assuming automatic variables are not accessed in ways unknown to the implementation.

Whether C code can distinguish or not is irrelevant (please, quote the standard if you believe otherwise), furthermore, this assumption makes no sense since it directly contradicts the ISO C11 standard, that says

if there is no distinguisher then there can be no conformance violation, looking at generated assembly is of course not relevant for conformance, only runtime observed behaviour compared to the abstract machine is relevant. but the abstract machine states of iso c are in general not observable, so what's the meaning of volatile and why does the standard says it's observable when accessed? that's because there can be platform specific ways or language extensions that allow observing memory accesses in ways unknown to the c language implementation http://port70.net/~nsz/c/c11/n1570.html#6.7.3p7 however a particular platform can know those ways and then it can specify volatile semantics in more detail accordingly, which of course does not contradict iso c, this just provides further guarantees to the implementation about the platform (e.g. that automatic variable access is not observable in unknown ways).

actually since c11 there is a way that makes volatile observable, even if there is no platform specific way to observe memory accesses: loops can be assumed to terminate unless they do io or access volatile objects http://port70.net/~nsz/c/c11/n1570.html#6.8.5p6 so an implementation that optimizes an infinite loop away that accesses a volatile automatic variable is observably non-conforming. (the text under discussion was written before this optimization was allowed in c11.)

given this change in c11 i support the removal of the text about volatiles (or extending it to mention infinite loops and not just the address taken case).

from abi-aa.

armask avatar armask commented on August 24, 2024

if there is no distinguisher then there can be no conformance violation, looking at generated assembly is of course not relevant for conformance, only runtime observed behaviour compared to the abstract machine is relevant.

No, where does the standard say this?

Section 5.1.2.3 “Program execution” of ISO C11 is very explicit about “abstract machine” and “actual implementation”. The access to volatile objects is explicitly required for “implementation”:

An actual implementation need not evaluate part of an expression if it can deduce that its value is not used and that no needed side effects are produced (including any caused by calling a function or accessing a volatile object).

The least requirements on a conforming implementation are:
— Accesses to volatile objects are evaluated strictly according to the rules of the abstract machine.
— […]
This is the observable behavior of the program.

You say

there can be platform specific ways or language extensions that allow observing memory accesses in ways unknown to the c language implementation http://port70.net/~nsz/c/c11/n1570.html#6.7.3p7 however a particular platform can know those ways and then it can specify volatile semantics in more detail accordingly, which of course does not contradict iso c

If the standard provides some justification for a requirement and you have reasons to believe that the justification is not good enough, it does not mean that the requirement is not applicable. No, if a requirement is not implemented, then the implementation is not “conforming”. Here the justification is

An object that has volatile-qualified type may be modified in ways unknown to the implementation or have other unknown side effects.

While I do not believe that it can ever be wrong, because a program can be single-stepped with ptrace(2) or JTAG, but even if this is the case, it does not make the requirement less required:

Therefore any expression referring to such an object shall be evaluated strictly according to the rules of the abstract machine, as described in 5.1.2.3.

from abi-aa.

nsz-arm avatar nsz-arm commented on August 24, 2024

if there is no distinguisher then there can be no conformance violation, looking at generated assembly is of course not relevant for conformance, only runtime observed behaviour compared to the abstract machine is relevant.

No, where does the standard say this?

well, you can disagree with my interpretation, but you need to demonstrate it with an actual example where your interpretation and my interpretation causes different behaviour, to start a relevant discussion.

arguing about semantics that's outside the scope of the standard is not helpful and there is no mapping from "access to volatile object" to machine behaviour that's observable, nor a mapping from abstract machine states to actual machine states, i.e. "strictly according to the abstract machine" is not meaningful by itself (debugging does not change this). iso c just assumes there may be a way for volatile objects to be observable in which case (and only in that case) an implementation has to take that into account (otherwise the requirement is entirely meaningless).

e.g. on a platform with no io capability, io operations are simply not observable, independently of what the c standard says, so those can be optimized away without changing the behaviour of conforming programs. volatile access is no different and on an arm platform volatile is only supposed to be observable by asynchronous signal handlers or special kind of memory (which an implementation can assume is not used for automatic variables).

from abi-aa.

armask avatar armask commented on August 24, 2024

you can disagree with my interpretation, but you need to demonstrate it with an actual example where your interpretation and my interpretation causes different behaviour, to start a relevant discussion.

If one makes a claim, he needs to be able to prove it with a quote from the standard (it is the single source of truth about the C programming language). Common sense is not good enough, especially if it directly contradicts the standard :-)

AAPCS contains text that is not grounded in the ISO C11 standard and it should be removed (not put into footnote). If we all agree on that, let us simply do this.

on an arm platform volatile is only supposed to be observable by asynchronous signal handlers or special kind of memory (which an implementation can assume is not used for automatic variables)

If we are talking about C, we need to use its terminology. The standard says “Accesses to volatile objects […] is the observable behavior”. If you want to use “observable” in some other sense (I guess you do, because you say “observable by …”, which is not defined by ISO C11), please, define what it means.

By the way, in a Linux system on Arm nothing prevents using makecontext(3)/pthread_attr_setstack(3) with device-mapped memory as the stack (at least https://github.com/ARM-software/software-standards/blob/master/abi/aapcs64/aapcs64.rst#the-stack does not say anything about that) and blink a light when the memory is accessed, thus making access to a volatile automatic variable “observable by” the naked eye :-)

from abi-aa.

nsz-arm avatar nsz-arm commented on August 24, 2024

If one makes a claim, he needs to be able to prove it with a quote from the standard (it is the single source of truth about the C programming language). Common sense is not good enough, especially if it directly contradicts the standard :-)

well, a quote is not a proof, you must consider the standard as a whole. i think what confuses you is that the terms in your quotes don't mean what you think they mean, e.g. access in the abstract machine does not mean memory access on a real machine.

AAPCS contains text that is not grounded in the ISO C11 standard and it should be removed (not put into footnote). If we all agree on that, let us simply do this.

the text in the aapcs is unnecessary, but it is in alignment with iso c11 (other than side-effect-free infinite loops, as mentioned before, which have special semantics for volatile qualified objects).

If we are talking about C, we need to use its terminology. The standard says “Accesses to volatile objects […] is the observable behavior”. If you want to use “observable” in some other sense (I guess you do, because you say “observable by …”, which is not defined by ISO C11), please, define what it means.

the c language defines what is observable in the abstract machine, the aapcs can define what is observable on a particular machine or platform.

if something is specified to be observable in the abstract machine but actually is not observable on a real machine, then an implementation for that particular machine can take advantage of this.

in short: abstract machine "access" is not the same as "memory access" and abstract machine "observable" is not the same as machine "observable". as a consequence the abstract machine accesses can be optimized away by an implementation for a target that does not provide ways to observe those accesses.

By the way, in a Linux system on Arm nothing prevents using makecontext(3)/pthread_attr_setstack(3) with device-mapped memory as the stack (at least https://github.com/ARM-software/software-standards/blob/master/abi/aapcs64/aapcs64.rst#the-stack does not say anything about that) and blink a light when the memory is accessed, thus making access to a volatile automatic variable “observable by” the naked eye :-)

if device memory is used for stack the behaviour is undefined (not by iso c, but by the platform): it breaks the memory model that the implementation expects (not just volatile, but alignment requirements and memory ordering guarantees etc too).

from abi-aa.

armask avatar armask commented on August 24, 2024

the text in the aapcs is unnecessary, but it is in alignment with iso c11

The only thing I care about is removal of that offending text from our document. I have shown that it contradicts the standard and as a corroborating evidence all major compilers do not ignore “volatile” in the described case.

Have we decided to remove that text from the AAPCS or we need to continue the discussion?

a quote is not a proof, you must consider the standard as a whole. i think what confuses you is that the terms in your quotes don't mean what you think they mean, e.g. access in the abstract machine does not mean memory access on a real machine.

I never thought that—objects are not even required (in general) to be stored in memory. On the other hand, if an implementation uses a “memory location” to store a volatile object, then “access” to this object in the abstract machine does mean access to this “memory location” in implementation: “Accesses to volatile objects are evaluated strictly according to the rules of the abstract machine.”

the c language defines what is observable in the abstract machine

Please, use the terms correctly. There is no such thing as “observable in the abstract machine”, there is only “observable behavior [of the program]”.

the aapcs can define what is observable on a particular machine or platform.

The standard requires that a “conforming implementation” implements “observable behavior”, thus if we will ever speak about “observable behavior of platform”, that will be a superset of “observable behavior”.

Hypothetically, the AAPCS can define “observable behavior”, but it is irrelevant to the offending text we discuss, because that text does not use this term and the AAPCS does not use “observable” at all (unless my search is broken).

if something is specified to be observable in the abstract machine but actually is not observable on a real machine, then an implementation for that particular machine can take advantage of this.

If you insist on using “observable on a real machine”, you must define it. In reality there is only “observable behavior [of the program]” and what the implementation takes advantage of is that “observable behavior [of the program]” is a tiny fraction of the abstract machine behavior.

from abi-aa.

nsz-arm avatar nsz-arm commented on August 24, 2024

the text in the aapcs is unnecessary, but it is in alignment with iso c11

The only thing I care about is removal of that offending text from our document. I have shown that it contradicts the standard and as a corroborating evidence all major compilers do not ignore “volatile” in the described case.

i tried to explain why it does not contradict the standard, but i'm not the c language committee so i cannot give an official interpretation for the questions you raised, you will have to take those to another forum if you are still not convinced.

we know that there are existing implementations that ignore volatile on locals and those that don't, they are standard conform and arm abi conform as far as i know. (there is at least one c implementation that ignores volatile completely but that's for a more special environment not related to aapcs.)

i don't plan to discuss this here further, the text will be probably moved to a footnote or removed, but not because it's in conflict with the standard, but because it allows something the standard already allows without the aapcs specifying it explicitly.

from abi-aa.

stuij avatar stuij commented on August 24, 2024

Hi armask,

Thanks for your input. As this issue also affects the AArch32 AAPCS, which isn't public yet, we've created a private ticket, but this ticket will stay active as well.

The ticket mirrors what others have stated in this thread: we agree that we should turn the text into a footnote or remove it. This sentiment is also shared by others in the Arm compiler teams.

from abi-aa.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.