From: Aaron Ballman Date: Tue, 3 Sep 2013 21:02:22 +0000 (+0000) Subject: Switched FormatAttr to using an IdentifierArgument instead of a StringArgument since... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=caa5ab264ddea332e8423af1ebcea50d0cb37206;p=clang Switched FormatAttr to using an IdentifierArgument instead of a StringArgument since that is a more accurate modeling. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@189851 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td index 9d5f414394..5e0ecdb16a 100644 --- a/include/clang/Basic/Attr.td +++ b/include/clang/Basic/Attr.td @@ -382,7 +382,7 @@ def MinSize : InheritableAttr { def Format : InheritableAttr { let Spellings = [GNU<"format">, CXX11<"gnu", "format">]; - let Args = [StringArgument<"Type">, IntArgument<"FormatIdx">, + let Args = [IdentifierArgument<"Type">, IntArgument<"FormatIdx">, IntArgument<"FirstArg">]; } diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 03c88be75e..553a86faff 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -1840,9 +1840,9 @@ public: unsigned AttrSpellingListIndex); DLLExportAttr *mergeDLLExportAttr(Decl *D, SourceRange Range, unsigned AttrSpellingListIndex); - FormatAttr *mergeFormatAttr(Decl *D, SourceRange Range, StringRef Format, - int FormatIdx, int FirstArg, - unsigned AttrSpellingListIndex); + FormatAttr *mergeFormatAttr(Decl *D, SourceRange Range, + IdentifierInfo *Format, int FormatIdx, + int FirstArg, unsigned AttrSpellingListIndex); SectionAttr *mergeSectionAttr(Decl *D, SourceRange Range, StringRef Name, unsigned AttrSpellingListIndex); diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index 499c21c7bc..82eca73e8c 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -2141,7 +2141,7 @@ Sema::CheckNonNullArguments(const NonNullAttr *NonNull, } Sema::FormatStringType Sema::GetFormatStringType(const FormatAttr *Format) { - return llvm::StringSwitch(Format->getType()) + return llvm::StringSwitch(Format->getType()->getName()) .Case("scanf", FST_Scanf) .Cases("printf", "printf0", FST_Printf) .Cases("NSString", "CFString", FST_NSString) diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index b6032339f7..78942afcc9 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -9755,7 +9755,8 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) { FD->getParamDecl(FormatIdx)->getType()->isObjCObjectPointerType()) fmt = "NSString"; FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), Context, - fmt, FormatIdx+1, + &Context.Idents.get(fmt), + FormatIdx+1, HasVAListArg ? 0 : FormatIdx+2)); } } @@ -9763,7 +9764,8 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) { HasVAListArg)) { if (!FD->getAttr()) FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), Context, - "scanf", FormatIdx+1, + &Context.Idents.get("scanf"), + FormatIdx+1, HasVAListArg ? 0 : FormatIdx+2)); } @@ -9803,7 +9805,7 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) { // target-specific builtins, perhaps? if (!FD->getAttr()) FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), Context, - "printf", 2, + &Context.Idents.get("printf"), 2, Name->isStr("vasprintf") ? 0 : 3)); } diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index cc4f107aeb..97d12d57dc 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -3177,8 +3177,9 @@ static void handleInitPriorityAttr(Sema &S, Decl *D, Attr.getAttributeSpellingListIndex())); } -FormatAttr *Sema::mergeFormatAttr(Decl *D, SourceRange Range, StringRef Format, - int FormatIdx, int FirstArg, +FormatAttr *Sema::mergeFormatAttr(Decl *D, SourceRange Range, + IdentifierInfo *Format, int FormatIdx, + int FirstArg, unsigned AttrSpellingListIndex) { // Check whether we already have an equivalent format attribute. for (specific_attr_iterator @@ -3197,8 +3198,8 @@ FormatAttr *Sema::mergeFormatAttr(Decl *D, SourceRange Range, StringRef Format, } } - return ::new (Context) FormatAttr(Range, Context, Format, FormatIdx, FirstArg, - AttrSpellingListIndex); + return ::new (Context) FormatAttr(Range, Context, Format, FormatIdx, + FirstArg, AttrSpellingListIndex); } /// Handle __attribute__((format(type,idx,firstarg))) attributes based on @@ -3229,8 +3230,11 @@ static void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) { StringRef Format = II->getName(); // Normalize the argument, __foo__ becomes foo. - if (Format.startswith("__") && Format.endswith("__")) + if (Format.startswith("__") && Format.endswith("__")) { Format = Format.substr(2, Format.size() - 4); + // If we've modified the string name, we need a new identifier for it. + II = &S.Context.Idents.get(Format); + } // Check for supported formats. FormatAttrKind Kind = getFormatAttrKind(Format); @@ -3336,7 +3340,7 @@ static void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) { return; } - FormatAttr *NewAttr = S.mergeFormatAttr(D, Attr.getRange(), Format, + FormatAttr *NewAttr = S.mergeFormatAttr(D, Attr.getRange(), II, Idx.getZExtValue(), FirstArg.getZExtValue(), Attr.getAttributeSpellingListIndex()); diff --git a/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp b/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp index c67c597fec..1dc60c6dbd 100644 --- a/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp @@ -619,7 +619,8 @@ static bool getPrintfFormatArgumentNum(const CallExpr *CE, const FormatAttr *Format = *i; ArgNum = Format->getFormatIdx() - 1; - if ((Format->getType() == "printf") && CE->getNumArgs() > ArgNum) + if ((Format->getType()->getName() == "printf") && + CE->getNumArgs() > ArgNum) return true; } diff --git a/test/SemaCXX/cxx11-attr-print.cpp b/test/SemaCXX/cxx11-attr-print.cpp index c82e5d2484..01325d3c8b 100644 --- a/test/SemaCXX/cxx11-attr-print.cpp +++ b/test/SemaCXX/cxx11-attr-print.cpp @@ -52,7 +52,7 @@ inline void f6() __attribute__((gnu_inline)); inline void f7 [[gnu::gnu_inline]] (); // arguments printing -// CHECK: __attribute__((format("printf", 2, 3))); +// CHECK: __attribute__((format(printf, 2, 3))); void f8 (void *, const char *, ...) __attribute__ ((format (printf, 2, 3))); // CHECK: int m __attribute__((aligned(4 diff --git a/utils/TableGen/ClangAttrEmitter.cpp b/utils/TableGen/ClangAttrEmitter.cpp index e8312c6a04..fdc4904f3c 100644 --- a/utils/TableGen/ClangAttrEmitter.cpp +++ b/utils/TableGen/ClangAttrEmitter.cpp @@ -1005,6 +1005,7 @@ void EmitClangAttrExprArgsList(RecordKeeper &Records, raw_ostream &OS) { .Case("DefaultIntArgument", true) .Case("IntArgument", true) .Case("ExprArgument", true) + .Case("StringArgument", true) .Case("UnsignedArgument", true) .Case("VariadicUnsignedArgument", true) .Case("VariadicExprArgument", true)