Author: rsmith Date: Fri May 18 13:18:17 2018 New Revision: 332760 URL: http://llvm.org/viewvc/llvm-project?rev=332760&view=rev Log: Revert r332470 (and corresponding tests in r332492).
This regressed our support for __attribute__((section)). See added test file for example of code broken by this. Added: cfe/trunk/test/SemaCXX/attr-section.cpp - copied, changed from r332757, cfe/trunk/test/Sema/attr-section.c Removed: cfe/trunk/test/CodeGenCXX/code_seg1.cpp cfe/trunk/test/CodeGenCXX/code_seg2.cpp cfe/trunk/test/CodeGenCXX/code_seg3.cpp cfe/trunk/test/CodeGenCXX/code_seg4.cpp cfe/trunk/test/SemaCXX/code_seg.cpp cfe/trunk/test/SemaCXX/code_seg1.cpp Modified: cfe/trunk/include/clang/Basic/Attr.td cfe/trunk/include/clang/Basic/AttrDocs.td cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/include/clang/Sema/Sema.h cfe/trunk/lib/Sema/SemaDecl.cpp cfe/trunk/lib/Sema/SemaDeclAttr.cpp cfe/trunk/lib/Sema/SemaDeclCXX.cpp cfe/trunk/lib/Sema/SemaLambda.cpp Modified: cfe/trunk/include/clang/Basic/Attr.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=332760&r1=332759&r2=332760&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/Attr.td (original) +++ cfe/trunk/include/clang/Basic/Attr.td Fri May 18 13:18:17 2018 @@ -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 = []; Modified: cfe/trunk/include/clang/Basic/AttrDocs.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/AttrDocs.td?rev=332760&r1=332759&r2=332760&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/AttrDocs.td (original) +++ cfe/trunk/include/clang/Basic/AttrDocs.td Fri May 18 13:18:17 2018 @@ -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 = [{ Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=332760&r1=332759&r2=332760&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri May 18 13:18:17 2018 @@ -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< Modified: cfe/trunk/include/clang/Sema/Sema.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=332760&r1=332759&r2=332760&view=diff ============================================================================== --- cfe/trunk/include/clang/Sema/Sema.h (original) +++ cfe/trunk/include/clang/Sema/Sema.h Fri May 18 13:18:17 2018 @@ -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(); Modified: cfe/trunk/lib/Sema/SemaDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=332760&r1=332759&r2=332760&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri May 18 13:18:17 2018 @@ -2667,14 +2667,9 @@ void Sema::mergeDeclAttributes(NamedDecl 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, 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, 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. /// Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=332760&r1=332759&r2=332760&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original) +++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Fri May 18 13:18:17 2018 @@ -2853,13 +2853,6 @@ static void handleVecTypeHint(Sema &S, D 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, De 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 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; Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=332760&r1=332759&r2=332760&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original) +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Fri May 18 13:18:17 2018 @@ -2231,20 +2231,6 @@ Sema::CheckBaseSpecifier(CXXRecordDecl * 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 checkForMultipleExportedDefa } } -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(CXXRec } checkClassLevelDLLAttribute(Record); - checkClassLevelSectionAttribute(Record); bool ClangABICompat4 = Context.getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver4; @@ -14556,16 +14531,6 @@ bool Sema::CheckOverridingFunctionAttrib 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(); Modified: cfe/trunk/lib/Sema/SemaLambda.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLambda.cpp?rev=332760&r1=332759&r2=332760&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaLambda.cpp (original) +++ cfe/trunk/lib/Sema/SemaLambda.cpp Fri May 18 13:18:17 2018 @@ -910,10 +910,6 @@ void Sema::ActOnStartOfLambdaDefinition( 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 Removed: cfe/trunk/test/CodeGenCXX/code_seg1.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/code_seg1.cpp?rev=332759&view=auto ============================================================================== --- cfe/trunk/test/CodeGenCXX/code_seg1.cpp (original) +++ cfe/trunk/test/CodeGenCXX/code_seg1.cpp (removed) @@ -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" Removed: cfe/trunk/test/CodeGenCXX/code_seg2.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/code_seg2.cpp?rev=332759&view=auto ============================================================================== --- cfe/trunk/test/CodeGenCXX/code_seg2.cpp (original) +++ cfe/trunk/test/CodeGenCXX/code_seg2.cpp (removed) @@ -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" Removed: cfe/trunk/test/CodeGenCXX/code_seg3.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/code_seg3.cpp?rev=332759&view=auto ============================================================================== --- cfe/trunk/test/CodeGenCXX/code_seg3.cpp (original) +++ cfe/trunk/test/CodeGenCXX/code_seg3.cpp (removed) @@ -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" Removed: cfe/trunk/test/CodeGenCXX/code_seg4.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/code_seg4.cpp?rev=332759&view=auto ============================================================================== --- cfe/trunk/test/CodeGenCXX/code_seg4.cpp (original) +++ cfe/trunk/test/CodeGenCXX/code_seg4.cpp (removed) @@ -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" Copied: cfe/trunk/test/SemaCXX/attr-section.cpp (from r332757, cfe/trunk/test/Sema/attr-section.c) URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-section.cpp?p2=cfe/trunk/test/SemaCXX/attr-section.cpp&p1=cfe/trunk/test/Sema/attr-section.c&r1=332757&r2=332760&rev=332760&view=diff ============================================================================== --- cfe/trunk/test/Sema/attr-section.c (original) +++ cfe/trunk/test/SemaCXX/attr-section.cpp Fri May 18 13:18:17 2018 @@ -1,13 +1,9 @@ -// RUN: %clang_cc1 -verify -fsyntax-only -triple x86_64-apple-darwin9 %s +// RUN: %clang_cc1 -verify -fsyntax-only -triple x86_64-linux-gnu %s int x __attribute__((section( 42))); // expected-error {{'section' attribute requires a string}} -// rdar://4341926 -int y __attribute__((section( - "sadf"))); // expected-error {{mach-o section specifier requires a segment and section separated by a comma}} - // 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}} @@ -15,8 +11,8 @@ void test() { } // pr9356 -void __attribute__((section("foo,zed"))) test2(void); // expected-note {{previous attribute is here}} -void __attribute__((section("bar,zed"))) test2(void) {} // expected-warning {{section does not match previous declaration}} +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}} @@ -25,10 +21,24 @@ int *b = &a; extern int a __attribute__((section("foo,zed"))); // expected-warning {{section attribute is specified on redeclared variable}} // Not a warning. -int c; +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() {} +} Removed: cfe/trunk/test/SemaCXX/code_seg.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/code_seg.cpp?rev=332759&view=auto ============================================================================== --- cfe/trunk/test/SemaCXX/code_seg.cpp (original) +++ cfe/trunk/test/SemaCXX/code_seg.cpp (removed) @@ -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; } -}; Removed: cfe/trunk/test/SemaCXX/code_seg1.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/code_seg1.cpp?rev=332759&view=auto ============================================================================== --- cfe/trunk/test/SemaCXX/code_seg1.cpp (original) +++ cfe/trunk/test/SemaCXX/code_seg1.cpp (removed) @@ -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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits