Author: Tomas Matheson Date: 2020-12-17T11:43:47-05:00 New Revision: f50066292477fb26806336e5604615d0eddde399
URL: https://github.com/llvm/llvm-project/commit/f50066292477fb26806336e5604615d0eddde399 DIFF: https://github.com/llvm/llvm-project/commit/f50066292477fb26806336e5604615d0eddde399.diff LOG: Detect section type conflicts between functions and variables If two variables are declared with __attribute__((section(name))) and the implicit section types (e.g. read only vs writeable) conflict, an error is raised. Extend this mechanism so that an error is raised if the section type implied by a function's __attribute__((section)) conflicts with that of another variable. Added: Modified: clang/include/clang/AST/ASTContext.h clang/include/clang/Sema/Sema.h clang/lib/Sema/SemaAttr.cpp clang/lib/Sema/SemaDeclAttr.cpp clang/test/CodeGen/attributes.c clang/test/Sema/attr-section.c clang/test/SemaCXX/attr-section.cpp clang/test/SemaObjC/method-attributes.m Removed: ################################################################################ diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index ff84eb52e96e..0c5d82b3e9aa 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -3086,13 +3086,12 @@ OPT_LIST(V) }; struct SectionInfo { - DeclaratorDecl *Decl; + NamedDecl *Decl; SourceLocation PragmaSectionLocation; int SectionFlags; SectionInfo() = default; - SectionInfo(DeclaratorDecl *Decl, - SourceLocation PragmaSectionLocation, + SectionInfo(NamedDecl *Decl, SourceLocation PragmaSectionLocation, int SectionFlags) : Decl(Decl), PragmaSectionLocation(PragmaSectionLocation), SectionFlags(SectionFlags) {} diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index ff0257634d9d..6b81494e8eff 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -9757,9 +9757,8 @@ class Sema final { PSK_CodeSeg, }; - bool UnifySection(StringRef SectionName, - int SectionFlags, - DeclaratorDecl *TheDecl); + bool UnifySection(StringRef SectionName, int SectionFlags, + NamedDecl *TheDecl); bool UnifySection(StringRef SectionName, int SectionFlags, SourceLocation PragmaSectionLocation); diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp index ae6c3ea7313e..5901bd66b7a6 100644 --- a/clang/lib/Sema/SemaAttr.cpp +++ b/clang/lib/Sema/SemaAttr.cpp @@ -481,9 +481,8 @@ void Sema::ActOnPragmaMSVtorDisp(PragmaMsStackAction Action, VtorDispStack.Act(PragmaLoc, Action, StringRef(), Mode); } -bool Sema::UnifySection(StringRef SectionName, - int SectionFlags, - DeclaratorDecl *Decl) { +bool Sema::UnifySection(StringRef SectionName, int SectionFlags, + NamedDecl *Decl) { SourceLocation PragmaLocation; if (auto A = Decl->getAttr<SectionAttr>()) if (A->isImplicit()) diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 954388dda82e..7750d713f927 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -3081,8 +3081,14 @@ static void handleSectionAttr(Sema &S, Decl *D, const ParsedAttr &AL) { } SectionAttr *NewAttr = S.mergeSectionAttr(D, AL, Str); - if (NewAttr) + if (NewAttr) { D->addAttr(NewAttr); + if (isa<FunctionDecl, FunctionTemplateDecl, ObjCMethodDecl, + ObjCPropertyDecl>(D)) + S.UnifySection(NewAttr->getName(), + ASTContext::PSF_Execute | ASTContext::PSF_Read, + cast<NamedDecl>(D)); + } } // This is used for `__declspec(code_seg("segname"))` on a decl. diff --git a/clang/test/CodeGen/attributes.c b/clang/test/CodeGen/attributes.c index f6323e9be548..0c1455d3c612 100644 --- a/clang/test/CodeGen/attributes.c +++ b/clang/test/CodeGen/attributes.c @@ -63,11 +63,11 @@ void t72() { t71(); } // CHECK: call void @t71() [[COLDSITE:#[0-9]+]] // CHECK: declare void @t71() [[COLDDECL:#[0-9]+]] -// CHECK: define void @t10() [[NUW]] section "SECT" { -void t10(void) __attribute__((section("SECT"))); +// CHECK: define void @t10() [[NUW]] section "xSECT" { +void t10(void) __attribute__((section("xSECT"))); void t10(void) {} -// CHECK: define void @t11() [[NUW]] section "SECT" { -void __attribute__((section("SECT"))) t11(void) {} +// CHECK: define void @t11() [[NUW]] section "xSECT" { +void __attribute__((section("xSECT"))) t11(void) {} // CHECK: define i32 @t19() [[NUW]] { extern int t19(void) __attribute__((weak_import)); diff --git a/clang/test/Sema/attr-section.c b/clang/test/Sema/attr-section.c index bc4247411130..509c9752d8c3 100644 --- a/clang/test/Sema/attr-section.c +++ b/clang/test/Sema/attr-section.c @@ -26,9 +26,27 @@ extern int a __attribute__((section("foo,zed"))); // expected-warning {{section // 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("seg3,sec3"))); // expected-note {{declared here}} +void test3(void) {} +const int const_global_var __attribute__((section("seg3,sec3"))) = 10; // expected-error {{'const_global_var' causes a section type conflict with 'test3'}} + +void test4(void) __attribute__((section("seg4,sec4"))); // expected-note {{declared here}} +void test4(void) {} +int mut_global_var __attribute__((section("seg4,sec4"))) = 10; // expected-error {{'mut_global_var' causes a section type conflict with 'test4'}} + +const int global_seg5sec5 __attribute__((section("seg5,sec5"))) = 10; // expected-note {{declared here}} +void test5(void) __attribute__((section("seg5,sec5"))); // expected-error {{'test5' causes a section type conflict with 'global_seg5sec5'}} +void test5(void) {} + +void test6(void); +const int global_seg6sec6 __attribute__((section("seg6,sec6"))) = 10; // expected-note {{declared here}} +void test6(void) __attribute__((section("seg6,sec6"))); // expected-error {{'test6' causes a section type conflict with 'global_seg6sec6'}} +void test6(void) {} diff --git a/clang/test/SemaCXX/attr-section.cpp b/clang/test/SemaCXX/attr-section.cpp index cc80989d22bf..12c0da283997 100644 --- a/clang/test/SemaCXX/attr-section.cpp +++ b/clang/test/SemaCXX/attr-section.cpp @@ -42,3 +42,9 @@ namespace override { __attribute__((section("baz"))) // expected-warning {{section does not match}} void C::f() {} } + +// Check for section type conflicts between global variables and function templates +template <typename> __attribute__((section("template_fn1"))) void template_fn1() {} // expected-note {{declared here}} +const int const_global_var __attribute__((section("template_fn1"))) = 42; // expected-error {{'const_global_var' causes a section type conflict with 'template_fn1'}} +int mut_global_var __attribute__((section("template_fn2"))) = 42; // expected-note {{declared here}} +template <typename> __attribute__((section("template_fn2"))) void template_fn2() {} // expected-error {{'template_fn2' causes a section type conflict with 'mut_global_var'}} diff --git a/clang/test/SemaObjC/method-attributes.m b/clang/test/SemaObjC/method-attributes.m index 1b0a900da81d..110e6811e0f8 100644 --- a/clang/test/SemaObjC/method-attributes.m +++ b/clang/test/SemaObjC/method-attributes.m @@ -99,3 +99,18 @@ - (id) IMethod :(int) count, ... __attribute__((section("__TEXT,foo"))); + (void) CMethod : (id) Obj __attribute__((section("__TEXT,fee"))); @end + +// Section type conflicts between methods/properties and global variables +const int global1 __attribute__((section("seg1,sec1"))) = 10; // expected-note {{declared here}} expected-note {{declared here}} expected-note {{declared here}} +int global2 __attribute__((section("seg2,sec2"))) = 10; // expected-note {{declared here}} expected-note {{declared here}} expected-note {{declared here}} + +@interface section_conflicts : NSObject +@property int p1 __attribute__((section("seg1,sec1"))); // expected-error {{'p1' causes a section type conflict with 'global1'}} +@property int p2 __attribute__((section("seg2,sec2"))); // expected-error {{'p2' causes a section type conflict with 'global2'}} + +- (void)imethod1 __attribute__((section("seg1,sec1"))); // expected-error {{'imethod1' causes a section type conflict with 'global1'}} +- (void)imethod2 __attribute__((section("seg2,sec2"))); // expected-error {{'imethod2' causes a section type conflict with 'global2'}} + ++ (void)cmethod1:(id)Obj __attribute__((section("seg1,sec1"))); // expected-error {{'cmethod1:' causes a section type conflict with 'global1'}} ++ (void)cmethod2:(id)Obj __attribute__((section("seg2,sec2"))); // expected-error {{'cmethod2:' causes a section type conflict with 'global2'}} +@end _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits