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
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@156165
91177308-0d34-0410-b5e6-
96231b3b80d8
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;
/// 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;
} 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
}
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:
case CPointerTy:
return C.VoidPtrTy;
case WIntTy: {
- QualType WC = C.getWCharType();
- return WC->isPromotableIntegerType() ? C.getPromotedIntegerType(WC) : WC;
+ return C.getWIntType();
}
}
// 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()))
// 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}}
// 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
}
// 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
}