mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-07 10:02:22 +00:00
Make dereferencing a void* a hard-error instead of warn-as-error
Clang 16 changed to consider dereferencing a void* to be a warning-as-error, plus made this an error in SFINAE contexts, since this resulted in incorrect template instantiation. When doing so, the Clang 16 documentation was updated to reflect that this was likely to change again to a non-disablable error in the next version. As there has been no response to changing from a warning to an error, I believe this is a non-controversial change. This patch changes this to be an Error, consistent with the standard and other compilers. This was discussed in this RFC: https://discourse.llvm.org/t/rfc-can-we-stop-the-extension-to-allow-dereferencing-void-in-c/65708 Differential Revision: https://reviews.llvm.org/D150875
This commit is contained in:
parent
2daf91dae3
commit
fca4e2add0
@ -60,6 +60,10 @@ C++ Specific Potentially Breaking Changes
|
||||
-----------------------------------------
|
||||
- Clang won't search for coroutine_traits in std::experimental namespace any more.
|
||||
Clang will only search for std::coroutine_traits for coroutines then.
|
||||
- Clang no longer allows dereferencing of a ``void *`` as an extension. Clang 16
|
||||
converted this to a default-error as ``-Wvoid-ptr-dereference``, as well as a
|
||||
SFINAE error. This flag is still valid however, as it disables the equivalent
|
||||
warning in C.
|
||||
|
||||
ABI Changes in This Version
|
||||
---------------------------
|
||||
|
@ -6981,9 +6981,8 @@ def err_typecheck_indirection_requires_pointer : Error<
|
||||
def ext_typecheck_indirection_through_void_pointer : ExtWarn<
|
||||
"ISO C does not allow indirection on operand of type %0">,
|
||||
InGroup<VoidPointerDeref>;
|
||||
def ext_typecheck_indirection_through_void_pointer_cpp
|
||||
: ExtWarn<"ISO C++ does not allow indirection on operand of type %0">,
|
||||
InGroup<VoidPointerDeref>, DefaultError, SFINAEFailure;
|
||||
def err_typecheck_indirection_through_void_pointer_cpp
|
||||
: Error<"indirection not permitted on operand of type %0">;
|
||||
def warn_indirection_through_null : Warning<
|
||||
"indirection of non-volatile null pointer will be deleted, not trap">,
|
||||
InGroup<NullDereference>;
|
||||
|
@ -14957,7 +14957,7 @@ static QualType CheckIndirectionOperand(Sema &S, Expr *Op, ExprValueKind &VK,
|
||||
// be a pointer to an object type, or a pointer to a function type
|
||||
LangOptions LO = S.getLangOpts();
|
||||
if (LO.CPlusPlus)
|
||||
S.Diag(OpLoc, diag::ext_typecheck_indirection_through_void_pointer_cpp)
|
||||
S.Diag(OpLoc, diag::err_typecheck_indirection_through_void_pointer_cpp)
|
||||
<< OpTy << Op->getSourceRange();
|
||||
else if (!(LO.C99 && IsAfterAmp) && !S.isUnevaluatedContext())
|
||||
S.Diag(OpLoc, diag::ext_typecheck_indirection_through_void_pointer)
|
||||
|
@ -8,7 +8,7 @@ struct X0 {
|
||||
|
||||
template<typename T, typename U>
|
||||
void X0<T, U>::f(T *t, const U &u) {
|
||||
*t = u; // expected-error{{indirection on operand of type 'void *'}} expected-error{{not assignable}}
|
||||
*t = u; // expected-error{{indirection not permitted on operand of type 'void *'}} expected-error{{not assignable}}
|
||||
}
|
||||
|
||||
void test_f(X0<float, int> xfi, X0<void, int> xvi, float *fp, void *vp, int i) {
|
||||
|
@ -35,7 +35,7 @@ void f() {
|
||||
extern T f3();
|
||||
__typeof(*T()) f4(); // expected-warning {{empty parentheses interpreted as a function declaration}} expected-note {{replace parentheses with an initializer}}
|
||||
typedef void *V;
|
||||
__typeof(*V()) f5(); // expected-error {{ISO C++ does not allow indirection on operand of type 'V' (aka 'void *')}}
|
||||
__typeof(*V()) f5(); // expected-error {{indirection not permitted on operand of type 'V' (aka 'void *')}}
|
||||
T multi1,
|
||||
multi2(); // expected-warning {{empty parentheses interpreted as a function declaration}} expected-note {{replace parentheses with an initializer}}
|
||||
T(d)[5]; // expected-error {{redefinition of 'd'}}
|
||||
|
@ -1,8 +1,7 @@
|
||||
// RUN: %clang_cc1 -fsyntax-only -verify=enabled,sfinae -std=c++20 %s
|
||||
// RUN: %clang_cc1 -fsyntax-only -verify=sfinae -std=c++20 -Wno-void-ptr-dereference %s
|
||||
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
|
||||
|
||||
void f(void* p) {
|
||||
(void)*p; // enabled-error{{ISO C++ does not allow indirection on operand of type 'void *'}}
|
||||
(void)*p; // expected-error{{indirection not permitted on operand of type 'void *'}}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
@ -11,6 +10,6 @@ concept deref = requires (T& t) {
|
||||
};
|
||||
|
||||
static_assert(deref<void*>);
|
||||
// sfinae-error@-1{{static assertion failed}}
|
||||
// sfinae-note@-2{{because 'void *' does not satisfy 'deref'}}
|
||||
// sfinae-note@#FAILED_REQ{{because '*t' would be invalid: ISO C++ does not allow indirection on operand of type 'void *'}}
|
||||
// expected-error@-1{{static assertion failed}}
|
||||
// expected-note@-2{{because 'void *' does not satisfy 'deref'}}
|
||||
// expected-note@#FAILED_REQ{{because '*t' would be invalid: indirection not permitted on operand of type 'void *'}}
|
||||
|
@ -214,11 +214,11 @@ void dereference_reinterpret_cast() {
|
||||
(void)*reinterpret_cast<float*>(v_ptr);
|
||||
|
||||
// Casting to void pointer
|
||||
(void)*reinterpret_cast<void*>(&a); // expected-error {{ISO C++ does not allow}}
|
||||
(void)*reinterpret_cast<void*>(&b); // expected-error {{ISO C++ does not allow}}
|
||||
(void)*reinterpret_cast<void*>(&l); // expected-error {{ISO C++ does not allow}}
|
||||
(void)*reinterpret_cast<void*>(&d); // expected-error {{ISO C++ does not allow}}
|
||||
(void)*reinterpret_cast<void*>(&f); // expected-error {{ISO C++ does not allow}}
|
||||
(void)*reinterpret_cast<void*>(&a); // expected-error {{indirection not permitted on operand of type 'void *'}}
|
||||
(void)*reinterpret_cast<void*>(&b); // expected-error {{indirection not permitted on operand of type 'void *'}}
|
||||
(void)*reinterpret_cast<void*>(&l); // expected-error {{indirection not permitted on operand of type 'void *'}}
|
||||
(void)*reinterpret_cast<void*>(&d); // expected-error {{indirection not permitted on operand of type 'void *'}}
|
||||
(void)*reinterpret_cast<void*>(&f); // expected-error {{indirection not permitted on operand of type 'void *'}}
|
||||
}
|
||||
|
||||
void reinterpret_cast_allowlist () {
|
||||
|
Loading…
x
Reference in New Issue
Block a user