From 48c28fa6db071750afb134a2841c98993a7c48da Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Wed, 22 Oct 2014 21:08:43 +0000 Subject: [PATCH] Parse: Ignore "long" and "short" in #pragma section This fixes PR21337. llvm-svn: 220429 --- clang/lib/Parse/ParsePragma.cpp | 16 +++++++++++++++- clang/test/CodeGenCXX/sections.cpp | 14 ++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp index 8c3fb7a..473be54 100644 --- a/clang/lib/Parse/ParsePragma.cpp +++ b/clang/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/clang/test/CodeGenCXX/sections.cpp b/clang/test/CodeGenCXX/sections.cpp index ba2c125..f84f9d9 100644 --- a/clang/test/CodeGenCXX/sections.cpp +++ b/clang/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" -- 2.7.4