[clang] fca4e2a - Make dereferencing a void* a hard-error instead of warn-as-error

Erich Keane via cfe-commits cfe-commits at lists.llvm.org
Wed May 24 11:27:19 PDT 2023


Author: Erich Keane
Date: 2023-05-24T11:27:13-07:00
New Revision: fca4e2add0f8b0471e4dbae5cf647006ec360bb2

URL: https://github.com/llvm/llvm-project/commit/fca4e2add0f8b0471e4dbae5cf647006ec360bb2
DIFF: https://github.com/llvm/llvm-project/commit/fca4e2add0f8b0471e4dbae5cf647006ec360bb2.diff

LOG: 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

Added: 
    

Modified: 
    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/decl-expr-ambiguity.cpp
    clang/test/SemaCXX/disallow_void_deref.cpp
    clang/test/SemaCXX/reinterpret-cast.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 53bc6b6c00270..0075f94e344ee 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -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
 ---------------------------

diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 0cbc2fc8c8949..f203ac6c2a84e 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -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>;

diff  --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index ac0b2ad6eb7ee..fb55c95bd0689 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -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)

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 6d591457ae149..9b570202b0635 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-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) {

diff  --git a/clang/test/SemaCXX/decl-expr-ambiguity.cpp b/clang/test/SemaCXX/decl-expr-ambiguity.cpp
index a15ec397b4aed..89265494a0dd3 100644
--- a/clang/test/SemaCXX/decl-expr-ambiguity.cpp
+++ b/clang/test/SemaCXX/decl-expr-ambiguity.cpp
@@ -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'}}

diff  --git a/clang/test/SemaCXX/disallow_void_deref.cpp b/clang/test/SemaCXX/disallow_void_deref.cpp
index 2981e709525b2..4e3313347d818 100644
--- a/clang/test/SemaCXX/disallow_void_deref.cpp
+++ b/clang/test/SemaCXX/disallow_void_deref.cpp
@@ -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 at -1{{static assertion failed}}
-// sfinae-note at -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 at -1{{static assertion failed}}
+// expected-note at -2{{because 'void *' does not satisfy 'deref'}}
+// expected-note@#FAILED_REQ{{because '*t' would be invalid: indirection not permitted on operand of type 'void *'}}

diff  --git a/clang/test/SemaCXX/reinterpret-cast.cpp b/clang/test/SemaCXX/reinterpret-cast.cpp
index ee856485272b2..63619b52b9702 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-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 () {


        


More information about the cfe-commits mailing list