Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,8 @@ Improvements to Clang's diagnostics

- Don't emit bogus dangling diagnostics when ``[[gsl::Owner]]`` and `[[clang::lifetimebound]]` are used together (#GH108272).

- Don't emit bogus dignostic about an undefined behavior on ``reinterpret_cast<T>`` for non-instantiated template functions without sufficient knowledge whether it can actually lead to undefined behavior for ``T`` (#GH109430).

- The ``-Wreturn-stack-address`` warning now also warns about addresses of
local variables passed to function calls using the ``[[clang::musttail]]``
attribute.
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/Sema/SemaCast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2094,6 +2094,10 @@ void Sema::CheckCompatibleReinterpretCast(QualType SrcType, QualType DestType,
}
}

if (SrcTy->isDependentType() || DestTy->isDependentType()) {
return;
}

Diag(Range.getBegin(), DiagID) << SrcType << DestType << Range;
}

Expand Down
74 changes: 74 additions & 0 deletions clang/test/SemaCXX/reinterpret-cast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -302,3 +302,77 @@ 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>();
}

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
Loading