[cfe-commits] r108499 - in /cfe/trunk: include/clang/Basic/Builtins.def include/clang/Basic/Builtins.h lib/Basic/Builtins.cpp lib/Sema/SemaDecl.cpp
Ted Kremenek
kremenek at apple.com
Thu Jul 15 19:11:15 PDT 2010
Author: kremenek
Date: Thu Jul 15 21:11:15 2010
New Revision: 108499
URL: http://llvm.org/viewvc/llvm-project?rev=108499&view=rev
Log:
Add builtin definition for scanf, including extending the builtin encoding to
represent builtins that have the "scanf" attribution (via the format attribute) just
like we do with printf functions. Follow-up work is needed to add similar support
for fscanf et al.
This is to support format-string checking for scanf functions.
Modified:
cfe/trunk/include/clang/Basic/Builtins.def
cfe/trunk/include/clang/Basic/Builtins.h
cfe/trunk/lib/Basic/Builtins.cpp
cfe/trunk/lib/Sema/SemaDecl.cpp
Modified: cfe/trunk/include/clang/Basic/Builtins.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Builtins.def?rev=108499&r1=108498&r2=108499&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Builtins.def (original)
+++ cfe/trunk/include/clang/Basic/Builtins.def Thu Jul 15 21:11:15 2010
@@ -66,6 +66,11 @@
// P:N: -> similar to the p:N: attribute, but the function is like vprintf
// in that it accepts its arguments as a va_list rather than
// through an ellipsis
+// s:N: -> this is a scanf-like function whose Nth argument is the format
+// string.
+// S:N: -> similar to the s:N: attribute, but the function is like vscanf
+// in that it accepts its arguments as a va_list rather than
+// through an ellipsis
// e -> const, but only when -fmath-errno=0
// FIXME: gcc has nonnull
@@ -516,6 +521,7 @@
LIBBUILTIN(vfprintf, "i.", "fP:1:", "stdio.h")
LIBBUILTIN(vsnprintf, "ic*zcC*a", "fP:2:", "stdio.h")
LIBBUILTIN(vsprintf, "ic*cC*a", "fP:1:", "stdio.h")
+LIBBUILTIN(scanf, "icC*.", "fs:0:", "stdio.h")
// C99
LIBBUILTIN(longjmp, "vJi", "fr", "setjmp.h")
Modified: cfe/trunk/include/clang/Basic/Builtins.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Builtins.h?rev=108499&r1=108498&r2=108499&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Builtins.h (original)
+++ cfe/trunk/include/clang/Basic/Builtins.h Thu Jul 15 21:11:15 2010
@@ -119,6 +119,11 @@
/// argument and whether this function as a va_list argument.
bool isPrintfLike(unsigned ID, unsigned &FormatIdx, bool &HasVAListArg);
+ /// \brief Determine whether this builtin is like scanf in its
+ /// formatting rules and, if so, set the index to the format string
+ /// argument and whether this function as a va_list argument.
+ bool isScanfLike(unsigned ID, unsigned &FormatIdx, bool &HasVAListArg);
+
/// hasVAListUse - Return true of the specified builtin uses __builtin_va_list
/// as an operand or return type.
bool hasVAListUse(unsigned ID) const {
Modified: cfe/trunk/lib/Basic/Builtins.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Builtins.cpp?rev=108499&r1=108498&r2=108499&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/Builtins.cpp (original)
+++ cfe/trunk/lib/Basic/Builtins.cpp Thu Jul 15 21:11:15 2010
@@ -93,3 +93,23 @@
return true;
}
+// FIXME: Refactor with isPrintfLike.
+bool
+Builtin::Context::isScanfLike(unsigned ID, unsigned &FormatIdx,
+ bool &HasVAListArg) {
+ const char *Scanf = strpbrk(GetRecord(ID).Attributes, "sS");
+ if (!Scanf)
+ return false;
+
+ HasVAListArg = (*Scanf == 'S');
+
+ ++Scanf;
+ assert(*Scanf == ':' && "s or S specifier must have be followed by a ':'");
+ ++Scanf;
+
+ assert(strchr(Scanf, ':') && "printf specifier must end with a ':'");
+ FormatIdx = strtol(Scanf, 0, 10);
+ return true;
+}
+
+
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=108499&r1=108498&r2=108499&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Jul 15 21:11:15 2010
@@ -4905,6 +4905,12 @@
FD->addAttr(::new (Context) FormatAttr(Context, "printf", FormatIdx+1,
HasVAListArg ? 0 : FormatIdx+2));
}
+ if (Context.BuiltinInfo.isScanfLike(BuiltinID, FormatIdx,
+ HasVAListArg)) {
+ if (!FD->getAttr<FormatAttr>())
+ FD->addAttr(::new (Context) FormatAttr(Context, "scanf", FormatIdx+1,
+ HasVAListArg ? 0 : FormatIdx+2));
+ }
// Mark const if we don't care about errno and that is the only
// thing preventing the function from being const. This allows
More information about the cfe-commits
mailing list