[m-rev.] diff: avoid a C# error with bitwise complement

Julien Fischer jfischer at opturion.com
Thu Mar 24 21:33:42 AEDT 2022


This one is for the release branch as well.

----------------------------------

Avoid a C# error with bitwise complement.

C# will promote the bitwise complement of byte or ushort into an int and then
sometimes complains about possible information loss when we cast it back to the
original type.  (Specifically, it complains when the operand is a literal value
whose complement is a negative int.)  This is causing compilation of the
standard library to fail with -O5 --intermod-opt.  The fix is to wrap the
bitwise complement in an unchecked context.

compiler/mlds_to_cs_data.m:
     As above.

Julien.

diff --git a/compiler/mlds_to_cs_data.m b/compiler/mlds_to_cs_data.m
index b3c1277..ce43e76 100644
--- a/compiler/mlds_to_cs_data.m
+++ b/compiler/mlds_to_cs_data.m
@@ -2,7 +2,7 @@
  % vim: ft=mercury ts=4 sw=4 et
  %---------------------------------------------------------------------------%
  % Copyright (C) 2010-2012 The University of Melbourne.
-% Copyright (C) 2013-2018, 2020 The Mercury team.
+% Copyright (C) 2013-2018, 2020-2022 The Mercury team.
  % This file may only be copied under the terms of the GNU General
  % Public License - see the file COPYING in the Mercury distribution.
  %---------------------------------------------------------------------------%
@@ -404,21 +404,36 @@ output_unop_for_csharp(Info, Stream, UnaryOp, Expr, !IO) :-
              UnaryOp = bitwise_complement(int_type_int8),
              CastStr = "(sbyte) "
          ;
-            UnaryOp = bitwise_complement(int_type_uint8),
-            CastStr = "(byte) "
-        ;
              UnaryOp = bitwise_complement(int_type_int16),
              CastStr = "(short) "
+        ),
+        UnaryOpStr = "~",
+        io.write_string(Stream, CastStr, !IO),
+        io.write_string(Stream, UnaryOpStr, !IO),
+        io.write_string(Stream, "(", !IO),
+        output_rval_for_csharp(Info, Expr, Stream, !IO),
+        io.write_string(Stream, ")", !IO)
+    ;
+        % The result of the bitwise complement of byte or ushort in C# will be
+        % promoted to an int. Casting this back to the original type may result
+        % in a CS0221 error from the C# compiler due to the possible
+        % information loss involved in such a cast. We need to wrap the whole
+        % expression in an unchecked context in order to prevent the C#
+        % compiler from treating it as an error.
+        (
+            UnaryOp = bitwise_complement(int_type_uint8),
+            CastStr = "(byte) "
          ;
              UnaryOp = bitwise_complement(int_type_uint16),
              CastStr = "(ushort) "
          ),
          UnaryOpStr = "~",
+        io.write_string(Stream, "unchecked (", !IO),
          io.write_string(Stream, CastStr, !IO),
          io.write_string(Stream, UnaryOpStr, !IO),
          io.write_string(Stream, "(", !IO),
          output_rval_for_csharp(Info, Expr, Stream, !IO),
-        io.write_string(Stream, ")", !IO)
+        io.write_string(Stream, "))", !IO)
      ;
          ( UnaryOp = dword_float_get_word0
          ; UnaryOp = dword_float_get_word1


More information about the reviews mailing list