MarcusJohnson91 updated this revision to Diff 363244.
MarcusJohnson91 added a comment.

Rebased on Main


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

https://reviews.llvm.org/D106756

Files:
  clang/include/clang/AST/FormatString.h
  clang/lib/AST/FormatString.cpp
  clang/test/Sema/format-strings-int-typedefs.c
  clang/test/SemaCXX/format-strings.cpp

Index: clang/test/SemaCXX/format-strings.cpp
===================================================================
--- clang/test/SemaCXX/format-strings.cpp
+++ clang/test/SemaCXX/format-strings.cpp
@@ -24,6 +24,8 @@
 
 void g() {
   printf("%ls", "foo"); // expected-warning{{format specifies type 'wchar_t *' but the argument has type 'const char *'}}
+  printf("%l16s", "foo"); // expected-warning{{format specifies type 'char16_t *' but the argument has type 'const char *'}}
+  printf("%l32s", "foo"); // expected-warning{{format specifies type 'char32_t *' but the argument has type 'const char *'}}
 }
 
 // Test that we properly handle format_idx on C++ members.
Index: clang/test/Sema/format-strings-int-typedefs.c
===================================================================
--- clang/test/Sema/format-strings-int-typedefs.c
+++ clang/test/Sema/format-strings-int-typedefs.c
@@ -10,18 +10,35 @@
   printf("%td", 42.0); // expected-warning {{format specifies type 'ptrdiff_t' (aka 'int')}}
   printf("%lc", 42.0); // expected-warning {{format specifies type 'wint_t' (aka 'int')}}
   printf("%ls", 42.0); // expected-warning {{format specifies type 'wchar_t *' (aka 'int *')}}
+  printf("%l16c", 42.0); // expected-warning {{format specifies type 'char16_t' (aka 'int')}}
+  printf("%l16s", 42.0); // expected-warning {{format specifies type 'char16_t *' (aka 'int *')}}
+  printf("%l32c", 42.0); // expected-warning {{format specifies type 'char32_t' (aka 'int')}}
+  printf("%l32s", 42.0); // expected-warning {{format specifies type 'char32_t *' (aka 'int *')}}
   printf("%S", 42.0);  // expected-warning {{format specifies type 'wchar_t *' (aka 'int *')}}
   printf("%C", 42.0);  // expected-warning {{format specifies type 'wchar_t' (aka 'int')}}
 
+  wprintf(L"%l16c", 42.0); // expected-warning {{format specifies type 'char16_t' (aka 'short')}}
+  wprintf(L"%l16s", 42.0); // expected-warning {{format specifies type 'char16_t *' (aka 'short *')}}
+  wprintf(L"%l32c", 42.0); // expected-warning {{format specifies type 'char32_t' (aka 'int')}}
+  wprintf(L"%l32s", 42.0); // expected-warning {{format specifies type 'char32_t *' (aka 'int *')}}
+
   scanf("%jd", 0); // expected-warning {{format specifies type 'intmax_t *' (aka 'long long *')}}
   scanf("%ju", 0); // expected-warning {{format specifies type 'uintmax_t *' (aka 'unsigned long long *')}}
   scanf("%zu", 0); // expected-warning {{format specifies type 'size_t *' (aka 'unsigned long *')}}
   scanf("%td", 0); // expected-warning {{format specifies type 'ptrdiff_t *' (aka 'int *')}}
   scanf("%lc", 0); // expected-warning {{format specifies type 'wchar_t *' (aka 'int *')}}
   scanf("%ls", 0); // expected-warning {{format specifies type 'wchar_t *' (aka 'int *')}}
+  scanf("%l16c", 0); // expected-warning {{format specifies type 'char16_t *' (aka 'int *')}}
+  scanf("%l16s", 0); // expected-warning {{format specifies type 'char16_t *' (aka 'int *')}}
+  scanf("%l32c", 0); // expected-warning {{format specifies type 'char32_t *' (aka 'int *')}}
+  scanf("%l32s", 0); // expected-warning {{format specifies type 'char32_t *' (aka 'int *')}}
   scanf("%S",  0);  // expected-warning {{format specifies type 'wchar_t *' (aka 'int *')}}
   scanf("%C",  0);  // expected-warning {{format specifies type 'wchar_t *' (aka 'int *')}}
 
+  wscanf("%l16c", 0); // expected-warning {{format specifies type 'char16_t *' (aka 'int *')}}
+  wscanf("%l16s", 0); // expected-warning {{format specifies type 'char16_t *' (aka 'int *')}}
+  wscanf("%l32c", 0); // expected-warning {{format specifies type 'char32_t *' (aka 'int *')}}
+  wscanf("%l32s", 0); // expected-warning {{format specifies type 'char32_t *' (aka 'int *')}}
 
   // typedef size_t et al. to something crazy.
   typedef void *size_t;
Index: clang/lib/AST/FormatString.cpp
===================================================================
--- clang/lib/AST/FormatString.cpp
+++ clang/lib/AST/FormatString.cpp
@@ -520,6 +520,12 @@
     case WCStrTy:
       Res = C.getPointerType(C.getWideCharType());
       break;
+    case Char16Ty:
+      Res = C.getPointerType(C.getChar16Type());
+      break;
+    case Char32Ty:
+      Res = C.getPointerType(C.getChar32Type());
+      break;
     case ObjCPointerTy:
       Res = C.ObjCBuiltinIdTy;
       break;
@@ -607,6 +613,10 @@
     return "m";
   case AsWide:
     return "w";
+  case AsUTF16:
+    return "l16";
+  case AsUTF32:
+    return "l32";
   case None:
     return "";
   }
@@ -860,6 +870,17 @@
         default:
           return false;
       }
+    case LengthModifier::AsUTF16:
+    case LengthModifier::AsUTF32:
+      switch (CS.getKind()) {
+      case ConversionSpecifier::cArg:
+      case ConversionSpecifier::CArg:
+      case ConversionSpecifier::sArg:
+      case ConversionSpecifier::SArg:
+        return true;
+      default:
+        return false;
+      }
     case LengthModifier::AsWide:
       switch (CS.getKind()) {
         case ConversionSpecifier::cArg:
@@ -886,6 +907,8 @@
     case LengthModifier::AsSizeT:
     case LengthModifier::AsPtrDiff:
     case LengthModifier::AsLongDouble:
+    case LengthModifier::AsUTF16:
+    case LengthModifier::AsUTF32:
       return true;
     case LengthModifier::AsAllocate:
     case LengthModifier::AsMAllocate:
@@ -997,6 +1020,12 @@
     } else if (Identifier->getName() == "ptrdiff_t") {
       LM.setKind(LengthModifier::AsPtrDiff);
       return true;
+    } else if (Identifier->getName() == "char16_t") {
+      LM.setKind(LengthModifier::AsUTF16);
+      return true;
+    } else if (Identifier->getName() == "char32_t") {
+      LM.setKind(LengthModifier::AsUTF32);
+      return true;
     }
 
     QualType T = Typedef->getUnderlyingType();
Index: clang/include/clang/AST/FormatString.h
===================================================================
--- clang/include/clang/AST/FormatString.h
+++ clang/include/clang/AST/FormatString.h
@@ -65,22 +65,24 @@
 public:
   enum Kind {
     None,
-    AsChar,       // 'hh'
-    AsShort,      // 'h'
-    AsShortLong,  // 'hl' (OpenCL float/int vector element)
-    AsLong,       // 'l'
-    AsLongLong,   // 'll'
-    AsQuad,       // 'q' (BSD, deprecated, for 64-bit integer types)
-    AsIntMax,     // 'j'
-    AsSizeT,      // 'z'
-    AsPtrDiff,    // 't'
-    AsInt32,      // 'I32' (MSVCRT, like __int32)
-    AsInt3264,    // 'I'   (MSVCRT, like __int3264 from MIDL)
-    AsInt64,      // 'I64' (MSVCRT, like __int64)
-    AsLongDouble, // 'L'
-    AsAllocate,   // for '%as', GNU extension to C90 scanf
-    AsMAllocate,  // for '%ms', GNU extension to scanf
-    AsWide,       // 'w' (MSVCRT, like l but only for c, C, s, S, or Z
+    AsChar,             // 'hh'
+    AsShort,            // 'h'
+    AsShortLong,        // 'hl' (OpenCL float/int vector element)
+    AsLong,             // 'l'
+    AsLongLong,         // 'll'
+    AsQuad,             // 'q' (BSD, deprecated, for 64-bit integer types)
+    AsIntMax,           // 'j'
+    AsSizeT,            // 'z'
+    AsPtrDiff,          // 't'
+    AsInt32,            // 'I32' (MSVCRT, like __int32)
+    AsInt3264,          // 'I'   (MSVCRT, like __int3264 from MIDL)
+    AsInt64,            // 'I64' (MSVCRT, like __int64)
+    AsLongDouble,       // 'L'
+    AsAllocate,         // for '%as', GNU extension to C90 scanf
+    AsMAllocate,        // for '%ms', GNU extension to scanf
+    AsUTF16,            // for '%l16(c|s)', Clang extension
+    AsUTF32,            // for '%l32(c|s)', Clang extension
+    AsWide,             // 'w' (MSVCRT, like l but only for c, C, s, S, or Z
     AsWideChar = AsLong // for '%ls', only makes sense for printf
   };
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to