hubert.reinterpretcast updated this revision to Diff 315648.
hubert.reinterpretcast added a comment.

- Address review: Mention plain char only when it appears


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D93999/new/

https://reviews.llvm.org/D93999

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaExpr.cpp
  clang/test/Sema/incompatible-sign.c
  clang/test/Sema/incompatible-sign.cpp
  clang/test/SemaObjC/objc-cf-audited-warning.m

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 where one is of the unique plain char type and the other is not}}
 }
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 where one is of the unique plain char type and the other is not}}
+}
+
+void unsignedToPlain() {
+  extern unsigned char uc;
+  char *p;
+  p = &uc; // expected-error {{converts between pointers to integer types where one is of the unique plain char type and the other is not}}
+}
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}}
 
+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 where one is of the unique plain char type and the other is not}}
+  struct { signed char *p; } s = { &c }; // expected-warning {{converts between pointers to integer types where one is of the unique plain char type and the other is not}}
+  p = &c; // expected-warning {{converts between pointers to integer types where one is of the unique plain char type and the other is not}}
+  plainCharToSignedChar(&c); // expected-warning {{converts between pointers to integer types where one is of the unique plain char type and the other is not}}
+  return &c; // expected-warning {{converts between pointers to integer types where one is of the unique plain char type and the other is not}}
+}
+
+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 where one is of the unique plain char type and the other is not}}
+  (void) (char *[]){ [42] = uc }; // expected-warning {{converts between pointers to integer types where one is of the unique plain char type and the other is not}}
+  p = uc; // expected-warning {{converts between pointers to integer types where one is of the unique plain char type and the other is not}}
+  unsignedCharToPlainChar(uc); // expected-warning {{converts between pointers to integer types where one is of the unique plain char type and the other is not}}
+  return uc; // expected-warning {{converts between pointers to integer types where one is of the unique plain char type and the other is not}}
+}
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -15962,6 +15962,16 @@
   else
     FDiag << FirstType << SecondType << Action << SrcExpr->getSourceRange();
 
+  if (DiagKind == diag::ext_typecheck_convert_incompatible_pointer_sign ||
+      DiagKind == diag::err_typecheck_convert_incompatible_pointer_sign) {
+    const auto isPlainChar = [](const clang::Type *Type) {
+      return Type->isSpecificBuiltinType(BuiltinType::Char_S) ||
+             Type->isSpecificBuiltinType(BuiltinType::Char_U);
+    };
+    FDiag << (isPlainChar(FirstType->getPointeeOrArrayElementType()) ||
+              isPlainChar(SecondType->getPointeeOrArrayElementType()));
+  }
+
   // If we can fix the conversion, suggest the FixIts.
   if (!ConvHints.isNull()) {
     for (FixItHint &H : ConvHints.Hints)
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -7780,21 +7780,11 @@
   "|%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 %select{with different sign|"
+  "where one is of the unique plain char type and the other is not}3">,
   InGroup<DiagGroup<"pointer-sign">>;
-def err_typecheck_convert_incompatible_pointer_sign : Error<
-  "%select{%diff{assigning to $ from $|assigning to different types}0,1"
-  "|%diff{passing $ to parameter of type $|"
-  "passing to parameter of different type}0,1"
-  "|%diff{returning $ from a function with result type $|"
-  "returning from function with different return type}0,1"
-  "|%diff{converting $ to type $|converting between types}0,1"
-  "|%diff{initializing $ with an expression of type $|"
-  "initializing with expression of different type}0,1"
-  "|%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">;
+def err_typecheck_convert_incompatible_pointer_sign :
+  Error<ext_typecheck_convert_incompatible_pointer_sign.Text>;
 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