erichkeane created this revision. erichkeane added a reviewer: clang-language-wg. Herald added a project: All. erichkeane requested review of this revision.
as Discussed: https://discourse.llvm.org/t/rfc-can-we-stop-the-extension-to-allow-dereferencing-void-in-c/65708 There is no good reason to allow this when the other compilers all reject this, and it messes with SFINAE/constraint checking. https://reviews.llvm.org/D135287 Files: clang/docs/ReleaseNotes.rst clang/include/clang/Basic/DiagnosticSemaKinds.td clang/lib/Sema/SemaExpr.cpp clang/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1inst.cpp clang/test/SemaCXX/disallow_void_deref.cpp clang/test/SemaCXX/reinterpret-cast.cpp
Index: clang/test/SemaCXX/reinterpret-cast.cpp =================================================================== --- clang/test/SemaCXX/reinterpret-cast.cpp +++ clang/test/SemaCXX/reinterpret-cast.cpp @@ -214,11 +214,11 @@ (void)*reinterpret_cast<float*>(v_ptr); // Casting to void pointer - (void)*reinterpret_cast<void*>(&a); // expected-warning {{ISO C++ does not allow}} - (void)*reinterpret_cast<void*>(&b); // expected-warning {{ISO C++ does not allow}} - (void)*reinterpret_cast<void*>(&l); // expected-warning {{ISO C++ does not allow}} - (void)*reinterpret_cast<void*>(&d); // expected-warning {{ISO C++ does not allow}} - (void)*reinterpret_cast<void*>(&f); // expected-warning {{ISO C++ does not allow}} + (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_allowlist () { Index: clang/test/SemaCXX/disallow_void_deref.cpp =================================================================== --- /dev/null +++ clang/test/SemaCXX/disallow_void_deref.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s + +void f(void* p) { + (void)*p; // expected-error{{ISO C++ does not allow indirection on operand of type 'void *'}} +} + +template<class T> +concept deref = requires (T& t) { + { *t }; // #FAILED_REQ +}; + +static_assert(deref<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: ISO C++ does not allow indirection on operand of type 'void *'}} Index: clang/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1inst.cpp =================================================================== --- clang/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1inst.cpp +++ clang/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1inst.cpp @@ -8,7 +8,7 @@ template<typename T, typename U> void X0<T, U>::f(T *t, const U &u) { - *t = u; // expected-warning{{indirection on operand of type 'void *'}} expected-error{{not assignable}} + *t = u; // expected-error{{indirection 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) { Index: clang/lib/Sema/SemaExpr.cpp =================================================================== --- clang/lib/Sema/SemaExpr.cpp +++ clang/lib/Sema/SemaExpr.cpp @@ -14536,7 +14536,10 @@ // [...] the expression to which [the unary * operator] is applied shall // be a pointer to an object type, or a pointer to a function type LangOptions LO = S.getLangOpts(); - if (LO.CPlusPlus || !(LO.C99 && (IsAfterAmp || S.isUnevaluatedContext()))) + if (LO.CPlusPlus) + S.Diag(OpLoc, diag::ext_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) << LO.CPlusPlus << OpTy << Op->getSourceRange(); } Index: clang/include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- clang/include/clang/Basic/DiagnosticSemaKinds.td +++ clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -6934,6 +6934,14 @@ def ext_typecheck_indirection_through_void_pointer : ExtWarn< "ISO %select{C|C++}0 does not allow indirection on operand of type %1">, InGroup<DiagGroup<"void-ptr-dereference">>; +def ext_typecheck_indirection_through_void_pointer_cpp + : ExtWarn<"ISO C++ does not allow indirection on operand of type %0">, + // Note: This uses a different diagnostics group than the C diagnostic + // so that projects that have disabled the above will get this diagnostic, + // and be aware of the deprecation. + InGroup<DiagGroup<"void-ptr-dereference-cpp">>, + DefaultError, + SFINAEFailure; def warn_indirection_through_null : Warning< "indirection of non-volatile null pointer will be deleted, not trap">, InGroup<NullDereference>; Index: clang/docs/ReleaseNotes.rst =================================================================== --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -86,6 +86,16 @@ typedef char int8_a16 __attribute__((aligned(16))); int8_a16 array[4]; // Now diagnosed as the element size not being a multiple of the array alignment. +- Clang now diagnoses a Warning-As-Default-Error on indirection of void* in C++ + mode for ISO C++, GCC, ICC, and MSVC Compatibility. This is also now a SFINAE + error so constraint checking and SFINAE checking can be compatible with other + compilers. It is likely that this will be made a perminent error in Clang 17. + + .. code-block:: c + + void func(void* p) { + *p; // Now diagnosed as a warning-as-error. + } What's New in Clang |release|? ==============================
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits