[clang] [Clang] enhance diagnostic message for __builtin_bit_cast size mismatch (PR #115940)

Oleksandr T. via cfe-commits cfe-commits at lists.llvm.org
Wed Nov 13 05:53:28 PST 2024


https://github.com/a-tarasyuk updated https://github.com/llvm/llvm-project/pull/115940

>From 2132ccb175f1eb37a4b4e60c8ee8ade90ba5bb18 Mon Sep 17 00:00:00 2001
From: Oleksandr T <oleksandr.tarasiuk at outlook.com>
Date: Tue, 12 Nov 2024 23:09:06 +0200
Subject: [PATCH 1/3] [Clang] enhance diagnostic message for __builtin_bit_cast
 size mismatch

---
 clang/docs/ReleaseNotes.rst                       | 2 ++
 clang/include/clang/Basic/DiagnosticSemaKinds.td  | 3 ++-
 clang/lib/Sema/SemaCast.cpp                       | 3 ++-
 clang/test/AST/ByteCode/builtin-bit-cast.cpp      | 4 ++--
 clang/test/SemaCXX/builtin-bit-cast.cpp           | 2 +-
 clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp | 2 +-
 6 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index ffed972ed120d0..d401dbfaf23aaa 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -528,6 +528,8 @@ Improvements to Clang's diagnostics
 
 - Clang now diagnoses ``[[deprecated]]`` attribute usage on local variables (#GH90073).
 
+- Improved diagnostic message for __builtin_bit_cast size mismatch (#GH115870).
+
 Improvements to Clang's time-trace
 ----------------------------------
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 509d45c0867590..9bf3196c4f7cd3 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -12354,7 +12354,8 @@ def err_preserve_enum_value_not_const: Error<
 def err_bit_cast_non_trivially_copyable : Error<
   "__builtin_bit_cast %select{source|destination}0 type must be trivially copyable">;
 def err_bit_cast_type_size_mismatch : Error<
-  "__builtin_bit_cast source size does not equal destination size (%0 vs %1)">;
+  "__builtin_bit_cast source type %0 size (%1 %plural{1:byte|:bytes}1) "
+  "does not match destination type %2 size (%3 %plural{1:byte|:bytes}3)">;
 
 // SYCL-specific diagnostics
 def warn_sycl_kernel_num_of_template_params : Warning<
diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp
index 6ac6201843476b..211e4dbfe682e7 100644
--- a/clang/lib/Sema/SemaCast.cpp
+++ b/clang/lib/Sema/SemaCast.cpp
@@ -3283,7 +3283,8 @@ void CastOperation::CheckBuiltinBitCast() {
   CharUnits SourceSize = Self.Context.getTypeSizeInChars(SrcType);
   if (DestSize != SourceSize) {
     Self.Diag(OpRange.getBegin(), diag::err_bit_cast_type_size_mismatch)
-        << (int)SourceSize.getQuantity() << (int)DestSize.getQuantity();
+      << SrcType << (int)SourceSize.getQuantity()
+      << DestType << (int)DestSize.getQuantity();
     SrcExpr = ExprError();
     return;
   }
diff --git a/clang/test/AST/ByteCode/builtin-bit-cast.cpp b/clang/test/AST/ByteCode/builtin-bit-cast.cpp
index 7d1fcbda10965f..62f5e9eff4b1fd 100644
--- a/clang/test/AST/ByteCode/builtin-bit-cast.cpp
+++ b/clang/test/AST/ByteCode/builtin-bit-cast.cpp
@@ -496,7 +496,7 @@ typedef bool bool32 __attribute__((ext_vector_type(32)));
 typedef bool bool128 __attribute__((ext_vector_type(128)));
 
 static_assert(bit_cast<unsigned char>(bool8{1,0,1,0,1,0,1,0}) == (LITTLE_END ? 0x55 : 0xAA), "");
-constexpr bool8 b8 = __builtin_bit_cast(bool8, 0x55); // both-error {{__builtin_bit_cast source size does not equal destination size (4 vs 1)}}
+constexpr bool8 b8 = __builtin_bit_cast(bool8, 0x55); // both-error {{__builtin_bit_cast source type 'int' size (4 bytes) does not match destination type 'bool8' (vector of 8 'bool' values) size (1 byte)}}
 #if 0
 static_assert(check_round_trip<bool8>(static_cast<unsigned char>(0)), "");
 static_assert(check_round_trip<bool8>(static_cast<unsigned char>(1)), "");
@@ -535,5 +535,5 @@ namespace test_complex {
   static_assert(TF.A == 1.0f && TF.B == 2.0f);
 
   constexpr double D = __builtin_bit_cast(double, test_float_complex);
-  constexpr int M = __builtin_bit_cast(int, test_int_complex); // both-error {{__builtin_bit_cast source size does not equal destination size}}
+  constexpr int M = __builtin_bit_cast(int, test_int_complex); // both-error {{__builtin_bit_cast source type 'const _Complex unsigned int' size (8 bytes) does not match destination type 'int' size (4 bytes)}}
 }
diff --git a/clang/test/SemaCXX/builtin-bit-cast.cpp b/clang/test/SemaCXX/builtin-bit-cast.cpp
index 87919d9d9d2865..cce700dffb6cdf 100644
--- a/clang/test/SemaCXX/builtin-bit-cast.cpp
+++ b/clang/test/SemaCXX/builtin-bit-cast.cpp
@@ -24,7 +24,7 @@ void test1() {
 
 void test2() {
   constexpr int i = 0;
-  // expected-error at +1{{__builtin_bit_cast source size does not equal destination size (4 vs 1)}}
+  // expected-error at +1{{__builtin_bit_cast source type 'const int' size (4 bytes) does not match destination type 'char' size (1 byte)}}
   constexpr char c = __builtin_bit_cast(char, i);
 }
 
diff --git a/clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp b/clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp
index 5ddb77b35ff145..2e26c31d3613de 100644
--- a/clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp
+++ b/clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp
@@ -525,5 +525,5 @@ namespace test_complex {
   static_assert(TF.A == 1.0f && TF.B == 2.0f);
 
   constexpr double D = __builtin_bit_cast(double, test_float_complex);
-  constexpr int M = __builtin_bit_cast(int, test_int_complex); // expected-error {{__builtin_bit_cast source size does not equal destination size}}
+  constexpr int M = __builtin_bit_cast(int, test_int_complex); // expected-error {{__builtin_bit_cast source type 'const _Complex unsigned int' size (8 bytes) does not match destination type 'int' size (4 bytes)}}
 }

>From 0c6e54b63dfee5aba53492045f94239086634479 Mon Sep 17 00:00:00 2001
From: Oleksandr T <oleksandr.tarasiuk at outlook.com>
Date: Tue, 12 Nov 2024 23:14:47 +0200
Subject: [PATCH 2/3] fix formatting

---
 clang/lib/Sema/SemaCast.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp
index 211e4dbfe682e7..fea7a15c314bdf 100644
--- a/clang/lib/Sema/SemaCast.cpp
+++ b/clang/lib/Sema/SemaCast.cpp
@@ -3283,8 +3283,8 @@ void CastOperation::CheckBuiltinBitCast() {
   CharUnits SourceSize = Self.Context.getTypeSizeInChars(SrcType);
   if (DestSize != SourceSize) {
     Self.Diag(OpRange.getBegin(), diag::err_bit_cast_type_size_mismatch)
-      << SrcType << (int)SourceSize.getQuantity()
-      << DestType << (int)DestSize.getQuantity();
+        << SrcType << (int)SourceSize.getQuantity() << DestType
+        << (int)DestSize.getQuantity();
     SrcExpr = ExprError();
     return;
   }

>From 33e7f91a24a48cd38c973d971efaf1f6395b755f Mon Sep 17 00:00:00 2001
From: Oleksandr T <oleksandr.tarasiuk at outlook.com>
Date: Wed, 13 Nov 2024 15:53:11 +0200
Subject: [PATCH 3/3] update diagnostic message

---
 clang/include/clang/Basic/DiagnosticSemaKinds.td  | 3 +--
 clang/lib/Sema/SemaCast.cpp                       | 2 +-
 clang/test/AST/ByteCode/builtin-bit-cast.cpp      | 4 ++--
 clang/test/SemaCXX/builtin-bit-cast.cpp           | 2 +-
 clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp | 2 +-
 5 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 9bf3196c4f7cd3..200dc8bd238357 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -12354,8 +12354,7 @@ def err_preserve_enum_value_not_const: Error<
 def err_bit_cast_non_trivially_copyable : Error<
   "__builtin_bit_cast %select{source|destination}0 type must be trivially copyable">;
 def err_bit_cast_type_size_mismatch : Error<
-  "__builtin_bit_cast source type %0 size (%1 %plural{1:byte|:bytes}1) "
-  "does not match destination type %2 size (%3 %plural{1:byte|:bytes}3)">;
+  "size of '__builtin_bit_cast' source type %0 does not match destination type %1 (%2 vs %3 bytes)">;
 
 // SYCL-specific diagnostics
 def warn_sycl_kernel_num_of_template_params : Warning<
diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp
index fea7a15c314bdf..3eb013e3612d1c 100644
--- a/clang/lib/Sema/SemaCast.cpp
+++ b/clang/lib/Sema/SemaCast.cpp
@@ -3283,7 +3283,7 @@ void CastOperation::CheckBuiltinBitCast() {
   CharUnits SourceSize = Self.Context.getTypeSizeInChars(SrcType);
   if (DestSize != SourceSize) {
     Self.Diag(OpRange.getBegin(), diag::err_bit_cast_type_size_mismatch)
-        << SrcType << (int)SourceSize.getQuantity() << DestType
+        << SrcType << DestType << (int)SourceSize.getQuantity()
         << (int)DestSize.getQuantity();
     SrcExpr = ExprError();
     return;
diff --git a/clang/test/AST/ByteCode/builtin-bit-cast.cpp b/clang/test/AST/ByteCode/builtin-bit-cast.cpp
index 62f5e9eff4b1fd..60e8c3a615c5e6 100644
--- a/clang/test/AST/ByteCode/builtin-bit-cast.cpp
+++ b/clang/test/AST/ByteCode/builtin-bit-cast.cpp
@@ -496,7 +496,7 @@ typedef bool bool32 __attribute__((ext_vector_type(32)));
 typedef bool bool128 __attribute__((ext_vector_type(128)));
 
 static_assert(bit_cast<unsigned char>(bool8{1,0,1,0,1,0,1,0}) == (LITTLE_END ? 0x55 : 0xAA), "");
-constexpr bool8 b8 = __builtin_bit_cast(bool8, 0x55); // both-error {{__builtin_bit_cast source type 'int' size (4 bytes) does not match destination type 'bool8' (vector of 8 'bool' values) size (1 byte)}}
+constexpr bool8 b8 = __builtin_bit_cast(bool8, 0x55); // both-error {{'__builtin_bit_cast' source type 'int' does not match destination type 'bool8' (vector of 8 'bool' values) (4 vs 1 bytes)}}
 #if 0
 static_assert(check_round_trip<bool8>(static_cast<unsigned char>(0)), "");
 static_assert(check_round_trip<bool8>(static_cast<unsigned char>(1)), "");
@@ -535,5 +535,5 @@ namespace test_complex {
   static_assert(TF.A == 1.0f && TF.B == 2.0f);
 
   constexpr double D = __builtin_bit_cast(double, test_float_complex);
-  constexpr int M = __builtin_bit_cast(int, test_int_complex); // both-error {{__builtin_bit_cast source type 'const _Complex unsigned int' size (8 bytes) does not match destination type 'int' size (4 bytes)}}
+  constexpr int M = __builtin_bit_cast(int, test_int_complex); // both-error {{size of '__builtin_bit_cast' source type 'const _Complex unsigned int' does not match destination type 'int' (8 vs 4 bytes)}}
 }
diff --git a/clang/test/SemaCXX/builtin-bit-cast.cpp b/clang/test/SemaCXX/builtin-bit-cast.cpp
index cce700dffb6cdf..d7f24c7939b558 100644
--- a/clang/test/SemaCXX/builtin-bit-cast.cpp
+++ b/clang/test/SemaCXX/builtin-bit-cast.cpp
@@ -24,7 +24,7 @@ void test1() {
 
 void test2() {
   constexpr int i = 0;
-  // expected-error at +1{{__builtin_bit_cast source type 'const int' size (4 bytes) does not match destination type 'char' size (1 byte)}}
+  // expected-error at +1{{size of '__builtin_bit_cast' source type 'const int' does not match destination type 'char' (4 vs 1 bytes)}}
   constexpr char c = __builtin_bit_cast(char, i);
 }
 
diff --git a/clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp b/clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp
index 2e26c31d3613de..425447c5e604e9 100644
--- a/clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp
+++ b/clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp
@@ -525,5 +525,5 @@ namespace test_complex {
   static_assert(TF.A == 1.0f && TF.B == 2.0f);
 
   constexpr double D = __builtin_bit_cast(double, test_float_complex);
-  constexpr int M = __builtin_bit_cast(int, test_int_complex); // expected-error {{__builtin_bit_cast source type 'const _Complex unsigned int' size (8 bytes) does not match destination type 'int' size (4 bytes)}}
+  constexpr int M = __builtin_bit_cast(int, test_int_complex); // expected-error {{size of '__builtin_bit_cast' source type 'const _Complex unsigned int' does not match destination type 'int' (8 vs 4 bytes)}}
 }



More information about the cfe-commits mailing list