[clang] a7eaaba - [Parser] Parse string literal arguments of 'availability', 'external_source_symbol' and 'uuid' attributes as unevaluated

Sergei Barannikov via cfe-commits cfe-commits at lists.llvm.org
Wed Aug 30 01:47:05 PDT 2023


Author: Sergei Barannikov
Date: 2023-08-30T11:46:54+03:00
New Revision: a7eaaba69906d3305752cb738332b9365e666def

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

LOG: [Parser] Parse string literal arguments of 'availability', 'external_source_symbol' and 'uuid' attributes as unevaluated

This is a complementary to D156237.
These attributes have custom parsing logic.

Reviewed By: cor3ntin

Differential Revision: https://reviews.llvm.org/D159024

Added: 
    

Modified: 
    clang/lib/Parse/ParseDecl.cpp
    clang/lib/Parse/ParseDeclCXX.cpp
    clang/test/Parser/attr-availability-xcore.c
    clang/test/Parser/attr-availability.c
    clang/test/Parser/attr-external-source-symbol.m
    clang/test/Parser/ms-square-bracket-attributes.mm

Removed: 
    


################################################################################
diff  --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 8daa33a2a7b5b8..7c27a02ee4af62 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -1316,31 +1316,19 @@ void Parser::ParseAvailabilityAttribute(
     }
     ConsumeToken();
     if (Keyword == Ident_message || Keyword == Ident_replacement) {
-      if (Tok.isNot(tok::string_literal)) {
+      if (!isTokenStringLiteral()) {
         Diag(Tok, diag::err_expected_string_literal)
           << /*Source='availability attribute'*/2;
         SkipUntil(tok::r_paren, StopAtSemi);
         return;
       }
-      if (Keyword == Ident_message)
-        MessageExpr = ParseStringLiteralExpression();
-      else
-        ReplacementExpr = ParseStringLiteralExpression();
-      // Also reject wide string literals.
-      if (StringLiteral *MessageStringLiteral =
-              cast_or_null<StringLiteral>(MessageExpr.get())) {
-        if (!MessageStringLiteral->isOrdinary()) {
-          Diag(MessageStringLiteral->getSourceRange().getBegin(),
-               diag::err_expected_string_literal)
-            << /*Source='availability attribute'*/ 2;
-          SkipUntil(tok::r_paren, StopAtSemi);
-          return;
-        }
-      }
-      if (Keyword == Ident_message)
+      if (Keyword == Ident_message) {
+        MessageExpr = ParseUnevaluatedStringLiteralExpression();
         break;
-      else
+      } else {
+        ReplacementExpr = ParseUnevaluatedStringLiteralExpression();
         continue;
+      }
     }
 
     // Special handling of 'NA' only when applied to introduced or
@@ -1508,7 +1496,7 @@ void Parser::ParseExternalSourceSymbolAttribute(
     else
       HasDefinedIn = true;
 
-    if (Tok.isNot(tok::string_literal)) {
+    if (!isTokenStringLiteral()) {
       Diag(Tok, diag::err_expected_string_literal)
           << /*Source='external_source_symbol attribute'*/ 3
           << /*language | source container | USR*/ (
@@ -1522,27 +1510,27 @@ void Parser::ParseExternalSourceSymbolAttribute(
       if (HadLanguage) {
         Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
             << Keyword;
-        ParseStringLiteralExpression();
+        ParseUnevaluatedStringLiteralExpression();
         continue;
       }
-      Language = ParseStringLiteralExpression();
+      Language = ParseUnevaluatedStringLiteralExpression();
     } else if (Keyword == Ident_USR) {
       if (HadUSR) {
         Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
             << Keyword;
-        ParseStringLiteralExpression();
+        ParseUnevaluatedStringLiteralExpression();
         continue;
       }
-      USR = ParseStringLiteralExpression();
+      USR = ParseUnevaluatedStringLiteralExpression();
     } else {
       assert(Keyword == Ident_defined_in && "Invalid clause keyword!");
       if (HadDefinedIn) {
         Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
             << Keyword;
-        ParseStringLiteralExpression();
+        ParseUnevaluatedStringLiteralExpression();
         continue;
       }
-      DefinedInExpr = ParseStringLiteralExpression();
+      DefinedInExpr = ParseUnevaluatedStringLiteralExpression();
     }
   } while (TryConsumeToken(tok::comma));
 

diff  --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index 186a5e61a8fa32..730b6e55246d6b 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -4715,9 +4715,9 @@ void Parser::ParseMicrosoftUuidAttributeArgs(ParsedAttributes &Attrs) {
   }
 
   ArgsVector ArgExprs;
-  if (Tok.is(tok::string_literal)) {
+  if (isTokenStringLiteral()) {
     // Easy case: uuid("...") -- quoted string.
-    ExprResult StringResult = ParseStringLiteralExpression();
+    ExprResult StringResult = ParseUnevaluatedStringLiteralExpression();
     if (StringResult.isInvalid())
       return;
     ArgExprs.push_back(StringResult.get());
@@ -4772,7 +4772,7 @@ void Parser::ParseMicrosoftUuidAttributeArgs(ParsedAttributes &Attrs) {
     Toks[0].setLiteralData(StrBuffer.data());
     Toks[0].setLength(StrBuffer.size());
     StringLiteral *UuidString =
-        cast<StringLiteral>(Actions.ActOnStringLiteral(Toks, nullptr).get());
+        cast<StringLiteral>(Actions.ActOnUnevaluatedStringLiteral(Toks).get());
     ArgExprs.push_back(UuidString);
   }
 

diff  --git a/clang/test/Parser/attr-availability-xcore.c b/clang/test/Parser/attr-availability-xcore.c
index 0b354a3d01e805..6bc1f45c8ed9fa 100644
--- a/clang/test/Parser/attr-availability-xcore.c
+++ b/clang/test/Parser/attr-availability-xcore.c
@@ -6,6 +6,6 @@
 #  error 'availability' attribute is not available
 #endif
 
-void f7() __attribute__((availability(macosx,message=L"wide"))); // expected-error {{expected string literal for optional message in 'availability' attribute}}
+void f7() __attribute__((availability(macosx,message=L"wide"))); // expected-warning {{encoding prefix 'L' on an unevaluated string literal has no effect}}
 
-void f8() __attribute__((availability(macosx,message="a" L"b"))); // expected-error {{expected string literal for optional message in 'availability' attribute}}
+void f8() __attribute__((availability(macosx,message="a" L"b"))); // expected-warning {{encoding prefix 'L' on an unevaluated string literal has no effect}}

diff  --git a/clang/test/Parser/attr-availability.c b/clang/test/Parser/attr-availability.c
index 71e80bd0b29f59..aab0f2f3a852a9 100644
--- a/clang/test/Parser/attr-availability.c
+++ b/clang/test/Parser/attr-availability.c
@@ -18,17 +18,17 @@ void f5(void) __attribute__((availability(macosx,introduced=10.5), availability(
 
 void f6(void) __attribute__((availability(macosx,unavailable,introduced=10.5))); // expected-warning{{'unavailable' availability overrides all other availability information}}
 
-void f7(void) __attribute__((availability(macosx,message=L"wide"))); // expected-error {{expected string literal for optional message in 'availability' attribute}}
+void f7(void) __attribute__((availability(macosx,message=L"wide"))); // expected-warning {{encoding prefix 'L' on an unevaluated string literal has no effect}}
 
-void f8(void) __attribute__((availability(macosx,message="a" L"b"))); // expected-error {{expected string literal for optional message in 'availability' attribute}}
+void f8(void) __attribute__((availability(macosx,message="a" L"b"))); // expected-warning {{encoding prefix 'L' on an unevaluated string literal has no effect}}
 
-void f9(void) __attribute__((availability(macosx,message=u8"b"))); // expected-error {{expected string literal for optional message in 'availability' attribute}}
+void f9(void) __attribute__((availability(macosx,message=u8"b"))); // expected-warning {{encoding prefix 'u8' on an unevaluated string literal has no effect}}
 
-void f10(void) __attribute__((availability(macosx,message="a" u8"b"))); // expected-error {{expected string literal for optional message in 'availability' attribute}}
+void f10(void) __attribute__((availability(macosx,message="a" u8"b"))); // expected-warning {{encoding prefix 'u8' on an unevaluated string literal has no effect}}
 
-void f11(void) __attribute__((availability(macosx,message=u"b"))); // expected-error {{expected string literal for optional message in 'availability' attribute}}
+void f11(void) __attribute__((availability(macosx,message=u"b"))); // expected-warning {{encoding prefix 'u' on an unevaluated string literal has no effect}}
 
-void f12(void) __attribute__((availability(macosx,message="a" u"b"))); // expected-error {{expected string literal for optional message in 'availability' attribute}}
+void f12(void) __attribute__((availability(macosx,message="a" u"b"))); // expected-warning {{encoding prefix 'u' on an unevaluated string literal has no effect}}
 
 enum E{
     gorf __attribute__((availability(macosx,introduced=8.5, message = 10.0))), // expected-error {{expected string literal for optional message in 'availability' attribute}}

diff  --git a/clang/test/Parser/attr-external-source-symbol.m b/clang/test/Parser/attr-external-source-symbol.m
index b94cb3a628145f..329c820371f1d1 100644
--- a/clang/test/Parser/attr-external-source-symbol.m
+++ b/clang/test/Parser/attr-external-source-symbol.m
@@ -95,6 +95,27 @@ void f27(void)
 void f28(void)
 __attribute__((external_source_symbol(USR="")));
 
+void f29(void)
+__attribute__((external_source_symbol(language=L"Swift"))); // expected-warning {{encoding prefix 'L' on an unevaluated string literal has no effect}}
+
+void f30(void)
+__attribute__((external_source_symbol(language="Swift", language=L"Swift"))); // expected-error {{duplicate 'language' clause in an 'external_source_symbol' attribute}} \
+                                                                              // expected-warning {{encoding prefix 'L' on an unevaluated string literal has no effect}}
+
+void f31(void)
+__attribute__((external_source_symbol(USR=u"foo"))); // expected-warning {{encoding prefix 'u' on an unevaluated string literal has no effect}}
+
+void f32(void)
+__attribute__((external_source_symbol(USR="foo", USR=u"foo"))); // expected-error {{duplicate 'USR' clause in an 'external_source_symbol' attribute}} \
+                                                                // expected-warning {{encoding prefix 'u' on an unevaluated string literal has no effect}}
+
+void f33(void)
+__attribute__((external_source_symbol(defined_in=U"module"))); // expected-warning {{encoding prefix 'U' on an unevaluated string literal has no effect}}
+
+void f34(void)
+__attribute__((external_source_symbol(defined_in="module", defined_in=U"module"))); // expected-error {{duplicate 'defined_in' clause in an 'external_source_symbol' attribute}} \
+                                                                                    // expected-warning {{encoding prefix 'U' on an unevaluated string literal has no effect}}
+
 #if __has_attribute(external_source_symbol) != 20230206
 # error "invalid __has_attribute version"
 #endif

diff  --git a/clang/test/Parser/ms-square-bracket-attributes.mm b/clang/test/Parser/ms-square-bracket-attributes.mm
index c1fc14cec563d3..6c4923dfa43310 100644
--- a/clang/test/Parser/ms-square-bracket-attributes.mm
+++ b/clang/test/Parser/ms-square-bracket-attributes.mm
@@ -17,9 +17,9 @@
 )] struct struct_with_uuid_brace;
 
 // uuids must be ascii string literals.
-// expected-error at +1 {{uuid attribute contains a malformed GUID}}
+// expected-warning at +1 {{encoding prefix 'u8' on an unevaluated string literal has no effect and is incompatible with c++2c}}
 [uuid(u8"000000A0-0000-0000-C000-000000000049")] struct struct_with_uuid_u8;
-// expected-error at +1 {{uuid attribute contains a malformed GUID}}
+// expected-warning at +1 {{encoding prefix 'L' on an unevaluated string literal has no effect and is incompatible with c++2c}}
 [uuid(L"000000A0-0000-0000-C000-000000000049")] struct struct_with_uuid_L;
 
 // cl.exe doesn't allow raw string literals in []-style attributes, but does


        


More information about the cfe-commits mailing list