[m-rev.] for review: fix bug #196: binary compatiblity checks in C grade don't work

Julien Fischer jfischer at opturion.com
Fri Jul 15 01:16:25 AEST 2016


Hi,

Is anyone intending to review this one?  In the absence of any comments
I'll commit it later today.

Julien.


On Thu, 7 Jul 2016, Julien Fischer wrote:

>
> 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