thakis created this revision.
thakis added a reviewer: rnk.

https://reviews.llvm.org/D64349

Files:
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaAttr.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/Sema/pragma-section.c

Index: clang/test/Sema/pragma-section.c
===================================================================
--- clang/test/Sema/pragma-section.c
+++ clang/test/Sema/pragma-section.c
@@ -42,3 +42,17 @@
 #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) {}
+
+// Not sure if this should warn or not.
+__attribute__((section(".drectve"))) int drectve_int;
Index: clang/lib/Sema/SemaDeclCXX.cpp
===================================================================
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -2280,8 +2280,9 @@
   // For the MS ABI, propagate DLL attributes to base class templates.
   if (Context.getTargetInfo().getCXXABI().isMicrosoft()) {
     if (Attr *ClassAttr = getDLLAttr(Class)) {
-      if (auto *BaseTemplate = dyn_cast_or_null<ClassTemplateSpecializationDecl>(
-              BaseType->getAsCXXRecordDecl())) {
+      if (auto *BaseTemplate =
+              dyn_cast_or_null<ClassTemplateSpecializationDecl>(
+                  BaseType->getAsCXXRecordDecl())) {
         propagateDLLAttrToBaseClassTemplate(Class, ClassAttr, BaseTemplate,
                                             BaseLoc);
       }
@@ -2311,7 +2312,8 @@
   const auto *BaseCSA = CXXBaseDecl->getAttr<CodeSegAttr>();
   const auto *DerivedCSA = Class->getAttr<CodeSegAttr>();
   if ((DerivedCSA || BaseCSA) &&
-      (!BaseCSA || !DerivedCSA || BaseCSA->getName() != DerivedCSA->getName())) {
+      (!BaseCSA || !DerivedCSA ||
+       BaseCSA->getName() != DerivedCSA->getName())) {
     Diag(Class->getLocation(), diag::err_mismatched_code_seg_base);
     Diag(CXXBaseDecl->getLocation(), diag::note_base_class_specified_here)
       << CXXBaseDecl;
@@ -5665,7 +5667,8 @@
   for (auto *Method : Class->methods()) {
     if (Method->isUserProvided())
       continue;
-    if (Attr *A = getImplicitCodeSegOrSectionAttrForFunction(Method, /*IsDefinition=*/true))
+    if (Attr *A = getImplicitCodeSegOrSectionAttrForFunction(
+            Method, /*IsDefinition=*/true))
       Method->addAttr(A);
   }
 }
Index: clang/lib/Sema/SemaDeclAttr.cpp
===================================================================
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/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: clang/lib/Sema/SemaAttr.cpp
===================================================================
--- clang/lib/Sema/SemaAttr.cpp
+++ clang/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: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/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<MicrosoftDrectveSection>;
 def warn_mismatched_section : Warning<
   "%select{codeseg|section}0 does not match previous declaration">, InGroup<Section>;
 def warn_attribute_section_on_redeclaration : Warning<
Index: clang/include/clang/Basic/DiagnosticGroups.td
===================================================================
--- clang/include/clang/Basic/DiagnosticGroups.td
+++ clang/include/clang/Basic/DiagnosticGroups.td
@@ -923,6 +923,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">;
@@ -960,9 +961,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: clang/include/clang/Basic/Attr.td
===================================================================
--- clang/include/clang/Basic/Attr.td
+++ clang/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">];
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to