diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -3043,8 +3043,15 @@ } SectionAttr *NewAttr = S.mergeSectionAttr(D, AL, Str); - if (NewAttr) + if (NewAttr) { D->addAttr(NewAttr); + if (auto FD = dyn_cast(D)) + if (auto SA = dyn_cast(NewAttr)) + S.UnifySection(SA->getName(), + ASTContext::PSF_Implicit | ASTContext::PSF_Execute | + ASTContext::PSF_Read, + FD); + } } // This is used for `__declspec(code_seg("segname"))` on a decl. diff --git a/clang/test/Sema/attr-section.c b/clang/test/Sema/attr-section.c --- a/clang/test/Sema/attr-section.c +++ b/clang/test/Sema/attr-section.c @@ -26,9 +26,17 @@ // Not a warning. int c; -int c __attribute__((section("foo,zed"))); +int c __attribute__((section("seg1,sec1"))); // Also OK. struct r_debug {}; extern struct r_debug _r_debug; struct r_debug _r_debug __attribute__((nocommon, section(".r_debug,bar"))); + +// Section type conflicts between functions and variables +void test3(void) __attribute__((section("seg2,sec2"))); // expected-note {{declared here}} +void test3(void) {} +const int ro __attribute__((section("seg2,sec2"))) = 10; // expected-error {{'ro' causes a section type conflict with 'test3'}} +void test4(void) __attribute__((section("seg3,sec3"))); // expected-note {{declared here}} +void test4(void) {} +int rw __attribute__((section("seg3,sec3"))) = 10; // expected-error {{'rw' causes a section type conflict with 'test4'}}