diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp index 6ac6201843476b..4de5b41c5f35ac 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->isDependentType() || DestTy->isDependentType()) { + 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..bfb808773b9004 100644 --- a/clang/test/SemaCXX/reinterpret-cast.cpp +++ b/clang/test/SemaCXX/reinterpret-cast.cpp @@ -302,3 +302,77 @@ void reinterpret_cast_allowlist () { (void)reinterpret_cast(b); (void)*reinterpret_cast(&b); } + +namespace templated { +template +void cast_uninstantiated() { + const UATYPE* data; + (void)*reinterpret_cast(data); // no warning +} + + +template +void cast_instantiated_badly() { + const UATYPE* data; + (void)*reinterpret_cast(data); // expected-warning {{dereference of type 'const int *' that was reinterpret_cast from type 'const float *' has undefined behavior}} +} + +template +void cast_instantiated_well() { + const UATYPE* data; + (void)*reinterpret_cast(data); // no warning +} + +template +void cast_one_tmpl_arg_uninstantiated() { + const int* data; + (void)*reinterpret_cast(data); // no warning +} + +template +void cast_one_tmpl_arg_instantiated_badly() { + const float* data; + (void)*reinterpret_cast(data); // expected-warning {{dereference of type 'const int *' that was reinterpret_cast from type 'const float *' has undefined behavior}} +} + +template +void cast_one_tmpl_arg_instantiated_well() { + const float* data; + (void)*reinterpret_cast(data); // no warning +} + +template +void cast_nontype_template_true_positive_noninstantiated() { + const float *data; + const int arr[size]; + (void)*reinterpret_cast(data); // expected-warning {{dereference of type 'const int *' that was reinterpret_cast from type 'const float *' has undefined behavior}} +} + +template +void cast_nontype_template_true_negative_noninstantiated() { + const int data[size]; + (void)*reinterpret_cast(data); // no warning +} + +void top() { + cast_instantiated_badly(); + // expected-note@-1 {{in instantiation of function template specialization 'templated::cast_instantiated_badly' requested here}} + cast_instantiated_well(); + cast_one_tmpl_arg_instantiated_badly(); + // expected-note@-1 {{in instantiation of function template specialization 'templated::cast_one_tmpl_arg_instantiated_badly' requested here}} + cast_one_tmpl_arg_instantiated_well(); +} + +template +void cast_template_dependent_type_noninstantiated(T** x) +{ + (void)*reinterpret_cast(x); +} + +template +void cast_template_dependent_member_type_noninstantiated(typename T::X x) +{ + (void)*reinterpret_cast(x); +} + +} // namespace templated