[clang] [clang] Fix false warning on reinterpret_casting unknown template type (PR #109430)

Arseniy Zaostrovnykh via cfe-commits cfe-commits at lists.llvm.org
Mon Sep 23 00:34:13 PDT 2024


https://github.com/necto updated https://github.com/llvm/llvm-project/pull/109430

>From 3533863fd58f54d2d5570b4f593d2635e1e11aa8 Mon Sep 17 00:00:00 2001
From: Arseniy Zaostrovnykh <necto.ne at gmail.com>
Date: Fri, 20 Sep 2024 09:16:17 +0200
Subject: [PATCH 1/2] [clang] Fix false warning on reinterpret_casting unknown
 template type

After 1595988ee6f9732e7ea79928af8a470ad5ef7dbe
diag::warn_undefined_reinterpret_cast started raising on
non-instantiated template functions without sufficient knowledge whether
the reinterpret_cast is indeed UB.

This change fixes it.

CPP-5704
---
 clang/lib/Sema/SemaCast.cpp             |  4 ++
 clang/test/SemaCXX/reinterpret-cast.cpp | 62 +++++++++++++++++++++++++
 2 files changed, 66 insertions(+)

diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp
index 6ac6201843476b..dd65b301343e6c 100644
--- a/clang/lib/Sema/SemaCast.cpp
+++ b/clang/lib/Sema/SemaCast.cpp
@@ -2092,6 +2092,10 @@ void Sema::CheckCompatibleReinterpretCast(QualType SrcType, QualType DestType,
     }
   }
 
+  if (SrcTy->isTemplateTypeParmType() || DestTy->isTemplateTypeParmType()) {
+    return;
+  }
+
   Diag(Range.getBegin(), DiagID) << SrcType << DestType << Range;
 }
 
diff --git a/clang/test/SemaCXX/reinterpret-cast.cpp b/clang/test/SemaCXX/reinterpret-cast.cpp
index 45332fd15b5d4e..773aa8ee0e7894 100644
--- a/clang/test/SemaCXX/reinterpret-cast.cpp
+++ b/clang/test/SemaCXX/reinterpret-cast.cpp
@@ -302,3 +302,65 @@ void reinterpret_cast_allowlist () {
   (void)reinterpret_cast<unsigned char&>(b);
   (void)*reinterpret_cast<unsigned char*>(&b);
 }
+
+namespace templated {
+template <typename TARGETTYPE, typename UATYPE>
+void cast_uninstantiated() {
+  const UATYPE* data;
+  (void)*reinterpret_cast<const TARGETTYPE*>(data); // no warning
+}
+
+
+template <typename TARGETTYPE, typename UATYPE>
+void cast_instantiated_badly() {
+  const UATYPE* data;
+  (void)*reinterpret_cast<const TARGETTYPE*>(data); // expected-warning {{dereference of type 'const int *' that was reinterpret_cast from type 'const float *' has undefined behavior}}
+}
+
+template <typename TARGETTYPE, typename UATYPE>
+void cast_instantiated_well() {
+  const UATYPE* data;
+  (void)*reinterpret_cast<const TARGETTYPE*>(data); // no warning
+}
+
+template <typename TARGETTYPE>
+void cast_one_tmpl_arg_uninstantiated() {
+  const int* data;
+  (void)*reinterpret_cast<const TARGETTYPE*>(data); // no warning
+}
+
+template <typename TARGETTYPE>
+void cast_one_tmpl_arg_instantiated_badly() {
+  const float* data;
+  (void)*reinterpret_cast<const TARGETTYPE*>(data); // expected-warning {{dereference of type 'const int *' that was reinterpret_cast from type 'const float *' has undefined behavior}}
+}
+
+template <typename TARGETTYPE>
+void cast_one_tmpl_arg_instantiated_well() {
+  const float* data;
+  (void)*reinterpret_cast<const TARGETTYPE*>(data); // no warning
+}
+
+template <int size>
+void cast_nontype_template_true_positive_noninstantiated() {
+  const float *data;
+  const int arr[size];
+  (void)*reinterpret_cast<const int*>(data); // expected-warning {{dereference of type 'const int *' that was reinterpret_cast from type 'const float *' has undefined behavior}}
+}
+
+template <int size>
+void cast_nontype_template_true_negative_noninstantiated() {
+  const int data[size];
+  (void)*reinterpret_cast<const int*>(data); // no warning
+}
+
+void top() {
+  cast_instantiated_badly<int, float>();
+  // expected-note at -1 {{in instantiation of function template specialization 'templated::cast_instantiated_badly<int, float>' requested here}}
+  cast_instantiated_well<int, int>();
+  cast_one_tmpl_arg_instantiated_badly<int>();
+  // expected-note at -1 {{in instantiation of function template specialization 'templated::cast_one_tmpl_arg_instantiated_badly<int>' requested here}}
+  cast_one_tmpl_arg_instantiated_well<float>();
+}
+
+} // namespace templated

>From 541e0af03998c4bd96f2ff0e51f4306b5db5af14 Mon Sep 17 00:00:00 2001
From: Arseniy Zaostrovnykh <necto.ne at gmail.com>
Date: Mon, 23 Sep 2024 09:33:43 +0200
Subject: [PATCH 2/2] Apply review suggestion: filter out all dependent types

not just direct type parameters
---
 clang/lib/Sema/SemaCast.cpp             |  2 +-
 clang/test/SemaCXX/reinterpret-cast.cpp | 12 ++++++++++++
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp
index dd65b301343e6c..4de5b41c5f35ac 100644
--- a/clang/lib/Sema/SemaCast.cpp
+++ b/clang/lib/Sema/SemaCast.cpp
@@ -2092,7 +2092,7 @@ void Sema::CheckCompatibleReinterpretCast(QualType SrcType, QualType DestType,
     }
   }
 
-  if (SrcTy->isTemplateTypeParmType() || DestTy->isTemplateTypeParmType()) {
+  if (SrcTy->isDependentType() || DestTy->isDependentType()) {
     return;
   }
 
diff --git a/clang/test/SemaCXX/reinterpret-cast.cpp b/clang/test/SemaCXX/reinterpret-cast.cpp
index 773aa8ee0e7894..bfb808773b9004 100644
--- a/clang/test/SemaCXX/reinterpret-cast.cpp
+++ b/clang/test/SemaCXX/reinterpret-cast.cpp
@@ -363,4 +363,16 @@ void top() {
   cast_one_tmpl_arg_instantiated_well<float>();
 }
 
+template<typename T, typename U>
+void cast_template_dependent_type_noninstantiated(T** x)
+{
+    (void)*reinterpret_cast<U**>(x);
+}
+
+template<typename T, typename U>
+void cast_template_dependent_member_type_noninstantiated(typename T::X x)
+{
+    (void)*reinterpret_cast<typename U::Y>(x);
+}
+
 } // namespace templated



More information about the cfe-commits mailing list