diff --git a/lib/Parse/ParsePragma.cpp b/lib/Parse/ParsePragma.cpp index 8c3fb7a56950b9da6ff38986e52a8d78441d4c65..473be5467eeb0345f88b6f3e2fc9664f410c6045 100644 --- a/lib/Parse/ParsePragma.cpp +++ b/lib/Parse/ParsePragma.cpp @@ -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; diff --git a/test/CodeGenCXX/sections.cpp b/test/CodeGenCXX/sections.cpp index ba2c1255f7a0561c44377b98437e3ab5f8bd537d..f84f9d939c0bed34bd8c5c9ea954705dc236f36b 100644 --- a/test/CodeGenCXX/sections.cpp +++ b/test/CodeGenCXX/sections.cpp @@ -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"