[m-rev.] for review: fix bug #196: binary compatiblity checks in C grade don't work
Julien Fischer
jfischer at opturion.com
Thu Jul 7 22:34:36 AEST 2016
For review by anyone.
I haven't had a chance to look at whether MSVC is affected by bug #196,
but will do so shortly. If anyone is using Mercury with a C compiler that
is not GCC, clang, or MSVC could they please take a look what whether
MR_grade is being optimised away as well.
--------------------------------------------
Fix bug #196: binary compatibility checks in C grades don't work.
These have been broken since 2011 because GCC and clang (at least) began
optimising away the MR_grade variable we emit at the end of each generated
.c file. For these C compilers attach an attribute that prevents them from
doing this; for other C compilers declare MR_grade to be volatile (although
that didn't prevent GCC or clang deleting MR_grade).
runtime/mercury_std.h:
Add a new macro MR_CONSIDER_USED, that expands to an attribute that
tells the C compiler not to optimise a way a static variable even
if it is unreferenced.
util/mkinit.c:
compiler/mlds_to_c.m:
compiler/llds_outfile.m:
Use the new macro in the definition of MR_grade.
Julien.
diff --git a/compiler/llds_out_file.m b/compiler/llds_out_file.m
index f437ce4..9b919ce 100644
--- a/compiler/llds_out_file.m
+++ b/compiler/llds_out_file.m
@@ -616,7 +616,7 @@ output_c_module_init_list(Info, ModuleName, AnnotatedModules, RttiDatas,
"/* ensure everything is compiled with the same grade */\n",
!IO),
io.write_string(
- "static const void *const MR_grade = &MR_GRADE_VAR;\n", !IO).
+ "static const void *const MR_CONSIDER_USED MR_grade = &MR_GRADE_VAR;\n", !IO).
:- pred module_defines_label_with_layout(llds_out_info::in,
annotated_c_module::in) is semidet.
diff --git a/compiler/mlds_to_c.m b/compiler/mlds_to_c.m
index eeb570c..bea8b28 100644
--- a/compiler/mlds_to_c.m
+++ b/compiler/mlds_to_c.m
@@ -679,7 +679,7 @@ mlds_output_grade_var(!IO) :-
"/* ensure everything is compiled with the same grade */\n",
!IO),
io.write_string(
- "static const void *const MR_grade = &MR_GRADE_VAR;\n",
+ "static const void *const MR_CONSIDER_USED MR_grade = &MR_GRADE_VAR;\n",
!IO).
% Get the foreign code for C.
diff --git a/runtime/mercury_std.h b/runtime/mercury_std.h
index d3f761a..b3baecb 100644
--- a/runtime/mercury_std.h
+++ b/runtime/mercury_std.h
@@ -220,6 +220,21 @@ typedef char MR_small_bool;
/*---------------------------------------------------------------------------*/
/*
+** A macro for declaring that a variable with static storage class must be
+** considered used even if it is not referenced. We use this to ensure that
+** the MR_grade variable emitted at the end of every generated .c file is
+** not optimised away.
+*/
+
+#if defined(MR_GNUC) || defined(MR_CLANG)
+ #define MR_CONSIDER_USED __attribute__((used))
+#else
+ #define MR_CONSIDER_USED volatile
+#endif
+
+/*---------------------------------------------------------------------------*/
+
+/*
** MR_CALL:
** A macro for specifying the calling convention to use
** for C functions generated by the MLDS back-end
diff --git a/util/mkinit.c b/util/mkinit.c
index 0e15a60..8be079c 100644
--- a/util/mkinit.c
+++ b/util/mkinit.c
@@ -621,7 +621,7 @@ static const char mercury_main_func[] =
static const char mercury_grade_var[] =
"/* ensure that everything gets compiled in the same grade */\n"
- "static const void *const MR_grade = &MR_GRADE_VAR;\n"
+ "static const void *const MR_CONSIDER_USED MR_grade = &MR_GRADE_VAR;\n"
"\n"
;
More information about the reviews
mailing list