-
Notifications
You must be signed in to change notification settings - Fork 15.4k
[clang] Fix string literal parsing on some attributes #171017
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
At the time ParseAttributeArgumentList is called, the first argument of an attribute may have already been parsed. We need to take this into account when accessing ParsedAttributeArgumentsProperties mask, which specifies which of the attribute arguments are string literals.
|
@llvm/pr-subscribers-clang Author: Sergei Barannikov (s-barannikov) ChangesAt the time ParseAttributeArgumentList is called, the first argument Full diff: https://github.com/llvm/llvm-project/pull/171017.diff 3 Files Affected:
diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index 58eb1c0a7c114..e51ae9bfa37c3 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -2117,10 +2117,9 @@ class Parser : public CodeCompletionHandler {
ExprResult ParseUnevaluatedStringInAttribute(const IdentifierInfo &AttrName);
- bool
- ParseAttributeArgumentList(const clang::IdentifierInfo &AttrName,
- SmallVectorImpl<Expr *> &Exprs,
- ParsedAttributeArgumentsProperties ArgsProperties);
+ bool parseAttributeArgumentList(
+ const IdentifierInfo &AttrName, SmallVectorImpl<Expr *> &Exprs,
+ ParsedAttributeArgumentsProperties ArgsProperties, unsigned Arg);
/// Parses syntax-generic attribute arguments for attributes which are
/// known to the implementation, and adds them to the given ParsedAttributes
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 8688ccf41acb5..26a1f7c0a5b93 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -421,11 +421,10 @@ Parser::ParseUnevaluatedStringInAttribute(const IdentifierInfo &AttrName) {
return ParseUnevaluatedStringLiteralExpression();
}
-bool Parser::ParseAttributeArgumentList(
+bool Parser::parseAttributeArgumentList(
const IdentifierInfo &AttrName, SmallVectorImpl<Expr *> &Exprs,
- ParsedAttributeArgumentsProperties ArgsProperties) {
+ ParsedAttributeArgumentsProperties ArgsProperties, unsigned Arg) {
bool SawError = false;
- unsigned Arg = 0;
while (true) {
ExprResult Expr;
if (ArgsProperties.isStringLiteralArg(Arg)) {
@@ -580,7 +579,8 @@ unsigned Parser::ParseAttributeArgsCommon(
ParsedAttributeArgumentsProperties ArgProperties =
attributeStringLiteralListArg(getTargetInfo().getTriple(), *AttrName,
Form.getSyntax(), ScopeName);
- if (ParseAttributeArgumentList(*AttrName, ParsedExprs, ArgProperties)) {
+ if (parseAttributeArgumentList(*AttrName, ParsedExprs, ArgProperties,
+ ArgExprs.size())) {
SkipUntil(tok::r_paren, StopAtSemi);
return 0;
}
diff --git a/clang/test/Sema/attr-modular-format.c b/clang/test/Sema/attr-modular-format.c
index fc5b28b0b88be..b7ae519cedbeb 100644
--- a/clang/test/Sema/attr-modular-format.c
+++ b/clang/test/Sema/attr-modular-format.c
@@ -3,6 +3,9 @@
int printf(const char *fmt, ...) __attribute__((modular_format(__modular_printf, "__printf", "float"))); // no-error
int myprintf(const char *fmt, ...) __attribute__((modular_format(__modular_printf, "__printf", "float"))); // expected-error {{'modular_format' attribute requires 'format' attribute}}
+int lprintf(const char *fmt, ...) __attribute__((modular_format(__modular_printf, L"__printf", L"float"), format(printf, 1, 2)));
+// expected-warning@-1 2{{encoding prefix 'L' on an unevaluated string literal has no effect}}
+
int dupe(const char *fmt, ...) __attribute__((modular_format(__modular_printf, "__printf", "float", "int", "float"), format(printf, 1, 2))); // expected-error {{duplicate aspect 'float' in 'modular_format' attribute}}
int multi_dupe(const char *fmt, ...) __attribute__((modular_format(__modular_printf, "__printf", "float", "int", "float", "int"), format(printf, 1, 2))); // expected-error {{duplicate aspect 'float' in 'modular_format' attribute}} \
// expected-error {{duplicate aspect 'int' in 'modular_format' attribute}}
|
| ParseAttributeArgumentList(const clang::IdentifierInfo &AttrName, | ||
| SmallVectorImpl<Expr *> &Exprs, | ||
| ParsedAttributeArgumentsProperties ArgsProperties); | ||
| bool parseAttributeArgumentList( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The other nearby attribute functions are generally going with an initial capital letter; probably should stick with the nearby formatting instead of changing it for just one API.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we're going this route, I think we should document the arguments. It's not going to be clear what the Arg parameter is for.
At the time ParseAttributeArgumentList is called, the first argument
of an attribute may have already been parsed. We need to take this into
account when accessing ParsedAttributeArgumentsProperties mask, which
specifies which of the attribute arguments are string literals.