Author: Sergei Barannikov
Date: 2026-01-09T16:37:03+03:00
New Revision: 7eae17e4c40c7c7b42dc9b5ccd18ab4a28a7ad28

URL: 
https://github.com/llvm/llvm-project/commit/7eae17e4c40c7c7b42dc9b5ccd18ab4a28a7ad28
DIFF: 
https://github.com/llvm/llvm-project/commit/7eae17e4c40c7c7b42dc9b5ccd18ab4a28a7ad28.diff

LOG: [clang] Fix string literal parsing on some attributes (#171017)

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.

Pull Request: https://github.com/llvm/llvm-project/pull/171017

Added: 
    

Modified: 
    clang/include/clang/Parse/Parser.h
    clang/lib/Parse/ParseDecl.cpp
    clang/test/Sema/attr-modular-format.c

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Parse/Parser.h 
b/clang/include/clang/Parse/Parser.h
index 9d21c507959f1..f7e7b0ec51d80 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -2117,10 +2117,14 @@ class Parser : public CodeCompletionHandler {
 
   ExprResult ParseUnevaluatedStringInAttribute(const IdentifierInfo &AttrName);
 
-  bool
-  ParseAttributeArgumentList(const clang::IdentifierInfo &AttrName,
-                             SmallVectorImpl<Expr *> &Exprs,
-                             ParsedAttributeArgumentsProperties 
ArgsProperties);
+  /// Parses a comma-delimited list of arguments of an attribute \p AttrName,
+  /// filling \p Exprs. \p ArgsProperties specifies which of the arguments
+  /// should be parsed as unevaluated string literals. \p Arg is the number
+  /// of arguments parsed before calling / this function (the index of the
+  /// argument to be parsed next).
+  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 0e2caa214f3fd..f8c49646fcf3f 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -423,9 +423,8 @@ Parser::ParseUnevaluatedStringInAttribute(const 
IdentifierInfo &AttrName) {
 
 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}}


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to