hubert.reinterpretcast created this revision.
hubert.reinterpretcast added reviewers: aaron.ballman, rsmith.
Herald added subscribers: jfb, jvesely.
hubert.reinterpretcast requested review of this revision.
Herald added a project: clang.

The `-Wpointer-sign` warning text is inappropriate for describing the 
incompatible pointer conversion between plain `char` and explicitly 
`signed`/`unsigned` `char` (whichever plain `char` has the same range as) and 
vice versa.

Specifically, in part, it reads "converts between pointers to integer types 
with different sign". This patch changes that portion to read instead as 
"converts between pointers to integer types that differ by 
signed/unsigned/plain variation".

C17 subclause 6.5.16.1 indicates that the conversions resulting in 
`-Wpointer-sign` warnings in assignment-like contexts are constraint 
violations. This means that strict conformance requires a diagnostic for the 
case where the message text is wrong before this patch. The lack of an even 
more specialized warning group is consistent with GCC.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D93999

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/test/Sema/incompatible-sign.c
  clang/test/Sema/incompatible-sign.cpp
  clang/test/Sema/vector-ops.c
  clang/test/SemaObjC/objc-cf-audited-warning.m
  clang/test/SemaOpenCL/builtins-amdgcn-error.cl

Index: clang/test/SemaOpenCL/builtins-amdgcn-error.cl
===================================================================
--- clang/test/SemaOpenCL/builtins-amdgcn-error.cl
+++ clang/test/SemaOpenCL/builtins-amdgcn-error.cl
@@ -156,7 +156,7 @@
   const char ptr[] = "workgroup";
   val = __builtin_amdgcn_atomic_inc32(&val, val, __ATOMIC_ACQUIRE, ptr); // expected-error {{expression is not a string literal}}
   int signedVal = 15;
-  signedVal = __builtin_amdgcn_atomic_inc32(&signedVal, signedVal, __ATOMIC_ACQUIRE, ""); // expected-warning {{passing '__private int *' to parameter of type 'volatile __private unsigned int *' converts between pointers to integer types with different sign}}
+  signedVal = __builtin_amdgcn_atomic_inc32(&signedVal, signedVal, __ATOMIC_ACQUIRE, ""); // expected-warning {{passing '__private int *' to parameter of type 'volatile __private unsigned int *' converts between pointers to integer types that differ by signed/unsigned/plain variation}}
 }
 
 void test_atomic_inc64() {
@@ -170,7 +170,7 @@
   const char ptr[] = "workgroup";
   val = __builtin_amdgcn_atomic_inc64(&val, val, __ATOMIC_ACQUIRE, ptr); // expected-error {{expression is not a string literal}}
   __INT64_TYPE__ signedVal = 15;
-  signedVal = __builtin_amdgcn_atomic_inc64(&signedVal, signedVal, __ATOMIC_ACQUIRE, ""); // expected-warning {{passing '__private long *' to parameter of type 'volatile __private unsigned long *' converts between pointers to integer types with different sign}}
+  signedVal = __builtin_amdgcn_atomic_inc64(&signedVal, signedVal, __ATOMIC_ACQUIRE, ""); // expected-warning {{passing '__private long *' to parameter of type 'volatile __private unsigned long *' converts between pointers to integer types that differ by signed/unsigned/plain variation}}
 }
 
 void test_atomic_dec32() {
@@ -184,7 +184,7 @@
   const char ptr[] = "workgroup";
   val = __builtin_amdgcn_atomic_dec32(&val, val, __ATOMIC_ACQUIRE, ptr); // expected-error {{expression is not a string literal}}
   int signedVal = 15;
-  signedVal = __builtin_amdgcn_atomic_dec32(&signedVal, signedVal, __ATOMIC_ACQUIRE, ""); // expected-warning {{passing '__private int *' to parameter of type 'volatile __private unsigned int *' converts between pointers to integer types with different sign}}
+  signedVal = __builtin_amdgcn_atomic_dec32(&signedVal, signedVal, __ATOMIC_ACQUIRE, ""); // expected-warning {{passing '__private int *' to parameter of type 'volatile __private unsigned int *' converts between pointers to integer types that differ by signed/unsigned/plain variation}}
 }
 
 void test_atomic_dec64() {
@@ -198,5 +198,5 @@
   const char ptr[] = "workgroup";
   val = __builtin_amdgcn_atomic_dec64(&val, val, __ATOMIC_ACQUIRE, ptr); // expected-error {{expression is not a string literal}}
   __INT64_TYPE__ signedVal = 15;
-  signedVal = __builtin_amdgcn_atomic_dec64(&signedVal, signedVal, __ATOMIC_ACQUIRE, ""); // expected-warning {{passing '__private long *' to parameter of type 'volatile __private unsigned long *' converts between pointers to integer types with different sign}}
+  signedVal = __builtin_amdgcn_atomic_dec64(&signedVal, signedVal, __ATOMIC_ACQUIRE, ""); // expected-warning {{passing '__private long *' to parameter of type 'volatile __private unsigned long *' converts between pointers to integer types that differ by signed/unsigned/plain variation}}
 }
Index: clang/test/SemaObjC/objc-cf-audited-warning.m
===================================================================
--- clang/test/SemaObjC/objc-cf-audited-warning.m
+++ clang/test/SemaObjC/objc-cf-audited-warning.m
@@ -20,5 +20,5 @@
 
 void saveImageToJPG(const char *filename)
 {
-    CFURLRef url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, filename, 10, 0); // expected-warning {{passing 'const char *' to parameter of type 'const UInt8 *' (aka 'const unsigned char *') converts between pointers to integer types with different sign}}
+    CFURLRef url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, filename, 10, 0); // expected-warning {{passing 'const char *' to parameter of type 'const UInt8 *' (aka 'const unsigned char *') converts between pointers to integer types that differ by signed/unsigned/plain variation}}
 }
Index: clang/test/Sema/vector-ops.c
===================================================================
--- clang/test/Sema/vector-ops.c
+++ clang/test/Sema/vector-ops.c
@@ -24,7 +24,7 @@
 
   v2u *v2u_ptr = 0;
   v2s *v2s_ptr;
-  v2s_ptr = v2u_ptr; // expected-warning{{converts between pointers to integer types with different sign}}
+  v2s_ptr = v2u_ptr; // expected-warning{{converts between pointers to integer types that differ by signed/unsigned/plain variation}}
 }
 
 void testLogicalVecVec(v2u v2ua, v2s v2sa, v2f v2fa) {
Index: clang/test/Sema/incompatible-sign.cpp
===================================================================
--- /dev/null
+++ clang/test/Sema/incompatible-sign.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+// RUN: %clang_cc1 %s -verify -fsyntax-only -fno-signed-char
+
+void plainToSigned() {
+  extern char c;
+  signed char *p;
+  p = &c; // expected-error {{converts between pointers to integer types that differ by signed/unsigned/plain variation}}
+}
+
+void unsignedToPlain() {
+  extern unsigned char uc;
+  char *p;
+  p = &uc; // expected-error {{converts between pointers to integer types that differ by signed/unsigned/plain variation}}
+}
Index: clang/test/Sema/incompatible-sign.c
===================================================================
--- clang/test/Sema/incompatible-sign.c
+++ clang/test/Sema/incompatible-sign.c
@@ -1,5 +1,23 @@
 // RUN: %clang_cc1 %s -verify -fsyntax-only
+// RUN: %clang_cc1 %s -verify -fsyntax-only -fno-signed-char
 
 int a(int* x); // expected-note{{passing argument to parameter 'x' here}}
-int b(unsigned* y) { return a(y); } // expected-warning {{passing 'unsigned int *' to parameter of type 'int *' converts between pointers to integer types with different sign}}
+int b(unsigned* y) { return a(y); } // expected-warning {{passing 'unsigned int *' to parameter of type 'int *' converts between pointers to integer types that differ by signed/unsigned/plain variation}}
 
+signed char *plainCharToSignedChar(signed char *arg) { // expected-note{{passing argument to parameter}}
+  extern char c;
+  signed char *p = &c; // expected-warning {{converts between pointers to integer types that differ by signed/unsigned/plain variation}}
+  struct { signed char *p; } s = { &c }; // expected-warning {{converts between pointers to integer types that differ by signed/unsigned/plain variation}}
+  p = &c; // expected-warning {{converts between pointers to integer types that differ by signed/unsigned/plain variation}}
+  plainCharToSignedChar(&c); // expected-warning {{converts between pointers to integer types that differ by signed/unsigned/plain variation}}
+  return &c; // expected-warning {{converts between pointers to integer types that differ by signed/unsigned/plain variation}}
+}
+
+char *unsignedCharToPlainChar(char *arg) { // expected-note{{passing argument to parameter}}
+  extern unsigned char uc;
+  char *p = &uc; // expected-warning {{converts between pointers to integer types that differ by signed/unsigned/plain variation}}
+  (void) (char *[]){ [42] = &uc }; // expected-warning {{converts between pointers to integer types that differ by signed/unsigned/plain variation}}
+  p = &uc; // expected-warning {{converts between pointers to integer types that differ by signed/unsigned/plain variation}}
+  unsignedCharToPlainChar(&uc); // expected-warning {{converts between pointers to integer types that differ by signed/unsigned/plain variation}}
+  return &uc; // expected-warning {{converts between pointers to integer types that differ by signed/unsigned/plain variation}}
+}
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -7780,7 +7780,8 @@
   "|%diff{sending $ to parameter of type $|"
   "sending to parameter of different type}0,1"
   "|%diff{casting $ to type $|casting between types}0,1}2"
-  " converts between pointers to integer types with different sign">,
+  " converts between pointers to integer types that differ by"
+  " signed/unsigned/plain variation">,
   InGroup<DiagGroup<"pointer-sign">>;
 def err_typecheck_convert_incompatible_pointer_sign : Error<
   "%select{%diff{assigning to $ from $|assigning to different types}0,1"
@@ -7794,7 +7795,8 @@
   "|%diff{sending $ to parameter of type $|"
   "sending to parameter of different type}0,1"
   "|%diff{casting $ to type $|casting between types}0,1}2"
-  " converts between pointers to integer types with different sign">;
+  " converts between pointers to integer types that differ by"
+  " signed/unsigned/plain variation">;
 def ext_typecheck_convert_incompatible_pointer : ExtWarn<
   "incompatible pointer types "
   "%select{%diff{assigning to $ from $|assigning to different types}0,1"
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to