diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index cd7021a5884b..5f8e7fceabc0 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -2978,6 +2978,7 @@ public: PSF_Write = 0x2, PSF_Execute = 0x4, PSF_Implicit = 0x8, + PSF_ZeroInit = 0x10, PSF_Invalid = 0x80000000U, }; diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp index 828d429e6969..816aaf9f0956 100644 --- a/clang/lib/Parse/ParsePragma.cpp +++ b/clang/lib/Parse/ParsePragma.cpp @@ -1873,6 +1873,7 @@ void PragmaClangSectionHandler::HandlePragma(Preprocessor &PP, return; } + SourceLocation PragmaLocation = Tok.getLocation(); PP.Lex(Tok); // eat ['bss'|'data'|'rodata'|'text'] if (Tok.isNot(tok::equal)) { PP.Diag(Tok.getLocation(), diag::err_pragma_clang_section_expected_equal) << SecKind; @@ -1883,10 +1884,11 @@ void PragmaClangSectionHandler::HandlePragma(Preprocessor &PP, if (!PP.LexStringLiteral(Tok, SecName, "pragma clang section", false)) return; - Actions.ActOnPragmaClangSection(Tok.getLocation(), - (SecName.size()? Sema::PragmaClangSectionAction::PCSA_Set : - Sema::PragmaClangSectionAction::PCSA_Clear), - SecKind, SecName); + Actions.ActOnPragmaClangSection( + PragmaLocation, + (SecName.size() ? Sema::PragmaClangSectionAction::PCSA_Set + : Sema::PragmaClangSectionAction::PCSA_Clear), + SecKind, SecName); } } diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp index 50089dea7759..b5cb96dff44b 100644 --- a/clang/lib/Sema/SemaAttr.cpp +++ b/clang/lib/Sema/SemaAttr.cpp @@ -256,12 +256,15 @@ void Sema::ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind, void Sema::ActOnPragmaClangSection(SourceLocation PragmaLoc, PragmaClangSectionAction Action, PragmaClangSectionKind SecKind, StringRef SecName) { PragmaClangSection *CSec; + int SectionFlags = ASTContext::PSF_Read; switch (SecKind) { case PragmaClangSectionKind::PCSK_BSS: CSec = &PragmaClangBSSSection; + SectionFlags |= ASTContext::PSF_Write | ASTContext::PSF_ZeroInit; break; case PragmaClangSectionKind::PCSK_Data: CSec = &PragmaClangDataSection; + SectionFlags |= ASTContext::PSF_Write; break; case PragmaClangSectionKind::PCSK_Rodata: CSec = &PragmaClangRodataSection; @@ -271,6 +274,7 @@ void Sema::ActOnPragmaClangSection(SourceLocation PragmaLoc, PragmaClangSectionA break; case PragmaClangSectionKind::PCSK_Text: CSec = &PragmaClangTextSection; + SectionFlags |= ASTContext::PSF_Execute; break; default: llvm_unreachable("invalid clang section kind"); @@ -281,6 +285,9 @@ void Sema::ActOnPragmaClangSection(SourceLocation PragmaLoc, PragmaClangSectionA return; } + if (UnifySection(SecName, SectionFlags, PragmaLoc)) + return; + CSec->Valid = true; CSec->SectionName = std::string(SecName); CSec->PragmaLocation = PragmaLoc; diff --git a/clang/test/Sema/pragma-clang-section.c b/clang/test/Sema/pragma-clang-section.c index 38a3bc92744f..97d10f5f11c3 100644 --- a/clang/test/Sema/pragma-clang-section.c +++ b/clang/test/Sema/pragma-clang-section.c @@ -1,5 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s -triple arm-none-eabi -#pragma clang section bss="mybss.1" data="mydata.1" rodata="myrodata.1" text="mytext.1" +#pragma clang section bss = "mybss.1" data = "mydata.1" rodata = "myrodata.1" text = "mytext.1" // expected-note 2 {{#pragma entered here}} #pragma clang section bss="" data="" rodata="" text="" #pragma clang section @@ -16,4 +16,10 @@ #pragma clang section text "text.2" // expected-error {{expected '=' following '#pragma clang section text'}} #pragma clang section relro "relro.2" // expected-error {{expected '=' following '#pragma clang section relro'}} #pragma clang section bss="" data="" rodata="" text="" more //expected-error {{expected one of [bss|data|rodata|text|relro] section kind in '#pragma clang section'}} + +#pragma clang section bss = "mybss.3" data = "mybss.3" // expected-error {{this causes a section type conflict with a prior #pragma section}} expected-note {{#pragma entered here}} expected-note {{#pragma entered here}} +#pragma clang section rodata = "mydata.1" // expected-error {{this causes a section type conflict with a prior #pragma section}} +#pragma clang section bss = "myrodata.1" // expected-error {{this causes a section type conflict with a prior #pragma section}} +#pragma clang section text = "mybss.3" // expected-error {{this causes a section type conflict with a prior #pragma section}} + int a;