[cfe-commits] r156165 - in /cfe/trunk: include/clang/AST/ASTContext.h lib/AST/ASTContext.cpp lib/Analysis/FormatString.cpp lib/Sema/SemaChecking.cpp test/Sema/format-strings.c

James Molloy james.molloy at arm.com
Fri May 4 03:55:22 PDT 2012


Author: jamesm
Date: Fri May  4 05:55:22 2012
New Revision: 156165

URL: http://llvm.org/viewvc/llvm-project?rev=156165&view=rev
Log:
Fix handling of wint_t - we can't assume wint_t is purely an integer promotion of wchar_t - they may differ in signedness.

Teach ASTContext about WIntType, and have it taken from TargetInfo like WCharType. Should fix test/Sema/format-strings.c for ARM, with the exception of one subtest which will fail if wint_t and wchar_t are the same size and wint_t is signed, wchar_t is unsigned.

There'll be a followup commit to fix that.

Reviewed by Chandler and Hans at http://llvm.org/reviews/r/8


Modified:
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/Analysis/FormatString.cpp
    cfe/trunk/lib/Sema/SemaChecking.cpp
    cfe/trunk/test/Sema/format-strings.c

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=156165&r1=156164&r2=156165&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Fri May  4 05:55:22 2012
@@ -557,6 +557,7 @@
   CanQualType BoolTy;
   CanQualType CharTy;
   CanQualType WCharTy;  // [C++ 3.9.1p5], integer type in C99.
+  CanQualType WIntTy;   // [C99 7.24.1], integer type unchanged by default promotions.
   CanQualType Char16Ty; // [C++0x 3.9.1p5], integer type in C99.
   CanQualType Char32Ty; // [C++0x 3.9.1p5], integer type in C99.
   CanQualType SignedCharTy, ShortTy, IntTy, LongTy, LongLongTy, Int128Ty;
@@ -929,6 +930,10 @@
   /// Used when in C++, as a GCC extension.
   QualType getUnsignedWCharType() const;
 
+  /// getWIntType - In C99, this returns a type compatible with the type
+  /// defined in <stddef.h> as defined by the target.
+  QualType getWIntType() const { return WIntTy; }
+
   /// getPointerDiffType - Return the unique type for "ptrdiff_t" (C99 7.17)
   /// defined in <stddef.h>. Pointer - pointer requires this (C99 6.5.6p9).
   QualType getPointerDiffType() const;

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=156165&r1=156164&r2=156165&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Fri May  4 05:55:22 2012
@@ -436,6 +436,8 @@
   } else // C99
     WCharTy = getFromTargetType(Target.getWCharType());
 
+  WIntTy = getFromTargetType(Target.getWIntType());
+
   if (LangOpts.CPlusPlus) // C++0x 3.9.1p5, extension for C++
     InitBuiltinType(Char16Ty,           BuiltinType::Char16);
   else // C99

Modified: cfe/trunk/lib/Analysis/FormatString.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/FormatString.cpp?rev=156165&r1=156164&r2=156165&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/FormatString.cpp (original)
+++ cfe/trunk/lib/Analysis/FormatString.cpp Fri May  4 05:55:22 2012
@@ -319,20 +319,21 @@
     }
     
     case WIntTy: {
-      // Instead of doing a lookup for the definition of 'wint_t' (which
-      // is defined by the system headers) instead see if wchar_t and
-      // the argument type promote to the same type.
-      QualType PromoWChar =
-        C.getWCharType()->isPromotableIntegerType() 
-          ? C.getPromotedIntegerType(C.getWCharType()) : C.getWCharType();
+      
       QualType PromoArg = 
         argTy->isPromotableIntegerType()
           ? C.getPromotedIntegerType(argTy) : argTy;
       
-      PromoWChar = C.getCanonicalType(PromoWChar).getUnqualifiedType();
+      QualType WInt = C.getCanonicalType(C.getWIntType()).getUnqualifiedType();
       PromoArg = C.getCanonicalType(PromoArg).getUnqualifiedType();
       
-      return PromoWChar == PromoArg;
+      // If the promoted argument is the corresponding signed type of the
+      // wint_t type, then it should match.
+      if (PromoArg->hasSignedIntegerRepresentation() &&
+          C.getCorrespondingUnsignedType(PromoArg) == WInt)
+        return true;
+
+      return WInt == PromoArg;
     }
 
     case CPointerTy:
@@ -380,8 +381,7 @@
     case CPointerTy:
       return C.VoidPtrTy;
     case WIntTy: {
-      QualType WC = C.getWCharType();
-      return WC->isPromotableIntegerType() ? C.getPromotedIntegerType(WC) : WC;
+      return C.getWIntType();
     }
   }
 

Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=156165&r1=156164&r2=156165&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Fri May  4 05:55:22 2012
@@ -2392,7 +2392,8 @@
     // or 'short' to an 'int'.  This is done because printf is a varargs
     // function.
     if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Ex))
-      if (ICE->getType() == S.Context.IntTy) {
+      if (ICE->getType() == S.Context.IntTy ||
+          ICE->getType() == S.Context.UnsignedIntTy) {
         // All further checking is done on the subexpression.
         Ex = ICE->getSubExpr();
         if (ATR.matchesType(S.Context, Ex->getType()))

Modified: cfe/trunk/test/Sema/format-strings.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/format-strings.c?rev=156165&r1=156164&r2=156165&view=diff
==============================================================================
--- cfe/trunk/test/Sema/format-strings.c (original)
+++ cfe/trunk/test/Sema/format-strings.c Fri May  4 05:55:22 2012
@@ -1,7 +1,9 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral -isystem %S/Inputs %s
 
+#define __need_wint_t
 #include <stdarg.h>
-typedef __typeof(sizeof(int)) size_t;
+#include <stddef.h> // For wint_t and wchar_t
+
 typedef struct _FILE FILE;
 int fprintf(FILE *, const char *restrict, ...);
 int printf(const char *restrict, ...); // expected-note{{passing argument to parameter here}}
@@ -258,7 +260,6 @@
 
 // Unicode test cases.  These are possibly specific to Mac OS X.  If so, they should
 // eventually be moved into a separate test.
-typedef __WCHAR_TYPE__ wchar_t;
 
 void test_unicode_conversions(wchar_t *s) {
   printf("%S", s); // no-warning
@@ -332,16 +333,12 @@
 }
 
 // PR 7981 - handle '%lc' (wint_t)
-#ifndef wint_t
-typedef int __darwin_wint_t;
-typedef __darwin_wint_t wint_t;
-#endif
 
 void pr7981(wint_t c, wchar_t c2) {
   printf("%lc", c); // no-warning
   printf("%lc", 1.0); // expected-warning{{the argument has type 'double'}}
   printf("%lc", (char) 1); // no-warning
-  printf("%lc", &c); // expected-warning{{the argument has type 'wint_t *' (aka 'int *')}}
+  printf("%lc", &c); // expected-warning{{the argument has type 'wint_t *'}}
   printf("%lc", c2); // no-warning
 }
 





More information about the cfe-commits mailing list