Mercury Bugs - mercury
View Issue Details
0000196mercuryBugpublic2011-04-13 23:102016-07-17 20:56
Reporterpbone 
Assigned Tojuliensf 
PrioritynormalSeverityminorReproducibilitysometimes
StatusresolvedResolutionfixed 
PlatformOSOS Version
Product Version 
Target VersionFixed in Version 
Summary0000196: Binary compatibility checks in C grades don't work.
DescriptionThe binary compatibility checks in runtime/mercury_goto.h don't work. I was able to modify the grade string and re-compile the runtime and link it against the standard library and object files that had been generated against an older version of this header file.

I suspect that the static variable in generated C files that refers to the grade variable is being optimized a way and therefore the linker happily links the mis-matched objects.
TagsNo tags attached.
Attached Files

Notes
(0000327)
juliensf   
2011-04-13 23:25   
Does the variable appear amongst the list of exported symbols?

What version of gcc are you using? (Recent ones do perform some LTO, so maybe
that's the problem?)
(0000892)
juliensf   
2016-07-07 19:56   
The problem is that the static variable MR_grade that we emit at the end of every generated .c file is being optimised away (since it is not referenced by anything else). GCC and clang seem quite happy to do this even if the variable is also declared to be volatile. The will however retain the variable if it is declared with
the variable attribute __attribute__((used)). For other C compilers I'm not yet sure what to do (or even if this is a problem).
(0000893)
zs   
2016-07-07 20:27   
We could generate an exported function that returns the value of MR_grade.
Since it could be called from somewhere else, the compiler wouldn't be able
to optimize away the reference. This should be more portable than __attribute__.
(0000894)
juliensf   
2016-07-07 20:48   
We can hide __attribute__ behind a macro, just as we already do with other such attributes, e.g.

  #if defined(MR_GNUC) || defined(MR_CLANG)
      #define MR_CONSIDER_USED __attribute__((used))
  #else
      #define MR_CONSIDER_USED volatile /* .. and hope for the best! */
  #endif

I've implemented this and tested it with clang. (I'm not even sure that this is an issue with
MSVC; I'll take a look tomorrow when I have access to a machine with that compiler installed.)
Given that C compilers used with Mercury are nearly always GCC or clang I think this is probably
good enough.
(0000898)
juliensf   
2016-07-17 20:56   
Fix in commit 10c210d.

Issue History
2011-04-13 23:10pboneNew Issue
2011-04-13 23:25juliensfNote Added: 0000327
2016-07-07 19:56juliensfNote Added: 0000892
2016-07-07 19:56juliensfAssigned To => juliensf
2016-07-07 19:56juliensfStatusnew => assigned
2016-07-07 20:27zsNote Added: 0000893
2016-07-07 20:48juliensfNote Added: 0000894
2016-07-17 20:56juliensfNote Added: 0000898
2016-07-17 20:56juliensfStatusassigned => resolved
2016-07-17 20:56juliensfResolutionopen => fixed