diff options
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/include/clang/Basic/Attr.td | 7 | ||||
| -rw-r--r-- | clang/include/clang/Basic/AttrDocs.td | 12 | ||||
| -rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 8 | ||||
| -rw-r--r-- | clang/include/clang/Sema/Sema.h | 2 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 89 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclAttr.cpp | 31 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 35 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaLambda.cpp | 4 | ||||
| -rw-r--r-- | clang/test/CodeGenCXX/code_seg1.cpp | 135 | ||||
| -rw-r--r-- | clang/test/CodeGenCXX/code_seg2.cpp | 141 | ||||
| -rw-r--r-- | clang/test/CodeGenCXX/code_seg3.cpp | 86 | ||||
| -rw-r--r-- | clang/test/CodeGenCXX/code_seg4.cpp | 31 | ||||
| -rw-r--r-- | clang/test/SemaCXX/attr-section.cpp | 44 | ||||
| -rw-r--r-- | clang/test/SemaCXX/code_seg.cpp | 104 | ||||
| -rw-r--r-- | clang/test/SemaCXX/code_seg1.cpp | 96 | 
15 files changed, 57 insertions, 768 deletions
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index d72544f6556..cddf67d45c5 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -1770,13 +1770,6 @@ def Section : InheritableAttr {    let Documentation = [SectionDocs];  } -def CodeSeg : InheritableAttr { -  let Spellings = [Declspec<"code_seg">]; -  let Args = [StringArgument<"Name">]; -  let Subjects = SubjectList<[Function, CXXRecord], ErrorDiag>; -  let Documentation = [CodeSegDocs]; -} -  def PragmaClangBSSSection : InheritableAttr {    // This attribute has no spellings as it is only ever created implicitly.    let Spellings = []; diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index 65fb8f68287..1cb510560d0 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -306,18 +306,6 @@ An example of how to use ``alloc_size``    }];  } -def CodeSegDocs : Documentation { -  let Category = DocCatFunction; -  let Content = [{ -The ``__declspec(code_seg)`` attribute enables the placement of code into separate -named segments that can be paged or locked in memory individually. This attribute -is used to control the placement of instantiated templates and compiler-generated -code. See the documentation for `__declspec(code_seg)`_ on MSDN. - -.. _`__declspec(code_seg)`: http://msdn.microsoft.com/en-us/library/dn636922.aspx -  }]; -} -  def AllocAlignDocs : Documentation {    let Category = DocCatFunction;    let Content = [{ diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 66966fcfeca..3aee1922163 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -2668,14 +2668,6 @@ def warn_mismatched_section : Warning<  def warn_attribute_section_on_redeclaration : Warning<    "section attribute is specified on redeclared variable">, InGroup<Section>; -def err_mismatched_code_seg_base : Error< -  "derived class must specify the same code segment as its base classes">; -def err_mismatched_code_seg_override : Error< -  "overriding virtual function must specify the same code segment as its overridden function">; -def err_conflicting_codeseg_attribute : Error< -  "conflicting code segment specifiers">; -def warn_duplicate_codeseg_attribute : Warning< -  "duplicate code segment specifiers">, InGroup<Section>;  def err_anonymous_property: Error<    "anonymous property is not supported">;  def err_property_is_variably_modified : Error< diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 8961e193c7b..bc393e91ea8 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -1934,7 +1934,6 @@ public:    bool shouldLinkDependentDeclWithPrevious(Decl *D, Decl *OldDecl);    void CheckMain(FunctionDecl *FD, const DeclSpec &D);    void CheckMSVCRTEntryPoint(FunctionDecl *FD); -  Attr *getImplicitSectionAttrForFunction(const FunctionDecl *FD, bool IsDefinition = true);    Decl *ActOnParamDeclarator(Scope *S, Declarator &D);    ParmVarDecl *BuildParmVarDeclForTypedef(DeclContext *DC,                                            SourceLocation Loc, @@ -5837,7 +5836,6 @@ public:    /// ensure that referenceDLLExportedClassMethods is called some point later    /// when all outer classes of Class are complete.    void checkClassLevelDLLAttribute(CXXRecordDecl *Class); -  void checkClassLevelSectionAttribute(CXXRecordDecl *Class);    void referenceDLLExportedClassMethods(); diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 8c16bbc2480..9a1ab4a3c58 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -2667,14 +2667,9 @@ void Sema::mergeDeclAttributes(NamedDecl *New, Decl *Old,          Diag(New->getLocation(), diag::warn_attribute_section_on_redeclaration);          Diag(Old->getLocation(), diag::note_previous_declaration);        } -    } else if (isa<CXXMethodDecl>(New)) { -      const auto *NewSA = New->getAttr<SectionAttr>(); -      if (!NewSA->isImplicit()) { -        Diag(New->getLocation(), diag::warn_mismatched_section); -        Diag(Old->getLocation(), diag::note_previous_declaration); -      }      }    } +    if (!Old->hasAttrs())      return; @@ -8721,18 +8716,18 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,                                                   PragmaClangTextSection.PragmaLocation));    } -  // Apply an implicit SectionAttr from class declspec or from -  // #pragma code_seg if active. -  if (!NewFD->hasAttr<SectionAttr>()) { -    if (Attr *SAttr = getImplicitSectionAttrForFunction(NewFD, -                                                        D.isFunctionDefinition())) { -      NewFD->addAttr(SAttr); -      if (UnifySection(cast<SectionAttr>(SAttr)->getName(), -                       ASTContext::PSF_Implicit | ASTContext::PSF_Execute | -                       ASTContext::PSF_Read, -                       NewFD)) -        NewFD->dropAttr<SectionAttr>(); -    } +  // Apply an implicit SectionAttr if #pragma code_seg is active. +  if (CodeSegStack.CurrentValue && D.isFunctionDefinition() && +      !NewFD->hasAttr<SectionAttr>()) { +    NewFD->addAttr( +        SectionAttr::CreateImplicit(Context, SectionAttr::Declspec_allocate, +                                    CodeSegStack.CurrentValue->getString(), +                                    CodeSegStack.CurrentPragmaLocation)); +    if (UnifySection(CodeSegStack.CurrentValue->getString(), +                     ASTContext::PSF_Implicit | ASTContext::PSF_Execute | +                         ASTContext::PSF_Read, +                     NewFD)) +      NewFD->dropAttr<SectionAttr>();    }    // Handle attributes. @@ -9182,64 +9177,6 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,    return NewFD;  } -/// Return a SectionAttr from a containing class.  The Microsoft docs say -/// when __declspec(code_seg) "is applied to a class, all member functions of -/// the class and nested classes -- this includes compiler-generated special -/// member functions -- are put in the specified segment." -/// The actual behavior is a little more complicated. The Microsoft compiler -/// won't check outer classes if there is an active value from #pragma code_seg. -/// The section is always applied from the direct parent but only from outer -/// classes when the #pragma code_seg stack is empty. See: -/// https://reviews.llvm.org/D22931, the Microsoft feedback page is no longer -/// available since MS has removed the page. -static Attr *getImplicitSectionAttrFromClass(Sema &S, const FunctionDecl *FD) { -  const auto *Method = dyn_cast<CXXMethodDecl>(FD); -  if (!Method) -    return nullptr; -  const CXXRecordDecl *Parent = Method->getParent(); -  if (const auto *SAttr = Parent->getAttr<SectionAttr>()) { -    Attr *NewAttr = SAttr->clone(S.getASTContext()); -    NewAttr->setImplicit(true); -    return NewAttr; -  } - -  // The Microsoft compiler won't check outer classes for the section -  // when the #pragma code_seg stack is active. -  if (S.CodeSegStack.CurrentValue) -    return nullptr; - -  while ((Parent = dyn_cast<CXXRecordDecl>(Parent->getParent()))) { -    if (const auto *SAttr = Parent->getAttr<SectionAttr>()) { -      Attr *NewAttr = SAttr->clone(S.getASTContext()); -      NewAttr->setImplicit(true); -      return NewAttr; -    } -  } -  return nullptr; -} - -/// \brief Returns an implicit SectionAttr for a function. -/// -/// \param FD Function being declared. -/// \param IsDefinition Whether it is a definition or just a declarartion. -/// \returns A SectionAttr to apply to the function or nullptr if no -///          attribute should be added. -/// -/// First tries to find a SectionAttr on a containing class (from -/// a __declspec(code_seg)).  If not found on the class, and if the function is -/// also a definition it will use the current #pragma code_seg value. -Attr *Sema::getImplicitSectionAttrForFunction(const FunctionDecl *FD, bool IsDefinition) { -  if (Attr *A = getImplicitSectionAttrFromClass(*this, FD)) -    return A; -  if (IsDefinition && CodeSegStack.CurrentValue) { -    return SectionAttr::CreateImplicit(getASTContext(), -                                       SectionAttr::Declspec_allocate, -                                       CodeSegStack.CurrentValue->getString(), -                                       CodeSegStack.CurrentPragmaLocation); -  } -  return nullptr; -} -  /// Checks if the new declaration declared in dependent context must be  /// put in the same redeclaration chain as the specified declaration.  /// diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 7e64b2369b3..e4532a7e678 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -2853,13 +2853,6 @@ static void handleVecTypeHint(Sema &S, Decl *D, const AttributeList &AL) {  SectionAttr *Sema::mergeSectionAttr(Decl *D, SourceRange Range,                                      StringRef Name,                                      unsigned AttrSpellingListIndex) { -  // Explicit or partial specializations do not inherit -  // the code_seg attribute from the primary template. -  if (const auto *FD = dyn_cast<FunctionDecl>(D)){ -    if (FD->isFunctionTemplateSpecialization()) -      return nullptr; -  } -    if (SectionAttr *ExistingAttr = D->getAttr<SectionAttr>()) {      if (ExistingAttr->getName() == Name)        return nullptr; @@ -2949,27 +2942,6 @@ static void handleTargetAttr(Sema &S, Decl *D, const AttributeList &AL) {    D->addAttr(NewAttr);  } -static void handleCodeSegAttr(Sema &S, Decl *D, const AttributeList &AL) { -  StringRef Str; -  SourceLocation LiteralLoc; -  if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &LiteralLoc)) -    return; -  if (!S.checkSectionName(LiteralLoc, Str)) -    return; -  if (const auto *ExistingAttr = D->getAttr<SectionAttr>()) { -    if (!ExistingAttr->isImplicit()) { -      S.Diag(AL.getLoc(),  -             ExistingAttr->getName() == Str  -             ? diag::warn_duplicate_codeseg_attribute -             : diag::err_conflicting_codeseg_attribute);	     -      return; -    } -    D->dropAttr<SectionAttr>(); -  } -  D->addAttr(::new (S.Context) SectionAttr( -      AL.getRange(), S.Context, Str, AL.getAttributeSpellingListIndex())); -} -  static void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &AL) {    Expr *E = AL.getArgAsExpr(0);    SourceLocation Loc = E->getExprLoc(); @@ -6325,9 +6297,6 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,    case AttributeList::AT_Uuid:      handleUuidAttr(S, D, AL);      break; -  case AttributeList::AT_CodeSeg: -    handleCodeSegAttr(S, D, AL); -    break;    case AttributeList::AT_MSInheritance:      handleMSInheritanceAttr(S, D, AL);      break; diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index b836d4c8ad7..d5af147279a 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -2231,20 +2231,6 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class,    CXXRecordDecl *CXXBaseDecl = cast<CXXRecordDecl>(BaseDecl);    assert(CXXBaseDecl && "Base type is not a C++ type"); -  // Microsoft docs say: -  // "If a base-class has a code_seg attribute, derived classes must have the -  // same attribute." -   const auto *BaseSA = CXXBaseDecl->getAttr<SectionAttr>(); -   const auto *DerivedSA = Class->getAttr<SectionAttr>(); -   if (BaseSA || DerivedSA) { -     if (!BaseSA || !DerivedSA || BaseSA->getName() != DerivedSA->getName()) { -       Diag(Class->getLocation(), diag::err_mismatched_code_seg_base); -       Diag(CXXBaseDecl->getLocation(), diag::note_base_class_specified_here) -         << CXXBaseDecl; -       return nullptr; -     } -   } -    // A class which contains a flexible array member is not suitable for use as a    // base class:    //   - If the layout determines that a base comes before another base, @@ -5590,16 +5576,6 @@ static void checkForMultipleExportedDefaultConstructors(Sema &S,    }  } -void Sema::checkClassLevelSectionAttribute(CXXRecordDecl *Class) { -  // Mark any compiler-generated routines with the implicit Section attribute. -  for (auto *Method : Class->methods()) { -    if (Method->isUserProvided()) -      continue; -    if (Attr *A = getImplicitSectionAttrForFunction(Method)) -      Method->addAttr(A); -  } -} -  /// Check class-level dllimport/dllexport attribute.  void Sema::checkClassLevelDLLAttribute(CXXRecordDecl *Class) {    Attr *ClassAttr = getDLLAttr(Class); @@ -6103,7 +6079,6 @@ void Sema::CheckCompletedCXXClass(CXXRecordDecl *Record) {    }    checkClassLevelDLLAttribute(Record); -  checkClassLevelSectionAttribute(Record);    bool ClangABICompat4 =        Context.getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver4; @@ -14556,16 +14531,6 @@ bool Sema::CheckOverridingFunctionAttributes(const CXXMethodDecl *New,               diag::note_overridden_marked_noescape);        }    } -  // Virtual overrides must have the same code_seg. -  const auto *OldSA = Old->getAttr<SectionAttr>(); -  const auto *NewSA = New->getAttr<SectionAttr>(); -  if (OldSA || NewSA) { -    if (!OldSA || !NewSA || NewSA->getName() != OldSA->getName()) { -      Diag(New->getLocation(), diag::err_mismatched_code_seg_override); -      Diag(Old->getLocation(), diag::note_previous_declaration); -      return true; -    } -  }    CallingConv NewCC = NewFT->getCallConv(), OldCC = OldFT->getCallConv(); diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index 4acff89fb90..fec0d575e5b 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -910,10 +910,6 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,    AddRangeBasedOptnone(Method);    // Attributes on the lambda apply to the method.   -  if (Attr *A = getImplicitSectionAttrForFunction(Method)) -    Method->addAttr(A); -   -  // Attributes on the lambda apply to the method.    ProcessDeclAttributes(CurScope, Method, ParamInfo);    // CUDA lambdas get implicit attributes based on the scope in which they're diff --git a/clang/test/CodeGenCXX/code_seg1.cpp b/clang/test/CodeGenCXX/code_seg1.cpp deleted file mode 100644 index 07ca29b8918..00000000000 --- a/clang/test/CodeGenCXX/code_seg1.cpp +++ /dev/null @@ -1,135 +0,0 @@ -// RUN: %clang_cc1 -emit-llvm -triple i686-pc-win32 -fms-extensions -verify -o - %s | FileCheck %s -// expected-no-diagnostics - -// Simple case - -int __declspec(code_seg("foo_one")) bar_one() { return 1; } -//CHECK: define {{.*}}bar_one{{.*}} section "foo_one" - -// Simple case - explicit attribute used over pragma -#pragma code_seg("foo_two") -int __declspec(code_seg("foo_three")) bar2() { return 2; } -//CHECK: define {{.*}}bar2{{.*}} section "foo_three" - -// Check that attribute on one function doesn't affect another -int another1() { return 1001; } -//CHECK: define {{.*}}another1{{.*}} section "foo_two" - -// Member functions - -struct __declspec(code_seg("foo_four")) Foo { -  int bar3() {return 0;} -  int bar4(); -  int __declspec(code_seg("foo_six")) bar6() { return 6; } -  int bar7() { return 7; } -  struct Inner { -    int bar5() { return 5; } -  } z; -  virtual int baz1() { return 1; } -}; - -struct __declspec(code_seg("foo_four")) FooTwo : Foo { -  int baz1() { return 20; } -}; - -int caller1() { -  Foo f; return f.bar3(); -} - -//CHECK: define {{.*}}bar3@Foo{{.*}} section "foo_four" -int Foo::bar4() { return 4; } -//CHECK: define {{.*}}bar4@Foo{{.*}} section "foo_four" - -#pragma code_seg("someother") - -int caller2() { -  Foo f; -  Foo *fp = new FooTwo; -  return f.z.bar5() + f.bar6() + f.bar7() + fp->baz1(); -} -// TBD: MS Compiler and Docs do not match for nested routines -// Doc says:      define {{.*}}bar5@Inner@Foo{{.*}} section "foo_four" -// Compiler says: define {{.*}}bar5@Inner@Foo{{.*}} section "foo_two" -//CHECK: define {{.*}}bar6@Foo{{.*}} section "foo_six" -//CHECK: define {{.*}}bar7@Foo{{.*}} section "foo_four" -// Check that code_seg active at class declaration is not used on member -// declared outside class when it is not active. - -#pragma code_seg(push,"AnotherSeg") - -struct FooThree { -  int bar8(); -  int bar9() { return 9; } -}; - -#pragma code_seg(pop) - - -int FooThree::bar8() {return 0;} - -int caller3() -{ -  FooThree f; -  return f.bar8() + f.bar9(); -} - -//CHECK: define {{.*}}bar8@FooThree{{.*}} section "someother" -//CHECK: define {{.*}}bar9@FooThree{{.*}} section "AnotherSeg" - -struct NonTrivialCopy { -  NonTrivialCopy(); -  NonTrivialCopy(const NonTrivialCopy&); -  ~NonTrivialCopy(); -}; - -// check the section for compiler-generated function with declspec. - -struct __declspec(code_seg("foo_seven")) FooFour { -  FooFour() {} -  int __declspec(code_seg("foo_eight")) bar10(int t) { return t; } -  NonTrivialCopy f; -}; - -//CHECK: define {{.*}}0FooFour@@QAE@ABU0@@Z{{.*}} section "foo_seven" -// check the section for compiler-generated function with no declspec. - -struct FooFive { -  FooFive() {} -  int __declspec(code_seg("foo_nine")) bar11(int t) { return t; } -  NonTrivialCopy f; -}; - -//CHECK: define {{.*}}0FooFive@@QAE@ABU0@@Z{{.*}} section "someother" - -#pragma code_seg("YetAnother") -int caller4() -{ -  FooFour z1; -  FooFour z2 = z1; -  FooFive y1; -  FooFive y2 = y1; -  return z2.bar10(0) + y2.bar11(1); -} - -//CHECK: define {{.*}}bar10@FooFour{{.*}} section "foo_eight" -//CHECK: define {{.*}}bar11@FooFive{{.*}} section "foo_nine" - -struct FooSix { -  #pragma code_seg("foo_ten") -  int bar12() { return 12; } -  #pragma code_seg("foo_eleven") -  int bar13() { return 13; } -}; - -int bar14() { return 14; } -//CHECK: define {{.*}}bar14{{.*}} section "foo_eleven" - -int caller5() -{ -  FooSix fsix; -  return fsix.bar12() + fsix.bar13(); -} - -//CHECK: define {{.*}}bar12@FooSix{{.*}} section "foo_ten" -//CHECK: define {{.*}}bar13@FooSix{{.*}} section "foo_eleven" -//CHECK: define {{.*}}baz1@FooTwo{{.*}} section "foo_four" diff --git a/clang/test/CodeGenCXX/code_seg2.cpp b/clang/test/CodeGenCXX/code_seg2.cpp deleted file mode 100644 index 127db2cf0d8..00000000000 --- a/clang/test/CodeGenCXX/code_seg2.cpp +++ /dev/null @@ -1,141 +0,0 @@ -// RUN: %clang_cc1 -emit-llvm -triple i686-pc-win32 -std=c++11 -fms-extensions -verify -o - %s | FileCheck %s -// expected-no-diagnostics - -// Class member templates - -#pragma code_seg(push, "something") - -template <typename T> -struct __declspec(code_seg("foo_one")) ClassOne { -  int bar1(T t) { return int(t); } -  int bar2(T t); -  int bar3(T t); -}; - -template <typename T> -int ClassOne<T>::bar2(T t) { -  return int(t); -} - -int caller1() { -  ClassOne<int> coi; -  return coi.bar1(6) + coi.bar2(3); -} - -//CHECK: define {{.*}}bar1@?$ClassOne{{.*}} section "foo_one" -//CHECK: define {{.*}}bar2@?$ClassOne{{.*}} section "foo_one" - - -template <typename T> -struct ClassTwo { -  int bar11(T t) { return int(t); } -  int bar22(T t); -  int bar33(T t); -}; - -#pragma code_seg("newone") - -template <typename T> -int ClassTwo<T>::bar22(T t) { -  return int(t); -} - -#pragma code_seg("someother") - -template <typename T> -int ClassTwo<T>::bar33(T t) { -  return int(t); -} - -#pragma code_seg("yetanother") - -int caller2() { -  ClassTwo<int> coi; -  return coi.bar11(6) + coi.bar22(3) + coi.bar33(44); -} - -//CHECK: define {{.*}}bar11@?$ClassTwo{{.*}} section "something" -//CHECK: define {{.*}}bar22@?$ClassTwo{{.*}} section "newone" -//CHECK: define {{.*}}bar33@?$ClassTwo{{.*}} section "someother" - -template<> -struct ClassOne<double> -{ -  int bar44(double d) { return 1; } -}; -template<> -struct  __declspec(code_seg("foo_three")) ClassOne<long> -{ -  int bar55(long d) { return 1; } -}; - -#pragma code_seg("onemore") -int caller3() { -  ClassOne<double> d; -  ClassOne<long> l; -  return d.bar44(1.0)+l.bar55(1); -} - -//CHECK: define {{.*}}bar44{{.*}} section "yetanother" -//CHECK: define {{.*}}bar55{{.*}} section "foo_three" - - -// Function templates -template <typename T> -int __declspec(code_seg("foo_four")) bar66(T t) { return int(t); } - -// specializations do not take the segment from primary -template<> -int bar66(int i) { return 0; } - -#pragma code_seg(pop) - -template<> -int bar66(char c) { return 0; } - -struct A1 {int i;}; -template<> -int __declspec(code_seg("foo_five")) bar66(A1 a) { return a.i; } - -int caller4() -{ -// but instantiations do use the section from the primary -return bar66(0) + bar66(1.0) + bar66('c'); -} -//CHECK: define {{.*}}bar66@H{{.*}} section "onemore" -//CHECK-NOT: define {{.*}}bar66@D{{.*}} section -//CHECK: define {{.*}}bar66@UA1{{.*}} section "foo_five" -//CHECK: define {{.*}}bar66@N{{.*}} section "foo_four" - - -#pragma code_seg("another") -// Member functions -struct __declspec(code_seg("foo_four")) Foo { -  int bar3() {return 0;} - __declspec(code_seg("foo_lala")) int bar4() {return 0;} }; int caller() {Foo f; return f.bar3() + f.bar4(); } - -//CHECK: define {{.*}}bar3@Foo{{.*}} section "foo_four" -//CHECK: define {{.*}}bar4@Foo{{.*}} section "foo_lala" - -// Lambdas -#pragma code_seg("something") - -int __declspec(code_seg("foo")) bar1() -{ -  int lala = 4; -  auto l = [=](int i) { return i+4; }; -  return l(-4); -} - -//CHECK: define {{.*}}bar1{{.*}} section "foo" -//CHECK: define {{.*}}lambda{{.*}}bar1{{.*}} section "something" - -double __declspec(code_seg("foo")) bar2() -{ -  double lala = 4.0; -  auto l = [=](double d) __declspec(code_seg("another"))  { return d+4.0; }; -  return l(4.0); -} - -//CHECK: define {{.*}}bar2{{.*}} section "foo" -//CHECK: define {{.*}}lambda{{.*}}bar2{{.*}} section "another" diff --git a/clang/test/CodeGenCXX/code_seg3.cpp b/clang/test/CodeGenCXX/code_seg3.cpp deleted file mode 100644 index a81e1b5bba9..00000000000 --- a/clang/test/CodeGenCXX/code_seg3.cpp +++ /dev/null @@ -1,86 +0,0 @@ -// RUN: %clang_cc1 -emit-llvm -triple i686-pc-win32 -fms-extensions -verify -o - %s | FileCheck %s -// expected-no-diagnostics -// The Microsoft document says: "When this attribute is applied to a class, -// all member functions of the class and nested classes - this includes  -// compiler-generated special member functions - are put in the specified segment." -// But the MS compiler does not always follow that.  A bug has been reported: -// see https://reviews.llvm.org/D22931, the Microsoft feedback page is no -// longer available. -// The MS compiler will apply a declspec from the parent class if there is no -// #pragma code_seg active at the class definition.  If there is an active -// code_seg that is used instead. - -// No active code_seg - -struct __declspec(code_seg("foo_outer")) Foo1 { -  struct Inner { -    void bar1(); -    static void bar2(); -  }; -}; -void Foo1::Inner::bar1() {} -void Foo1::Inner::bar2() {} - -//CHECK: define {{.*}}bar1@Inner@Foo1{{.*}} section "foo_outer" -//CHECK: define {{.*}}bar2@Inner@Foo1{{.*}} section "foo_outer" - -struct __declspec(code_seg("foo_outer")) Foo2 { -  struct __declspec(code_seg("foo_inner")) Inner { -    void bar1(); -    static void bar2(); -  }; -}; -void Foo2::Inner::bar1() {} -void Foo2::Inner::bar2() {} - -//CHECK: define {{.*}}bar1@Inner@Foo2{{.*}} section "foo_inner" -//CHECK: define {{.*}}bar2@Inner@Foo2{{.*}} section "foo_inner" - -#pragma code_seg(push, "otherseg") -struct __declspec(code_seg("foo_outer")) Foo3 { -  struct Inner { -    void bar1(); -    static void bar2(); -  }; -}; -void Foo3::Inner::bar1() {} -void Foo3::Inner::bar2() {} - -//CHECK: define {{.*}}bar1@Inner@Foo3{{.*}} section "otherseg" -//CHECK: define {{.*}}bar2@Inner@Foo3{{.*}} section "otherseg" - -struct __declspec(code_seg("foo_outer")) Foo4 { -  struct __declspec(code_seg("foo_inner")) Inner { -    void bar1(); -    static void bar2(); -  }; -}; -void Foo4::Inner::bar1() {} -void Foo4::Inner::bar2() {} - -//CHECK: define {{.*}}bar1@Inner@Foo4{{.*}} section "foo_inner" -//CHECK: define {{.*}}bar2@Inner@Foo4{{.*}} section "foo_inner" - -#pragma code_seg(pop) -// Back to no active pragma -struct __declspec(code_seg("foo_outer")) Foo5 { -  struct Inner { -    void bar1(); -    static void bar2(); -    struct __declspec(code_seg("inner1_seg")) Inner1 { -      struct Inner2 { -        void bar1(); -        static void bar2(); -      }; -    }; -  }; -}; -void Foo5::Inner::bar1() {} -void Foo5::Inner::bar2() {} -void Foo5::Inner::Inner1::Inner2::bar1() {} -void Foo5::Inner::Inner1::Inner2::bar2() {} - -//CHECK: define {{.*}}bar1@Inner@Foo5{{.*}} section "foo_outer" -//CHECK: define {{.*}}bar2@Inner@Foo5{{.*}} section "foo_outer" -//CHECK: define {{.*}}bar1@Inner2@Inner1@Inner@Foo5{{.*}} section "inner1_seg" -//CHECK: define {{.*}}bar2@Inner2@Inner1@Inner@Foo5{{.*}} section "inner1_seg" diff --git a/clang/test/CodeGenCXX/code_seg4.cpp b/clang/test/CodeGenCXX/code_seg4.cpp deleted file mode 100644 index dd5a9054316..00000000000 --- a/clang/test/CodeGenCXX/code_seg4.cpp +++ /dev/null @@ -1,31 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -fms-extensions %s -triple x86_64-pc-win32 -// expected-no-diagnostics - -// Non-Member Function Overloading is involved - -int __declspec(code_seg("foo_one")) bar_one(int) { return 1; } -//CHECK: define {{.*}}bar_one{{.*}} section "foo_one" -int __declspec(code_seg("foo_two")) bar_one(int,float) { return 11; } -//CHECK: define {{.*}}bar_one{{.*}} section "foo_two" -int __declspec(code_seg("foo_three")) bar_one(float) { return 12; } -//CHECK: define {{.*}}bar_one{{.*}} section "foo_three" - -// virtual function overloading is involved - -struct __declspec(code_seg("my_one")) Base3 { -  virtual int barA(int) { return 1; } -  virtual int barA(int,float) { return 2; } -  virtual int barA(float) { return 3; } - -  virtual void __declspec(code_seg("my_two")) barB(int) { } -  virtual void  __declspec(code_seg("my_three")) barB(float) { } -  virtual void __declspec(code_seg("my_four")) barB(int, float) { } - -}; - -//CHECK: define {{.*}}barA@Base3{{.*}} section "my_one" -//CHECK: define {{.*}}barA@Base3{{.*}} section "my_one" -//CHECK: define {{.*}}barA@Base3{{.*}} section "my_one" -//CHECK: define {{.*}}barB@Base3{{.*}} section "my_two" -//CHECK: define {{.*}}barB@Base3{{.*}} section "my_three" -//CHECK: define {{.*}}barB@Base3{{.*}} section "my_four" diff --git a/clang/test/SemaCXX/attr-section.cpp b/clang/test/SemaCXX/attr-section.cpp new file mode 100644 index 00000000000..cc80989d22b --- /dev/null +++ b/clang/test/SemaCXX/attr-section.cpp @@ -0,0 +1,44 @@ +// RUN: %clang_cc1 -verify -fsyntax-only -triple x86_64-linux-gnu %s + +int x __attribute__((section( +   42)));  // expected-error {{'section' attribute requires a string}} + + +// PR6007 +void test() { +  __attribute__((section("NEAR,x"))) int n1; // expected-error {{'section' attribute only applies to functions, global variables, Objective-C methods, and Objective-C properties}} +  __attribute__((section("NEAR,x"))) static int n2; // ok. +} + +// pr9356 +void __attribute__((section("foo"))) test2(); // expected-note {{previous attribute is here}} +void __attribute__((section("bar"))) test2() {} // expected-warning {{section does not match previous declaration}} + +enum __attribute__((section("NEAR,x"))) e { one }; // expected-error {{'section' attribute only applies to}} + +extern int a; // expected-note {{previous declaration is here}} +int *b = &a; +extern int a __attribute__((section("foo,zed"))); // expected-warning {{section attribute is specified on redeclared variable}} + +// Not a warning. +extern int c; +int c __attribute__((section("foo,zed"))); + +// Also OK. +struct r_debug {}; +extern struct r_debug _r_debug; +struct r_debug _r_debug __attribute__((nocommon, section(".r_debug,bar"))); + +namespace override { +  struct A { +    __attribute__((section("foo"))) virtual void f(){}; +  }; +  struct B : A { +    void f() {} // ok +  }; +  struct C : A { +    __attribute__((section("bar"))) void f(); // expected-note {{previous}} +  }; +  __attribute__((section("baz"))) // expected-warning {{section does not match}} +  void C::f() {} +} diff --git a/clang/test/SemaCXX/code_seg.cpp b/clang/test/SemaCXX/code_seg.cpp deleted file mode 100644 index c005fd1e082..00000000000 --- a/clang/test/SemaCXX/code_seg.cpp +++ /dev/null @@ -1,104 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -fms-extensions %s -triple x86_64-pc-win32 - -struct __declspec(code_seg("my_one")) FooOne { -  int barC(); -}; - -struct FooTwo { -  int __declspec(code_seg("my_three")) barD(); -  int barE(); -}; -int __declspec(code_seg("my_four")) FooOne::barC() { return 10; } -// expected-warning@-1 {{section does not match previous declaration}} -// expected-note@3{{previous attribute is here}} -int __declspec(code_seg("my_five")) FooTwo::barD() { return 20; } -// expected-warning@-1 {{section does not match previous declaration}} -// expected-note@8 {{previous attribute is here}} -int __declspec(code_seg("my_six")) FooTwo::barE() { return 30; } -// expected-warning@-1 {{section does not match previous declaration}} -// expected-note@9 {{previous declaration is here}} - -// Microsoft docs say: -// If a base-class has a code_seg attribute, derived classes must have the -// same attribute. -struct __declspec(code_seg("my_base")) Base1 {}; -struct Base2 {}; - -struct D1 : Base1 {}; -//expected-error@-1 {{derived class must specify the same code segment as its base classes}} -// expected-note@24 {{base class 'Base1' specified here}} -struct __declspec(code_seg("my_derived")) D2 : Base1 {}; -// expected-error@-1 {{derived class must specify the same code segment as its base classes}} -// expected-note@24 {{base class 'Base1' specified here}} -struct __declspec(code_seg("my_derived")) D3 : Base2 {}; -// expected-error@-1 {{derived class must specify the same code segment as its base classes}} -// expected-note@25 {{base class 'Base2' specified here}} - -template <typename T> struct __declspec(code_seg("my_base")) MB : T { }; -template <typename T> struct __declspec(code_seg("my_derived")) MD : T { }; -MB<Base1> mb1; // ok -MB<Base2> mb2; -// expected-error@37 {{derived class must specify the same code segment as its base classes}} -// expected-note@-2 {{in instantiation of template class}} -// expected-note@25  {{base class 'Base2' specified here}} -MD<Base1> md1; -// expected-error@38 {{derived class must specify the same code segment as its base classes}} -// expected-note@-2 {{in instantiation of template class}} -// expected-note@24 {{base class 'Base1' specified here}} -MD<Base2> md2; -// expected-error@38 {{derived class must specify the same code segment as its base classes}} -// expected-note@-2 {{in instantiation of template class}} -// expected-note@25 {{base class 'Base2' specified here}} - -// Virtual overrides must have the same code_seg. -struct __declspec(code_seg("my_one")) Base3 { -  virtual int barA() { return 1; } -  virtual int __declspec(code_seg("my_two")) barB() { return 2; } -}; -struct __declspec(code_seg("my_one")) Derived3 : Base3 { -  int barA() { return 4; } // ok -  int barB() { return 6; } -  // expected-error@-1 {{overriding virtual function must specify the same code segment as its overridden function}} -  // expected-note@56 {{previous declaration is here}} -}; - -struct Base4 { -  virtual int __declspec(code_seg("my_one")) barA() {return 1;} -  virtual int barB() { return 2;} -}; -struct Derived4 : Base4 { -  virtual int barA() {return 1;} -  // expected-error@-1 {{overriding virtual function must specify the same code segment as its overridden function}} -  // expected-note@66 {{previous declaration is here}} -  virtual int __declspec(code_seg("my_two")) barB() {return 1;} -  // expected-error@-1 {{overriding virtual function must specify the same code segment as its overridden function}} -  // expected-note@67 {{previous declaration is here}} -}; - -// MS gives an error when different code segments are used but a warning when a duplicate is used - -// Function -int __declspec(code_seg("foo")) __declspec(code_seg("foo")) bar1() { return 1; } -// expected-warning@-1 {{duplicate code segment specifiers}} -int __declspec(code_seg("foo")) __declspec(code_seg("bar")) bar2() { return 1; } -// expected-error@-1 {{conflicting code segment specifiers}} - -// Class -struct __declspec(code_seg("foo")) __declspec(code_seg("foo")) Foo { -  // expected-warning@-1 {{duplicate code segment specifiers}} -  int bar3() {return 0;} -}; -struct __declspec(code_seg("foo")) __declspec(code_seg("bar")) FooSix { -  // expected-error@-1 {{conflicting code segment specifiers}} -  int bar3() {return 0;} -}; - -//Class Members -struct FooThree { -  int __declspec(code_seg("foo")) __declspec(code_seg("foo")) bar1() { return 1; } -  // expected-warning@-1 {{duplicate code segment specifiers}} -  int __declspec(code_seg("foo")) __declspec(code_seg("bar")) bar2() { return 1; } -  // expected-error@-1 {{conflicting code segment specifiers}} -  int bar8(); -  int bar9() { return 9; } -}; diff --git a/clang/test/SemaCXX/code_seg1.cpp b/clang/test/SemaCXX/code_seg1.cpp deleted file mode 100644 index 03f732690ee..00000000000 --- a/clang/test/SemaCXX/code_seg1.cpp +++ /dev/null @@ -1,96 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -fms-extensions %s -triple x86_64-pc-win32 - -// Multiple inheritance is involved (code segmments all disagree between the bases and derived class) -struct __declspec(code_seg("my_base")) Base1 {}; -struct Base2 {}; - -struct D1 : Base1, Base2 {}; -// expected-error@-1 {{derived class must specify the same code segment as its base classes}} -// expected-note@4 {{base class 'Base1' specified here}} - -struct __declspec(code_seg("my_derived")) D2 : Base2, Base1 {}; -// expected-error@-1 {{derived class must specify the same code segment as its base classes}} -// expected-error@-2 {{derived class must specify the same code segment as its base classes}} -// expected-note@5 {{base class 'Base2' specified here}} -// expected-note@4 {{base class 'Base1' specified here}} - -// Multiple inheritance (code segments partially agree between the bases and the derived class) -struct __declspec(code_seg("base_class")) BaseClass1 {}; -struct __declspec(code_seg("base_class")) BaseClass2 {}; - -struct Derived1 : BaseClass1, BaseClass2 {}; -// expected-error@-1 {{derived class must specify the same code segment as its base classes}} -// expected-error@-2 {{derived class must specify the same code segment as its base classes}} -// expected-note@18 {{base class 'BaseClass1' specified here}} -// expected-note@19 {{base class 'BaseClass2' specified here}} - -struct __declspec(code_seg("derived_class")) Derived2 : BaseClass2, BaseClass1 {}; -// expected-error@-1 {{derived class must specify the same code segment as its base classes}} -// expected-error@-2 {{derived class must specify the same code segment as its base classes}} -// expected-note@19 {{base class 'BaseClass2' specified here}} -// expected-note@18 {{base class 'BaseClass1' specified here}} - -struct __declspec(code_seg("base_class")) Derived3 : BaseClass2, BaseClass1 {}; //OK -struct __declspec(code_seg("base_class")) Derived4 : BaseClass1, BaseClass2 {}; //OK - -// Multiple inheritance is involved (code segmments all agree between the bases and derived class) -struct __declspec(code_seg("foo_base")) B1 {}; -struct __declspec(code_seg("foo_base")) B2 {}; -struct __declspec(code_seg("foo_base")) Derived : B1, B2 {}; - -// virtual Inheritance is involved (code segmments all disagree between the bases and derived class) -struct __declspec(code_seg("my_one")) Base { -  virtual int barA() { return 1; } ; -}; - -struct __declspec(code_seg("my_two")) Derived5 : virtual Base { -  virtual int barB() { return 2; }; -}; -// expected-error@-3 {{derived class must specify the same code segment as its base classes}} -// expected-note@42 {{base class 'Base' specified here}} - -struct __declspec(code_seg("my_three")) Derived6 : virtual Base { -  virtual int barC() { return 3; }; -}; -// expected-error@-3 {{derived class must specify the same code segment as its base classes}} -// expected-note@42 {{base class 'Base' specified here}} - -struct __declspec(code_seg("my_four")) Derived7 : Derived5, Derived6 {}; -// expected-error@-1 {{derived class must specify the same code segment as its base classes}} -// expected-error@-2 {{derived class must specify the same code segment as its base classes}} -// expected-note@46 {{base class 'Derived5' specified here}} -// expected-note@52 {{base class 'Derived6' specified here}} - -// virtual Inheritance is involved (code segmments partially agree between the bases and derived class) -struct __declspec(code_seg("my_class")) BaseClass { -  virtual int barA() { return 1; } ; -}; - -struct __declspec(code_seg("my_class")) DerivedClass1 : virtual BaseClass { //OK -  virtual int barB() { return 2; }; -}; - -struct __declspec(code_seg("my_class")) DerivedClass2 : virtual BaseClass { //OK -  virtual int barC() { return 3; }; -}; - -struct __declspec(code_seg("my_derived_one")) DerivedClass3 : DerivedClass1, DerivedClass2 {}; -// expected-error@-1 {{derived class must specify the same code segment as its base classes}} -// expected-error@-2 {{derived class must specify the same code segment as its base classes}} -// expected-note@69 {{base class 'DerivedClass1' specified here}} -// expected-note@73 {{base class 'DerivedClass2' specified here}} - -// virtual Inheritance is involved (code segmments all agree between the bases and derived class) -struct __declspec(code_seg("foo_one")) Class { -  virtual int foo1() { return 10; } ; -}; - -struct __declspec(code_seg("foo_one")) Derived_One: virtual Class { //OK -  virtual int foo2() { return 20; }; -}; - -struct __declspec(code_seg("foo_one")) Derived_Two : virtual Class { //OK -  virtual int foo3() { return 30; }; -}; - -struct __declspec(code_seg("foo_one")) Derived_Three : Derived_One, Derived_Two {}; //OK  | 

