llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Arseniy Zaostrovnykh (necto) <details> <summary>Changes</summary> 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 --- Full diff: https://github.com/llvm/llvm-project/pull/109430.diff 2 Files Affected: - (modified) clang/lib/Sema/SemaCast.cpp (+4) - (modified) clang/test/SemaCXX/reinterpret-cast.cpp (+62) ``````````diff 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@-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@-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 `````````` </details> https://github.com/llvm/llvm-project/pull/109430 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits