In this testcase, A is for some reason considered volatile, so the first write is not removed:
procedure Vol is A : Integer; pragma Import (C, A); begin A := 1; A := 2; end; $ gcc -S -O2 vol.adb $ grep mov vol.s movl %esp, %ebp movl $1, a movl $2, a This is because of the following in ada/decl.c: /* Make a volatile version of this object's type if we are to make the object volatile. Note that 13.3(19) says that we should treat other types of objects as volatile as well. */ if ((Treat_As_Volatile (gnat_entity) || Is_Exported (gnat_entity) || Is_Imported (gnat_entity)) && !TYPE_VOLATILE (gnu_type)) gnu_type = build_qualified_type (gnu_type, (TYPE_QUALS (gnu_type) | TYPE_QUAL_VOLATILE)); What does 13.3(19) actually say? "If the Address of an object is specified, or it is imported or exported, then the implementation should not perform optimizations based on assumptions of no aliases." So it looks like volatile is a hack to get the effect of "no aliasing". Surely this can be done right nowadays? -- Summary: Imported variables marked "volatile" in Ada Product: gcc Version: 4.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: ada AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: baldrick at gcc dot gnu dot org GCC build triplet: i686-pc-linux-gnu GCC host triplet: i686-pc-linux-gnu GCC target triplet: i686-pc-linux-gnu http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31877