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 &Exprs, - ParsedAttributeArgumentsProperties ArgsProperties); + bool parseAttributeArgumentList( + const IdentifierInfo &AttrName, SmallVectorImpl &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 &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}}