Index: cfe/trunk/include/clang/Basic/Attr.td =================================================================== --- cfe/trunk/include/clang/Basic/Attr.td +++ cfe/trunk/include/clang/Basic/Attr.td @@ -1969,6 +1969,8 @@ 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">]; Index: cfe/trunk/include/clang/Basic/DiagnosticGroups.td =================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticGroups.td +++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td @@ -925,6 +925,7 @@ // 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 @@ // 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, Index: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td @@ -2750,6 +2750,9 @@ 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; def warn_mismatched_section : Warning< "%select{codeseg|section}0 does not match previous declaration">, InGroup
; def warn_attribute_section_on_redeclaration : Warning< Index: cfe/trunk/lib/Sema/SemaAttr.cpp =================================================================== --- cfe/trunk/lib/Sema/SemaAttr.cpp +++ cfe/trunk/lib/Sema/SemaAttr.cpp @@ -403,9 +403,15 @@ 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); } Index: cfe/trunk/lib/Sema/SemaDeclAttr.cpp =================================================================== --- cfe/trunk/lib/Sema/SemaDeclAttr.cpp +++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp @@ -3011,13 +3011,18 @@ 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; } Index: cfe/trunk/test/Sema/pragma-section.c =================================================================== --- cfe/trunk/test/Sema/pragma-section.c +++ cfe/trunk/test/Sema/pragma-section.c @@ -42,3 +42,20 @@ #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;