[llvm-branch-commits] [clang] f500662 - Detect section type conflicts between functions and variables
Aaron Ballman via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Dec 17 08:48:49 PST 2020
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}}
+
+ at interface section_conflicts : NSObject
+ at property int p1 __attribute__((section("seg1,sec1"))); // expected-error {{'p1' causes a section type conflict with 'global1'}}
+ at 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'}}
+ at end
More information about the llvm-branch-commits
mailing list