Author: Erich Keane Date: 2022-10-10T07:11:46-07:00 New Revision: 6685e56ceddf7c88eb3c39e838a8164941aade05
URL: https://github.com/llvm/llvm-project/commit/6685e56ceddf7c88eb3c39e838a8164941aade05 DIFF: https://github.com/llvm/llvm-project/commit/6685e56ceddf7c88eb3c39e838a8164941aade05.diff LOG: Disallow dereferencing of void* in C++. 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. Differential Revision: https://reviews.llvm.org/D135287 Added: clang/test/SemaCXX/disallow_void_deref.cpp Modified: clang/docs/ReleaseNotes.rst clang/include/clang/Basic/DiagnosticGroups.td 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/reinterpret-cast.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 513a5eda80801..16e6522a44273 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -117,6 +117,18 @@ code bases. These errors also match MSVC's behavior. +- Clang now diagnoses indirection of ``void *`` in C++ mode as a warning which + defaults to an error. This is compatible with ISO C++, GCC, ICC, and MSVC. This + is also now a SFINAE error so constraint checking and SFINAE checking can be + compatible with other compilers. It is expected that this will be upgraded to + an error-only diagnostic in the next Clang release. + + .. code-block:: c++ + + void func(void *p) { + *p; // Now diagnosed as a warning-as-error. + } + What's New in Clang |release|? ============================== Some of the major new features and improvements to Clang are listed diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td index ff88c8acec4c1..cddb127cae58f 100644 --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -961,6 +961,7 @@ def PointerToEnumCast : DiagGroup<"pointer-to-enum-cast", [VoidPointerToEnumCast]>; def PointerToIntCast : DiagGroup<"pointer-to-int-cast", [PointerToEnumCast, VoidPointerToIntCast]>; +def VoidPointerDeref : DiagGroup<"void-ptr-dereference">; def FUseLdPath : DiagGroup<"fuse-ld-path">; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 8a721d45e78f0..d6fbaed126d64 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -6936,8 +6936,11 @@ def err_typecheck_unary_expr : Error< def err_typecheck_indirection_requires_pointer : Error< "indirection requires pointer operand (%0 invalid)">; 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">>; + "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 warn_indirection_through_null : Warning< "indirection of non-volatile null pointer will be deleted, not trap">, InGroup<NullDereference>; diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 6d28a44952318..474f86cffd169 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -14536,9 +14536,12 @@ static QualType CheckIndirectionOperand(Sema &S, Expr *Op, ExprValueKind &VK, // [...] 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(); + << OpTy << Op->getSourceRange(); } // Dereferences are usually l-values... diff --git a/clang/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1inst.cpp b/clang/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1inst.cpp index eb11e3375e5f6..6d591457ae149 100644 --- a/clang/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1inst.cpp +++ b/clang/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1inst.cpp @@ -8,7 +8,7 @@ struct X0 { 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) { diff --git a/clang/test/SemaCXX/disallow_void_deref.cpp b/clang/test/SemaCXX/disallow_void_deref.cpp new file mode 100644 index 0000000000000..2981e709525b2 --- /dev/null +++ b/clang/test/SemaCXX/disallow_void_deref.cpp @@ -0,0 +1,16 @@ +// 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 + +void f(void* p) { + (void)*p; // enabled-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*>); +// 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 *'}} diff --git a/clang/test/SemaCXX/reinterpret-cast.cpp b/clang/test/SemaCXX/reinterpret-cast.cpp index 1b84df12129c7..ee856485272b2 100644 --- a/clang/test/SemaCXX/reinterpret-cast.cpp +++ b/clang/test/SemaCXX/reinterpret-cast.cpp @@ -214,11 +214,11 @@ void dereference_reinterpret_cast() { (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 () { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits