]> granicus.if.org Git - clang/commitdiff
Sema: handle `wint_t` more carefully for printf checking
authorSaleem Abdulrasool <compnerd@compnerd.org>
Wed, 19 Sep 2018 18:13:34 +0000 (18:13 +0000)
committerSaleem Abdulrasool <compnerd@compnerd.org>
Wed, 19 Sep 2018 18:13:34 +0000 (18:13 +0000)
In the case that `win_t` is an `unsigned short` (e.g. on Windows), we would
previously incorrectly diagnose the conversion because we would immediately
promote the argument type from `wint_t` (aka `unsigned short`) to `int` before
checking if the type matched.  This should repair the Windows hosted bots.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@342565 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/FormatString.cpp
test/Sema/format-strings-ms.c
test/Sema/format-strings.c

index f37e4affae3fcd0d3bc8955f475ddcdccdd3b748..0bab50c569f768adb2a916bc3678b26c884c3bd6 100644 (file)
@@ -406,12 +406,14 @@ ArgType::matchesType(ASTContext &C, QualType argTy) const {
     }
 
     case WIntTy: {
+      QualType WInt = C.getCanonicalType(C.getWIntType()).getUnqualifiedType();
 
-      QualType PromoArg =
-        argTy->isPromotableIntegerType()
-          ? C.getPromotedIntegerType(argTy) : argTy;
+      if (C.getCanonicalType(argTy).getUnqualifiedType() == WInt)
+        return Match;
 
-      QualType WInt = C.getCanonicalType(C.getWIntType()).getUnqualifiedType();
+      QualType PromoArg = argTy->isPromotableIntegerType()
+                              ? C.getPromotedIntegerType(argTy)
+                              : argTy;
       PromoArg = C.getCanonicalType(PromoArg).getUnqualifiedType();
 
       // If the promoted argument is the corresponding signed type of the
index 9887b461f610136b5e114a731040ad1e73685279..56a349051d427a4ab882a50d46904e32d10309d7 100644 (file)
@@ -13,7 +13,6 @@ void non_iso_warning_test(__int32 i32, __int64 i64, wchar_t c, void *p) {
   printf("%I32d", i32); // expected-warning{{'I32' length modifier is not supported by ISO C}}
   printf("%I64d", i64); // expected-warning{{'I64' length modifier is not supported by ISO C}}
   printf("%wc", c); // expected-warning{{'w' length modifier is not supported by ISO C}}
-  // expected-warning@-1{{format specifies type 'wint_t' (aka 'unsigned short') but the argument has type 'wchar_t' (aka 'unsigned short')}}
   printf("%Z", p); // expected-warning{{'Z' conversion specifier is not supported by ISO C}}
 }
 
@@ -36,7 +35,7 @@ void unsigned_test() {
 }
 
 void w_test(wchar_t c, wchar_t *s) {
-  printf("%wc", c); // expected-warning{{format specifies type 'wint_t' (aka 'unsigned short') but the argument has type 'wchar_t' (aka 'unsigned short')}}
+  printf("%wc", c);
   printf("%wC", c);
   printf("%C", c);
   printf("%ws", s);
index 54651226adc5c88795ff4a3de422659ffbcfa56e..6630acdbc28bc247621500dba3e133cdd73b238b 100644 (file)
@@ -401,7 +401,11 @@ void bug7377_bad_length_mod_usage() {
 void pr7981(wint_t c, wchar_t c2) {
   printf("%lc", c); // no-warning
   printf("%lc", 1.0); // expected-warning{{the argument has type 'double'}}
+#if __WINT_WIDTH__ == 4
   printf("%lc", (char) 1); // no-warning
+#else
+  printf("%lc", (char) 1); // expected-warning{{the argument has type 'char'}}
+#endif
   printf("%lc", &c); // expected-warning{{the argument has type 'wint_t *'}}
   // If wint_t and wchar_t are the same width and wint_t is signed where
   // wchar_t is unsigned, an implicit conversion isn't possible.