Skip to content

Conversation

@s-barannikov
Copy link
Contributor

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.

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.
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Dec 7, 2025
@llvmbot
Copy link
Member

llvmbot commented Dec 7, 2025

@llvm/pr-subscribers-clang

Author: Sergei Barannikov (s-barannikov)

Changes

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.


Full diff: https://github.com/llvm/llvm-project/pull/171017.diff

3 Files Affected:

  • (modified) clang/include/clang/Parse/Parser.h (+3-4)
  • (modified) clang/lib/Parse/ParseDecl.cpp (+4-4)
  • (modified) clang/test/Sema/attr-modular-format.c (+3)
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}}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants