[cfe-commits] r161408 - in /cfe/trunk: lib/Analysis/PrintfFormatString.cpp lib/Analysis/ScanfFormatString.cpp test/Sema/format-strings-scanf.c test/Sema/format-strings-size_t.c test/Sema/format-strings.c
Hans Wennborg
hans at hanshq.net
Tue Aug 7 02:13:19 PDT 2012
Author: hans
Date: Tue Aug 7 04:13:19 2012
New Revision: 161408
URL: http://llvm.org/viewvc/llvm-project?rev=161408&view=rev
Log:
Properly check length modfiers for %n in format strings.
Modified:
cfe/trunk/lib/Analysis/PrintfFormatString.cpp
cfe/trunk/lib/Analysis/ScanfFormatString.cpp
cfe/trunk/test/Sema/format-strings-scanf.c
cfe/trunk/test/Sema/format-strings-size_t.c
cfe/trunk/test/Sema/format-strings.c
Modified: cfe/trunk/lib/Analysis/PrintfFormatString.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/PrintfFormatString.cpp?rev=161408&r1=161407&r2=161408&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/PrintfFormatString.cpp (original)
+++ cfe/trunk/lib/Analysis/PrintfFormatString.cpp Tue Aug 7 04:13:19 2012
@@ -312,6 +312,33 @@
return Ctx.DoubleTy;
}
+ if (CS.getKind() == ConversionSpecifier::nArg) {
+ switch (LM.getKind()) {
+ case LengthModifier::None:
+ return ArgType::PtrTo(Ctx.IntTy);
+ case LengthModifier::AsChar:
+ return ArgType::PtrTo(Ctx.SignedCharTy);
+ case LengthModifier::AsShort:
+ return ArgType::PtrTo(Ctx.ShortTy);
+ case LengthModifier::AsLong:
+ return ArgType::PtrTo(Ctx.LongTy);
+ case LengthModifier::AsLongLong:
+ case LengthModifier::AsQuad:
+ return ArgType::PtrTo(Ctx.LongLongTy);
+ case LengthModifier::AsIntMax:
+ return ArgType::PtrTo(ArgType(Ctx.getIntMaxType(), "intmax_t"));
+ case LengthModifier::AsSizeT:
+ return ArgType(); // FIXME: ssize_t
+ case LengthModifier::AsPtrDiff:
+ return ArgType::PtrTo(ArgType(Ctx.getPointerDiffType(), "ptrdiff_t"));
+ case LengthModifier::AsLongDouble:
+ return ArgType(); // FIXME: Is this a known extension?
+ case LengthModifier::AsAllocate:
+ case LengthModifier::AsMAllocate:
+ return ArgType::Invalid();
+ }
+ }
+
switch (CS.getKind()) {
case ConversionSpecifier::sArg:
if (LM.getKind() == LengthModifier::AsWideChar) {
@@ -330,8 +357,6 @@
return ArgType(Ctx.WCharTy, "wchar_t");
case ConversionSpecifier::pArg:
return ArgType::CPointerTy;
- case ConversionSpecifier::nArg:
- return ArgType::PtrTo(Ctx.IntTy);
case ConversionSpecifier::ObjCObjArg:
return ArgType::ObjCPointerTy;
default:
Modified: cfe/trunk/lib/Analysis/ScanfFormatString.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/ScanfFormatString.cpp?rev=161408&r1=161407&r2=161408&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/ScanfFormatString.cpp (original)
+++ cfe/trunk/lib/Analysis/ScanfFormatString.cpp Tue Aug 7 04:13:19 2012
@@ -318,7 +318,30 @@
// Write-back.
case ConversionSpecifier::nArg:
- return ArgType::PtrTo(Ctx.IntTy);
+ switch (LM.getKind()) {
+ case LengthModifier::None:
+ return ArgType::PtrTo(Ctx.IntTy);
+ case LengthModifier::AsChar:
+ return ArgType::PtrTo(Ctx.SignedCharTy);
+ case LengthModifier::AsShort:
+ return ArgType::PtrTo(Ctx.ShortTy);
+ case LengthModifier::AsLong:
+ return ArgType::PtrTo(Ctx.LongTy);
+ case LengthModifier::AsLongLong:
+ case LengthModifier::AsQuad:
+ return ArgType::PtrTo(Ctx.LongLongTy);
+ case LengthModifier::AsIntMax:
+ return ArgType::PtrTo(ArgType(Ctx.getIntMaxType(), "intmax_t"));
+ case LengthModifier::AsSizeT:
+ return ArgType(); // FIXME: ssize_t
+ case LengthModifier::AsPtrDiff:
+ return ArgType::PtrTo(ArgType(Ctx.getPointerDiffType(), "ptrdiff_t"));
+ case LengthModifier::AsLongDouble:
+ return ArgType(); // FIXME: Is this a known extension?
+ case LengthModifier::AsAllocate:
+ case LengthModifier::AsMAllocate:
+ return ArgType::Invalid();
+ }
default:
break;
Modified: cfe/trunk/test/Sema/format-strings-scanf.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/format-strings-scanf.c?rev=161408&r1=161407&r2=161408&view=diff
==============================================================================
--- cfe/trunk/test/Sema/format-strings-scanf.c (original)
+++ cfe/trunk/test/Sema/format-strings-scanf.c Tue Aug 7 04:13:19 2012
@@ -131,6 +131,32 @@
void test_writeback(int *x) {
scanf("%n", (void*)0); // expected-warning{{format specifies type 'int *' but the argument has type 'void *'}}
scanf("%n %c", x, x); // expected-warning{{format specifies type 'char *' but the argument has type 'int *'}}
+
+ scanf("%hhn", (signed char*)0); // no-warning
+ scanf("%hhn", (char*)0); // no-warning
+ scanf("%hhn", (unsigned char*)0); // no-warning
+ scanf("%hhn", (int*)0); // expected-warning{{format specifies type 'signed char *' but the argument has type 'int *'}}
+
+ scanf("%hn", (short*)0); // no-warning
+ scanf("%hn", (unsigned short*)0); // no-warning
+ scanf("%hn", (int*)0); // expected-warning{{format specifies type 'short *' but the argument has type 'int *'}}
+
+ scanf("%n", (int*)0); // no-warning
+ scanf("%n", (unsigned int*)0); // no-warning
+ scanf("%n", (char*)0); // expected-warning{{format specifies type 'int *' but the argument has type 'char *'}}
+
+ scanf("%ln", (long*)0); // no-warning
+ scanf("%ln", (unsigned long*)0); // no-warning
+ scanf("%ln", (int*)0); // expected-warning{{format specifies type 'long *' but the argument has type 'int *'}}
+
+ scanf("%lln", (long long*)0); // no-warning
+ scanf("%lln", (unsigned long long*)0); // no-warning
+ scanf("%lln", (int*)0); // expected-warning{{format specifies type 'long long *' but the argument has type 'int *'}}
+
+ scanf("%qn", (long long*)0); // no-warning
+ scanf("%qn", (unsigned long long*)0); // no-warning
+ scanf("%qn", (int*)0); // expected-warning{{format specifies type 'long long *' but the argument has type 'int *'}}
+
}
void test_qualifiers(const int *cip, volatile int* vip,
Modified: cfe/trunk/test/Sema/format-strings-size_t.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/format-strings-size_t.c?rev=161408&r1=161407&r2=161408&view=diff
==============================================================================
--- cfe/trunk/test/Sema/format-strings-size_t.c (original)
+++ cfe/trunk/test/Sema/format-strings-size_t.c Tue Aug 7 04:13:19 2012
@@ -13,3 +13,16 @@
// ptrdiff_t
printf("%td", (double)42); // expected-warning {{format specifies type 'ptrdiff_t' (aka 'long') but the argument has type 'double'}}
}
+
+void test_writeback(void) {
+ printf("%jn", (long*)0); // no-warning
+ printf("%jn", (unsigned long*)0); // no-warning
+ printf("%jn", (int*)0); // expected-warning{{format specifies type 'intmax_t *' (aka 'long *') but the argument has type 'int *'}}
+
+ printf("%zn", (long*)0); // no-warning
+ // FIXME: Warn about %zn with non-ssize_t argument.
+
+ printf("%tn", (long*)0); // no-warning
+ printf("%tn", (unsigned long*)0); // no-warning
+ printf("%tn", (int*)0); // expected-warning{{format specifies type 'ptrdiff_t *' (aka 'long *') but the argument has type 'int *'}}
+}
Modified: cfe/trunk/test/Sema/format-strings.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/format-strings.c?rev=161408&r1=161407&r2=161408&view=diff
==============================================================================
--- cfe/trunk/test/Sema/format-strings.c (original)
+++ cfe/trunk/test/Sema/format-strings.c Tue Aug 7 04:13:19 2012
@@ -90,6 +90,33 @@
char *b;
printf("%n", b); // expected-warning{{format specifies type 'int *' but the argument has type 'char *'}}
printf("%n", &x); // no-warning
+
+ printf("%hhn", (signed char*)0); // no-warning
+ printf("%hhn", (char*)0); // no-warning
+ printf("%hhn", (unsigned char*)0); // no-warning
+ printf("%hhn", (int*)0); // expected-warning{{format specifies type 'signed char *' but the argument has type 'int *'}}
+
+ printf("%hn", (short*)0); // no-warning
+ printf("%hn", (unsigned short*)0); // no-warning
+ printf("%hn", (int*)0); // expected-warning{{format specifies type 'short *' but the argument has type 'int *'}}
+
+ printf("%n", (int*)0); // no-warning
+ printf("%n", (unsigned int*)0); // no-warning
+ printf("%n", (char*)0); // expected-warning{{format specifies type 'int *' but the argument has type 'char *'}}
+
+ printf("%ln", (long*)0); // no-warning
+ printf("%ln", (unsigned long*)0); // no-warning
+ printf("%ln", (int*)0); // expected-warning{{format specifies type 'long *' but the argument has type 'int *'}}
+
+ printf("%lln", (long long*)0); // no-warning
+ printf("%lln", (unsigned long long*)0); // no-warning
+ printf("%lln", (int*)0); // expected-warning{{format specifies type 'long long *' but the argument has type 'int *'}}
+
+ printf("%qn", (long long*)0); // no-warning
+ printf("%qn", (unsigned long long*)0); // no-warning
+ printf("%qn", (int*)0); // expected-warning{{format specifies type 'long long *' but the argument has type 'int *'}}
+
+ printf("%Ln", 0); // expected-warning{{length modifier 'L' results in undefined behavior or no effect with 'n' conversion specifier}}
}
void check_invalid_specifier(FILE* fp, char *buf)
More information about the cfe-commits
mailing list