diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Basic/Builtins.cpp | 20 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 6 |
2 files changed, 26 insertions, 0 deletions
diff --git a/lib/Basic/Builtins.cpp b/lib/Basic/Builtins.cpp index 1a3293775e..040cdb5d55 100644 --- a/lib/Basic/Builtins.cpp +++ b/lib/Basic/Builtins.cpp @@ -93,3 +93,23 @@ Builtin::Context::isPrintfLike(unsigned ID, unsigned &FormatIdx, 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; +} + + diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index c1c898fac5..76cb90565b 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -4905,6 +4905,12 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) { 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 |