diff options
-rw-r--r-- | include/clang/Basic/Attr.td | 2 | ||||
-rw-r--r-- | include/clang/Basic/DiagnosticGroups.td | 8 | ||||
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.td | 3 | ||||
-rw-r--r-- | lib/Sema/SemaAttr.cpp | 12 | ||||
-rw-r--r-- | lib/Sema/SemaDeclAttr.cpp | 13 | ||||
-rw-r--r-- | test/Sema/pragma-section.c | 17 |
6 files changed, 45 insertions, 10 deletions
diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td index 93913b043e..d39b16e62b 100644 --- a/include/clang/Basic/Attr.td +++ b/include/clang/Basic/Attr.td @@ -1969,6 +1969,8 @@ def Section : InheritableAttr { let Documentation = [SectionDocs]; } +// This is used for `__declspec(code_seg("segname"))`, but not for +// `#pragma code_seg("segname")`. def CodeSeg : InheritableAttr { let Spellings = [Declspec<"code_seg">]; let Args = [StringArgument<"Name">]; diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td index 27671df0cf..71500d3c45 100644 --- a/include/clang/Basic/DiagnosticGroups.td +++ b/include/clang/Basic/DiagnosticGroups.td @@ -925,6 +925,7 @@ def GccCompat : DiagGroup<"gcc-compat">; // Warnings for Microsoft extensions. def MicrosoftCharize : DiagGroup<"microsoft-charize">; +def MicrosoftDrectveSection : DiagGroup<"microsoft-drectve-section">; def MicrosoftInclude : DiagGroup<"microsoft-include">; def MicrosoftCppMacro : DiagGroup<"microsoft-cpp-macro">; def MicrosoftFixedEnum : DiagGroup<"microsoft-fixed-enum">; @@ -962,9 +963,10 @@ def : DiagGroup<"msvc-include", [MicrosoftInclude]>; // Warnings group for warnings about Microsoft extensions. def Microsoft : DiagGroup<"microsoft", - [MicrosoftCharize, MicrosoftInclude, MicrosoftCppMacro, MicrosoftFixedEnum, - MicrosoftSealed, MicrosoftUnqualifiedFriend, MicrosoftExceptionSpec, - MicrosoftUsingDecl, MicrosoftMutableReference, MicrosoftPureDefinition, + [MicrosoftCharize, MicrosoftDrectveSection, MicrosoftInclude, + MicrosoftCppMacro, MicrosoftFixedEnum, MicrosoftSealed, + MicrosoftUnqualifiedFriend, MicrosoftExceptionSpec, MicrosoftUsingDecl, + MicrosoftMutableReference, MicrosoftPureDefinition, MicrosoftUnionMemberReference, MicrosoftExplicitConstructorCall, MicrosoftEnumValue, MicrosoftDefaultArgRedefinition, MicrosoftTemplate, MicrosoftRedeclareStatic, MicrosoftEnumForwardReference, MicrosoftGoto, diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 0536552015..6eee62d4b3 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -2750,6 +2750,9 @@ def err_only_annotate_after_access_spec : Error< def err_attribute_section_invalid_for_target : Error< "argument to %select{'code_seg'|'section'}1 attribute is not valid for this target: %0">; +def warn_attribute_section_drectve : Warning< + "#pragma %0(\".drectve\") has undefined behavior, " + "use #pragma comment(linker, ...) instead">, InGroup<MicrosoftDrectveSection>; def warn_mismatched_section : Warning< "%select{codeseg|section}0 does not match previous declaration">, InGroup<Section>; def warn_attribute_section_on_redeclaration : Warning< diff --git a/lib/Sema/SemaAttr.cpp b/lib/Sema/SemaAttr.cpp index e1929e3ec2..8e93188473 100644 --- a/lib/Sema/SemaAttr.cpp +++ b/lib/Sema/SemaAttr.cpp @@ -403,9 +403,15 @@ void Sema::ActOnPragmaMSSeg(SourceLocation PragmaLocation, if (Action & PSK_Pop && Stack->Stack.empty()) Diag(PragmaLocation, diag::warn_pragma_pop_failed) << PragmaName << "stack empty"; - if (SegmentName && - !checkSectionName(SegmentName->getBeginLoc(), SegmentName->getString())) - return; + if (SegmentName) { + if (!checkSectionName(SegmentName->getBeginLoc(), SegmentName->getString())) + return; + + if (SegmentName->getString() == ".drectve" && + Context.getTargetInfo().getCXXABI().isMicrosoft()) + Diag(PragmaLocation, diag::warn_attribute_section_drectve) << PragmaName; + } + Stack->Act(PragmaLocation, Action, StackSlotLabel, SegmentName); } diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 5a1712ff13..e4e6a19dba 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -3011,13 +3011,18 @@ static void handleSectionAttr(Sema &S, Decl *D, const ParsedAttr &AL) { D->addAttr(NewAttr); } -static bool checkCodeSegName(Sema&S, SourceLocation LiteralLoc, StringRef CodeSegName) { - std::string Error = S.Context.getTargetInfo().isValidSectionSpecifier(CodeSegName); +// This is used for `__declspec(code_seg("segname"))` on a decl. +// `#pragma code_seg("segname")` uses checkSectionName() instead. +static bool checkCodeSegName(Sema &S, SourceLocation LiteralLoc, + StringRef CodeSegName) { + std::string Error = + S.Context.getTargetInfo().isValidSectionSpecifier(CodeSegName); if (!Error.empty()) { - S.Diag(LiteralLoc, diag::err_attribute_section_invalid_for_target) << Error - << 0 /*'code-seg'*/; + S.Diag(LiteralLoc, diag::err_attribute_section_invalid_for_target) + << Error << 0 /*'code-seg'*/; return false; } + return true; } diff --git a/test/Sema/pragma-section.c b/test/Sema/pragma-section.c index 2906fabac1..03aa053a87 100644 --- a/test/Sema/pragma-section.c +++ b/test/Sema/pragma-section.c @@ -42,3 +42,20 @@ void fn_bad_seg(void){} // expected-error {{'fn_bad_seg' causes a section type c #pragma section(".my_seg", nopage) // expected-warning {{known but unsupported action 'nopage' for '#pragma section' - ignored}} #pragma section(".my_seg", read, write) // expected-error {{this causes a section type conflict with a prior #pragma section}} #pragma section(".my_seg", read, write, 1) // expected-warning {{expected action or ')' in '#pragma section' - ignored}} + +#pragma bss_seg(".drectve") // expected-warning{{#pragma bss_seg(".drectve") has undefined behavior, use #pragma comment(linker, ...) instead}} +#pragma code_seg(".drectve") // expected-warning{{#pragma code_seg(".drectve") has undefined behavior, use #pragma comment(linker, ...) instead}} +#pragma const_seg(".drectve") // expected-warning{{#pragma const_seg(".drectve") has undefined behavior, use #pragma comment(linker, ...) instead}} +#pragma data_seg(".drectve") // expected-warning{{#pragma data_seg(".drectve") has undefined behavior, use #pragma comment(linker, ...) instead}} +#pragma code_seg(".my_seg") + +// cl.exe doesn't warn on this, so match that. +// (Technically it ICEs on this particular example, but if it's on a class then +// it just doesn't warn.) +__declspec(code_seg(".drectve")) void drectve_fn(void) {} + +// This shouldn't warn; mingw users likely want to use +// __attribute__((section(".drective"))) +// const char LinkerFlags[] = "-export:foo -export:bar"; +// for interop with gcc. +__attribute__((section(".drectve"))) int drectve_int; |