Parse: Ignore "long" and "short" in #pragma section
authorDavid Majnemer <david.majnemer@gmail.com>
Wed, 22 Oct 2014 21:08:43 +0000 (21:08 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Wed, 22 Oct 2014 21:08:43 +0000 (21:08 +0000)
This fixes PR21337.

llvm-svn: 220429

clang/lib/Parse/ParsePragma.cpp
clang/test/CodeGenCXX/sections.cpp

index 8c3fb7a..473be54 100644 (file)
@@ -532,9 +532,18 @@ bool Parser::HandlePragmaMSSection(StringRef PragmaName,
         << PragmaName;
     return false;
   }
-  int SectionFlags = 0;
+  int SectionFlags = ASTContext::PSF_Read;
+  bool SectionFlagsAreDefault = true;
   while (Tok.is(tok::comma)) {
     PP.Lex(Tok); // ,
+    // Ignore "long" and "short".
+    // They are undocumented, but widely used, section attributes which appear
+    // to do nothing.
+    if (Tok.is(tok::kw_long) || Tok.is(tok::kw_short)) {
+      PP.Lex(Tok); // long/short
+      continue;
+    }
+
     if (!Tok.isAnyIdentifier()) {
       PP.Diag(PragmaLocation, diag::warn_pragma_expected_action_or_r_paren)
           << PragmaName;
@@ -560,8 +569,13 @@ bool Parser::HandlePragmaMSSection(StringRef PragmaName,
       return false;
     }
     SectionFlags |= Flag;
+    SectionFlagsAreDefault = false;
     PP.Lex(Tok); // Identifier
   }
+  // If no section attributes are specified, the section will be marked as
+  // read/write.
+  if (SectionFlagsAreDefault)
+    SectionFlags |= ASTContext::PSF_Write;
   if (Tok.isNot(tok::r_paren)) {
     PP.Diag(PragmaLocation, diag::warn_pragma_expected_rparen) << PragmaName;
     return false;
index ba2c125..f84f9d9 100644 (file)
@@ -38,6 +38,17 @@ __declspec(allocate("read_flag_section")) int unreferenced = 0;
 extern __declspec(allocate("read_flag_section")) int referenced = 42;
 int *user() { return &referenced; }
 
+#pragma section("no_section_attributes")
+// A pragma section with no section attributes is read/write.
+__declspec(allocate("no_section_attributes")) int implicitly_read_write = 42;
+
+#pragma section("long_section", long)
+// Pragma section ignores "long".
+__declspec(allocate("long_section")) long long_var = 42;
+
+#pragma section("short_section", short)
+// Pragma section ignores "short".
+__declspec(allocate("short_section")) short short_var = 42;
 }
 
 //CHECK: @D = global i32 1
@@ -54,5 +65,8 @@ int *user() { return &referenced; }
 //CHECK: @TEST2 = global i32 0, section ".bss1"
 //CHECK: @unreferenced = constant i32 0, section "read_flag_section"
 //CHECK: @referenced = constant i32 42, section "read_flag_section"
+//CHECK: @implicitly_read_write = global i32 42, section "no_section_attributes"
+//CHECK: @long_var = global i32 42, section "long_section"
+//CHECK: @short_var = global i16 42, section "short_section"
 //CHECK: define void @g()
 //CHECK: define void @h() {{.*}} section ".my_code"