Skip to content

Commit 9801621

Browse files
committedJul 9, 2019
clang-cl: Port cl.exe's C4659 to clang-cl
Differential Revision: https://reviews.llvm.org/D64349 llvm-svn: 365411
1 parent c6b5c5b commit 9801621

File tree

6 files changed

+45
-10
lines changed

6 files changed

+45
-10
lines changed
 

‎clang/include/clang/Basic/Attr.td

+2
Original file line numberDiff line numberDiff line change
@@ -1969,6 +1969,8 @@ def Section : InheritableAttr {
19691969
let Documentation = [SectionDocs];
19701970
}
19711971

1972+
// This is used for `__declspec(code_seg("segname"))`, but not for
1973+
// `#pragma code_seg("segname")`.
19721974
def CodeSeg : InheritableAttr {
19731975
let Spellings = [Declspec<"code_seg">];
19741976
let Args = [StringArgument<"Name">];

‎clang/include/clang/Basic/DiagnosticGroups.td

+5-3
Original file line numberDiff line numberDiff line change
@@ -925,6 +925,7 @@ def GccCompat : DiagGroup<"gcc-compat">;
925925

926926
// Warnings for Microsoft extensions.
927927
def MicrosoftCharize : DiagGroup<"microsoft-charize">;
928+
def MicrosoftDrectveSection : DiagGroup<"microsoft-drectve-section">;
928929
def MicrosoftInclude : DiagGroup<"microsoft-include">;
929930
def MicrosoftCppMacro : DiagGroup<"microsoft-cpp-macro">;
930931
def MicrosoftFixedEnum : DiagGroup<"microsoft-fixed-enum">;
@@ -962,9 +963,10 @@ def : DiagGroup<"msvc-include", [MicrosoftInclude]>;
962963

963964
// Warnings group for warnings about Microsoft extensions.
964965
def Microsoft : DiagGroup<"microsoft",
965-
[MicrosoftCharize, MicrosoftInclude, MicrosoftCppMacro, MicrosoftFixedEnum,
966-
MicrosoftSealed, MicrosoftUnqualifiedFriend, MicrosoftExceptionSpec,
967-
MicrosoftUsingDecl, MicrosoftMutableReference, MicrosoftPureDefinition,
966+
[MicrosoftCharize, MicrosoftDrectveSection, MicrosoftInclude,
967+
MicrosoftCppMacro, MicrosoftFixedEnum, MicrosoftSealed,
968+
MicrosoftUnqualifiedFriend, MicrosoftExceptionSpec, MicrosoftUsingDecl,
969+
MicrosoftMutableReference, MicrosoftPureDefinition,
968970
MicrosoftUnionMemberReference, MicrosoftExplicitConstructorCall,
969971
MicrosoftEnumValue, MicrosoftDefaultArgRedefinition, MicrosoftTemplate,
970972
MicrosoftRedeclareStatic, MicrosoftEnumForwardReference, MicrosoftGoto,

‎clang/include/clang/Basic/DiagnosticSemaKinds.td

+3
Original file line numberDiff line numberDiff line change
@@ -2750,6 +2750,9 @@ def err_only_annotate_after_access_spec : Error<
27502750

27512751
def err_attribute_section_invalid_for_target : Error<
27522752
"argument to %select{'code_seg'|'section'}1 attribute is not valid for this target: %0">;
2753+
def warn_attribute_section_drectve : Warning<
2754+
"#pragma %0(\".drectve\") has undefined behavior, "
2755+
"use #pragma comment(linker, ...) instead">, InGroup<MicrosoftDrectveSection>;
27532756
def warn_mismatched_section : Warning<
27542757
"%select{codeseg|section}0 does not match previous declaration">, InGroup<Section>;
27552758
def warn_attribute_section_on_redeclaration : Warning<

‎clang/lib/Sema/SemaAttr.cpp

+9-3
Original file line numberDiff line numberDiff line change
@@ -403,9 +403,15 @@ void Sema::ActOnPragmaMSSeg(SourceLocation PragmaLocation,
403403
if (Action & PSK_Pop && Stack->Stack.empty())
404404
Diag(PragmaLocation, diag::warn_pragma_pop_failed) << PragmaName
405405
<< "stack empty";
406-
if (SegmentName &&
407-
!checkSectionName(SegmentName->getBeginLoc(), SegmentName->getString()))
408-
return;
406+
if (SegmentName) {
407+
if (!checkSectionName(SegmentName->getBeginLoc(), SegmentName->getString()))
408+
return;
409+
410+
if (SegmentName->getString() == ".drectve" &&
411+
Context.getTargetInfo().getCXXABI().isMicrosoft())
412+
Diag(PragmaLocation, diag::warn_attribute_section_drectve) << PragmaName;
413+
}
414+
409415
Stack->Act(PragmaLocation, Action, StackSlotLabel, SegmentName);
410416
}
411417

‎clang/lib/Sema/SemaDeclAttr.cpp

+9-4
Original file line numberDiff line numberDiff line change
@@ -3011,13 +3011,18 @@ static void handleSectionAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
30113011
D->addAttr(NewAttr);
30123012
}
30133013

3014-
static bool checkCodeSegName(Sema&S, SourceLocation LiteralLoc, StringRef CodeSegName) {
3015-
std::string Error = S.Context.getTargetInfo().isValidSectionSpecifier(CodeSegName);
3014+
// This is used for `__declspec(code_seg("segname"))` on a decl.
3015+
// `#pragma code_seg("segname")` uses checkSectionName() instead.
3016+
static bool checkCodeSegName(Sema &S, SourceLocation LiteralLoc,
3017+
StringRef CodeSegName) {
3018+
std::string Error =
3019+
S.Context.getTargetInfo().isValidSectionSpecifier(CodeSegName);
30163020
if (!Error.empty()) {
3017-
S.Diag(LiteralLoc, diag::err_attribute_section_invalid_for_target) << Error
3018-
<< 0 /*'code-seg'*/;
3021+
S.Diag(LiteralLoc, diag::err_attribute_section_invalid_for_target)
3022+
<< Error << 0 /*'code-seg'*/;
30193023
return false;
30203024
}
3025+
30213026
return true;
30223027
}
30233028

‎clang/test/Sema/pragma-section.c

+17
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,20 @@ void fn_bad_seg(void){} // expected-error {{'fn_bad_seg' causes a section type c
4242
#pragma section(".my_seg", nopage) // expected-warning {{known but unsupported action 'nopage' for '#pragma section' - ignored}}
4343
#pragma section(".my_seg", read, write) // expected-error {{this causes a section type conflict with a prior #pragma section}}
4444
#pragma section(".my_seg", read, write, 1) // expected-warning {{expected action or ')' in '#pragma section' - ignored}}
45+
46+
#pragma bss_seg(".drectve") // expected-warning{{#pragma bss_seg(".drectve") has undefined behavior, use #pragma comment(linker, ...) instead}}
47+
#pragma code_seg(".drectve") // expected-warning{{#pragma code_seg(".drectve") has undefined behavior, use #pragma comment(linker, ...) instead}}
48+
#pragma const_seg(".drectve") // expected-warning{{#pragma const_seg(".drectve") has undefined behavior, use #pragma comment(linker, ...) instead}}
49+
#pragma data_seg(".drectve") // expected-warning{{#pragma data_seg(".drectve") has undefined behavior, use #pragma comment(linker, ...) instead}}
50+
#pragma code_seg(".my_seg")
51+
52+
// cl.exe doesn't warn on this, so match that.
53+
// (Technically it ICEs on this particular example, but if it's on a class then
54+
// it just doesn't warn.)
55+
__declspec(code_seg(".drectve")) void drectve_fn(void) {}
56+
57+
// This shouldn't warn; mingw users likely want to use
58+
// __attribute__((section(".drective")))
59+
// const char LinkerFlags[] = "-export:foo -export:bar";
60+
// for interop with gcc.
61+
__attribute__((section(".drectve"))) int drectve_int;

0 commit comments

Comments
 (0)
Please sign in to comment.