[PATCH] D27165: Add format_dynamic_key_arg attribute to improve "-Wformat" warnings for functions that load the formatting string dynamically based on a key value
Aaron Ballman via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Mon Dec 19 12:52:08 PST 2016
aaron.ballman added inline comments.
================
Comment at: include/clang/Basic/Attr.td:862
+def FormatDynamicKeyArg : InheritableAttr {
+ let Spellings = [GCC<"format_dynamic_key_arg">];
+ let Args = [IntArgument<"FormatIdx">];
----------------
arphaman wrote:
> aaron.ballman wrote:
> > Does GCC support this attribute as well? If not, this should use the GNU spelling instead of the GCC one. Also, should this have a C++11 spelling in the clang namespace?
> >
> > The name doesn't really convey much about what the attribute is doing, mostly because it doesn't seem obvious what "key" means.
> >
> > It seems that the crux of what this attribute says is that the attributed function accepts a string argument of a format specifier and returns the same format specifier. Perhaps `returns_format_specifier` is a better name?
> > Does GCC support this attribute as well? If not, this should use the GNU spelling instead of the GCC one.
>
> No, it doesn't. Thanks for pointing that out, I fixed it.
>
> > Also, should this have a C++11 spelling in the clang namespace?
>
> I don't know, is that required for new attributes? I don't need the C++11 spelling personally, and I don't know if there is anyone else who's interested in this attribute.
>
> > The name doesn't really convey much about what the attribute is doing, mostly because it doesn't seem obvious what "key" means.
> >
> > It seems that the crux of what this attribute says is that the attributed function accepts a string argument of a format specifier and returns the same format specifier. Perhaps returns_format_specifier is a better name?
>
> You're right, the name should convey the intended meaning better. I switched to `loads_format_specifier_value_using_key`, how does that sound?
> I think it sounds better than just `returns_format_specifier` because I would like to see this attribute used only for a particular kind of function. This kind of function should load the value at runtime using the key from a platform-specific file/database that might also be accessible at compile-time. It shouldn't be used for functions that might just modify the given key, which, IMO, `returns_format_specifier` can imply.
>> Also, should this have a C++11 spelling in the clang namespace?
> I don't know, is that required for new attributes? I don't need the C++11 spelling personally, and I don't know if there is anyone else who's interested in this attribute.
It's not required, but not everyone likes GNU-style attributes, so having something a bit less awful is a kindness.
>> The name doesn't really convey much about what the attribute is doing, mostly because it doesn't seem obvious what "key" means.
>> It seems that the crux of what this attribute says is that the attributed function accepts a string argument of a format specifier and returns the same format specifier. Perhaps returns_format_specifier is a better name?
>You're right, the name should convey the intended meaning better. I switched to loads_format_specifier_value_using_key, how does that sound?
> I think it sounds better than just returns_format_specifier because I would like to see this attribute used only for a particular kind of function. This kind of function should load the value at runtime using the key from a platform-specific file/database that might also be accessible at compile-time. It shouldn't be used for functions that might just modify the given key, which, IMO, returns_format_specifier can imply.
It's a bit wordy, but I think it's better than the original name.
================
Comment at: include/clang/Basic/AttrDocs.td:1759
+function accepts a key string that corresponds to some external ``printf`` or
+``scanf``-like format string value, loads the value that corresponds to the
+given key and returns that value.
----------------
value -> specifier (same below).
================
Comment at: include/clang/Basic/AttrDocs.td:1766
+specifiers found in the key string.
+ }];
+}
----------------
Given that this is uses novel terminology like "key string", I think an example would be useful to add.
The docs should also mention that this attribute accepts an argument, and that the argument is 1-based instead of 0-based (I can't count how many times that's tripped me up).
================
Comment at: lib/Sema/SemaChecking.cpp:4408
+static void CheckFormatString(
+ Sema &S, const FormatStringLiteral *FExpr, const Expr *OrigFormatExpr,
+ ArrayRef<const Expr *> Args, bool HasVAListArg, unsigned format_idx,
----------------
I think the original formatting was easier to read.
================
Comment at: lib/Sema/SemaChecking.cpp:4418
// True string literals are then checked by CheckFormatString.
-static StringLiteralCheckType
-checkFormatStringExpr(Sema &S, const Expr *E, ArrayRef<const Expr *> Args,
- bool HasVAListArg, unsigned format_idx,
- unsigned firstDataArg, Sema::FormatStringType Type,
- Sema::VariadicCallType CallType, bool InFunctionCall,
- llvm::SmallBitVector &CheckedVarArgs,
- UncoveredArgHandler &UncoveredArg,
- llvm::APSInt Offset) {
- tryAgain:
+static StringLiteralCheckType checkFormatStringExpr(
+ Sema &S, const Expr *E, ArrayRef<const Expr *> Args, bool HasVAListArg,
----------------
Same here.
================
Comment at: lib/Sema/SemaChecking.cpp:4593
+ unsigned ArgIndex = FKA->getFormatIdx();
+ if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(ND))
+ if (MD->isInstance())
----------------
Can use `const auto *` here.
================
Comment at: lib/Sema/SemaChecking.cpp:6303
+static void CheckFormatString(
+ Sema &S, const FormatStringLiteral *FExpr, const Expr *OrigFormatExpr,
+ ArrayRef<const Expr *> Args, bool HasVAListArg, unsigned format_idx,
----------------
The original formatting was better.
================
Comment at: test/Sema/attr-format_arg.c:29
+const char *formatKeyArgError2(const char *format)
+ __attribute__((loads_format_specifier_value_using_key(0))); // expected-error{{'loads_format_specifier_value_using_key' attribute parameter 1 is out of bounds}}
----------------
You should also add tests for:
it diagnoses if the attribute is added to something other than a function/method.
it diagnoses if the attribute has no arguments/arguments of the wrong type.
it works properly on a class member function in C++.
Repository:
rL LLVM
https://reviews.llvm.org/D27165
More information about the cfe-commits
mailing list