[cfe-commits] r161052 - in /cfe/trunk: lib/Analysis/FormatString.cpp lib/Analysis/ScanfFormatString.cpp test/Sema/format-strings-scanf.c test/Sema/format-strings.c
Hans Wennborg
hans at hanshq.net
Tue Jul 31 09:37:48 PDT 2012
Author: hans
Date: Tue Jul 31 11:37:47 2012
New Revision: 161052
URL: http://llvm.org/viewvc/llvm-project?rev=161052&view=rev
Log:
-Wformat: better handling of qualifiers on pointer arguments
Warn about using pointers to const-qualified types as arguments to
scanf. Ignore the volatile qualifier when checking if types match.
Modified:
cfe/trunk/lib/Analysis/FormatString.cpp
cfe/trunk/lib/Analysis/ScanfFormatString.cpp
cfe/trunk/test/Sema/format-strings-scanf.c
cfe/trunk/test/Sema/format-strings.c
Modified: cfe/trunk/lib/Analysis/FormatString.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/FormatString.cpp?rev=161052&r1=161051&r2=161052&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/FormatString.cpp (original)
+++ cfe/trunk/lib/Analysis/FormatString.cpp Tue Jul 31 11:37:47 2012
@@ -262,6 +262,13 @@
argTy = ETy->getDecl()->getIntegerType();
argTy = C.getCanonicalType(argTy).getUnqualifiedType();
+ if (const PointerType *PTy = argTy->getAs<PointerType>()) {
+ // Strip volatile qualifier from pointee type.
+ QualType Pointee = PTy->getPointeeType();
+ Pointee.removeLocalVolatile();
+ argTy = C.getPointerType(Pointee);
+ }
+
if (T == argTy)
return true;
// Check for "compatible types".
Modified: cfe/trunk/lib/Analysis/ScanfFormatString.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/ScanfFormatString.cpp?rev=161052&r1=161051&r2=161052&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/ScanfFormatString.cpp (original)
+++ cfe/trunk/lib/Analysis/ScanfFormatString.cpp Tue Jul 31 11:37:47 2012
@@ -453,6 +453,15 @@
}
bool ScanfArgTypeResult::matchesType(ASTContext& C, QualType argTy) const {
+ // It has to be a pointer type.
+ const PointerType *PT = argTy->getAs<PointerType>();
+ if (!PT)
+ return false;
+
+ // We cannot write through a const qualified pointer.
+ if (PT->getPointeeType().isConstQualified())
+ return false;
+
switch (K) {
case InvalidTy:
llvm_unreachable("ArgTypeResult must be valid");
@@ -463,9 +472,6 @@
case WCStrTy:
return ArgTypeResult(ArgTypeResult::WCStrTy).matchesType(C, argTy);
case PtrToArgTypeResultTy: {
- const PointerType *PT = argTy->getAs<PointerType>();
- if (!PT)
- return false;
return A.matchesType(C, PT->getPointeeType());
}
}
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=161052&r1=161051&r2=161052&view=diff
==============================================================================
--- cfe/trunk/test/Sema/format-strings-scanf.c (original)
+++ cfe/trunk/test/Sema/format-strings-scanf.c Tue Jul 31 11:37:47 2012
@@ -126,3 +126,21 @@
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 *'}}
}
+
+void test_qualifiers(const int *cip, volatile int* vip,
+ const char *ccp, volatile char* vcp,
+ const volatile int *cvip) {
+ scanf("%d", cip); // expected-warning{{format specifies type 'int *' but the argument has type 'const int *'}}
+ scanf("%n", cip); // expected-warning{{format specifies type 'int *' but the argument has type 'const int *'}}
+ scanf("%s", ccp); // expected-warning{{format specifies type 'char *' but the argument has type 'const char *'}}
+ scanf("%d", cvip); // expected-warning{{format specifies type 'int *' but the argument has type 'const volatile int *'}}
+
+ scanf("%d", vip); // No warning.
+ scanf("%n", vip); // No warning.
+ scanf("%c", vcp); // No warning.
+
+ typedef int* ip_t;
+ typedef const int* cip_t;
+ scanf("%d", (ip_t)0); // No warning.
+ scanf("%d", (cip_t)0); // expected-warning{{format specifies type 'int *' but the argument has type 'cip_t' (aka 'const int *')}}
+}
Modified: cfe/trunk/test/Sema/format-strings.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/format-strings.c?rev=161052&r1=161051&r2=161052&view=diff
==============================================================================
--- cfe/trunk/test/Sema/format-strings.c (original)
+++ cfe/trunk/test/Sema/format-strings.c Tue Jul 31 11:37:47 2012
@@ -555,3 +555,19 @@
test14_foo("%", "%d", p); // expected-warning{{incomplete format specifier}}
test14_bar("%", "%d", p); // expected-warning{{incomplete format specifier}}
}
+
+void test_qualifiers(volatile int *vip, const int *cip,
+ const volatile int *cvip) {
+ printf("%n", cip); // expected-warning{{format specifies type 'int *' but the argument has type 'const int *'}}
+ printf("%n", cvip); // expected-warning{{format specifies type 'int *' but the argument has type 'const volatile int *'}}
+
+ printf("%n", vip); // No warning.
+ printf("%p", cip); // No warning.
+ printf("%p", cvip); // No warning.
+
+
+ typedef int* ip_t;
+ typedef const int* cip_t;
+ printf("%n", (ip_t)0); // No warning.
+ printf("%n", (cip_t)0); // expected-warning{{format specifies type 'int *' but the argument has type 'cip_t' (aka 'const int *')}}
+}
More information about the cfe-commits
mailing list