1*7963e8beSErich Keane // RUN: %clang_cc1 -fsyntax-only -verify -fms-extensions %s -triple x86_64-pc-win32 2*7963e8beSErich Keane 3*7963e8beSErich Keane struct __declspec(code_seg("my_one")) FooOne { 4*7963e8beSErich Keane int barC(); 5*7963e8beSErich Keane }; 6*7963e8beSErich Keane 7*7963e8beSErich Keane struct FooTwo { 8*7963e8beSErich Keane int __declspec(code_seg("my_three")) barD(); 9*7963e8beSErich Keane int barE(); 10*7963e8beSErich Keane }; barC()11*7963e8beSErich Keaneint __declspec(code_seg("my_four")) FooOne::barC() { return 10; } 12*7963e8beSErich Keane // expected-warning@-1 {{codeseg does not match previous declaration}} 13*7963e8beSErich Keane // expected-note@3{{previous attribute is here}} barD()14*7963e8beSErich Keaneint __declspec(code_seg("my_five")) FooTwo::barD() { return 20; } 15*7963e8beSErich Keane // expected-warning@-1 {{codeseg does not match previous declaration}} 16*7963e8beSErich Keane // expected-note@8 {{previous attribute is here}} barE()17*7963e8beSErich Keaneint __declspec(code_seg("my_six")) FooTwo::barE() { return 30; } 18*7963e8beSErich Keane // expected-warning@-1 {{codeseg does not match previous declaration}} 19*7963e8beSErich Keane // expected-note@9 {{previous declaration is here}} 20*7963e8beSErich Keane 21*7963e8beSErich Keane // Microsoft docs say: 22*7963e8beSErich Keane // If a base-class has a code_seg attribute, derived classes must have the 23*7963e8beSErich Keane // same attribute. 24*7963e8beSErich Keane struct __declspec(code_seg("my_base")) Base1 {}; 25*7963e8beSErich Keane struct Base2 {}; 26*7963e8beSErich Keane 27*7963e8beSErich Keane struct D1 : Base1 {}; 28*7963e8beSErich Keane //expected-error@-1 {{derived class must specify the same code segment as its base classes}} 29*7963e8beSErich Keane // expected-note@24 {{base class 'Base1' specified here}} 30*7963e8beSErich Keane struct __declspec(code_seg("my_derived")) D2 : Base1 {}; 31*7963e8beSErich Keane // expected-error@-1 {{derived class must specify the same code segment as its base classes}} 32*7963e8beSErich Keane // expected-note@24 {{base class 'Base1' specified here}} 33*7963e8beSErich Keane struct __declspec(code_seg("my_derived")) D3 : Base2 {}; 34*7963e8beSErich Keane // expected-error@-1 {{derived class must specify the same code segment as its base classes}} 35*7963e8beSErich Keane // expected-note@25 {{base class 'Base2' specified here}} 36*7963e8beSErich Keane 37*7963e8beSErich Keane template <typename T> struct __declspec(code_seg("my_base")) MB : T { }; 38*7963e8beSErich Keane template <typename T> struct __declspec(code_seg("my_derived")) MD : T { }; 39*7963e8beSErich Keane MB<Base1> mb1; // ok 40*7963e8beSErich Keane MB<Base2> mb2; 41*7963e8beSErich Keane // expected-error@37 {{derived class must specify the same code segment as its base classes}} 42*7963e8beSErich Keane // expected-note@-2 {{in instantiation of template class}} 43*7963e8beSErich Keane // expected-note@25 {{base class 'Base2' specified here}} 44*7963e8beSErich Keane MD<Base1> md1; 45*7963e8beSErich Keane // expected-error@38 {{derived class must specify the same code segment as its base classes}} 46*7963e8beSErich Keane // expected-note@-2 {{in instantiation of template class}} 47*7963e8beSErich Keane // expected-note@24 {{base class 'Base1' specified here}} 48*7963e8beSErich Keane MD<Base2> md2; 49*7963e8beSErich Keane // expected-error@38 {{derived class must specify the same code segment as its base classes}} 50*7963e8beSErich Keane // expected-note@-2 {{in instantiation of template class}} 51*7963e8beSErich Keane // expected-note@25 {{base class 'Base2' specified here}} 52*7963e8beSErich Keane 53*7963e8beSErich Keane // Virtual overrides must have the same code_seg. 54*7963e8beSErich Keane struct __declspec(code_seg("my_one")) Base3 { barABase355*7963e8beSErich Keane virtual int barA() { return 1; } barBBase356*7963e8beSErich Keane virtual int __declspec(code_seg("my_two")) barB() { return 2; } 57*7963e8beSErich Keane }; 58*7963e8beSErich Keane struct __declspec(code_seg("my_one")) Derived3 : Base3 { barADerived359*7963e8beSErich Keane int barA() { return 4; } // ok barBDerived360*7963e8beSErich Keane int barB() { return 6; } 61*7963e8beSErich Keane // expected-error@-1 {{overriding virtual function must specify the same code segment as its overridden function}} 62*7963e8beSErich Keane // expected-note@56 {{previous declaration is here}} 63*7963e8beSErich Keane }; 64*7963e8beSErich Keane 65*7963e8beSErich Keane struct Base4 { barABase466*7963e8beSErich Keane virtual int __declspec(code_seg("my_one")) barA() {return 1;} barBBase467*7963e8beSErich Keane virtual int barB() { return 2;} 68*7963e8beSErich Keane }; 69*7963e8beSErich Keane struct Derived4 : Base4 { barADerived470*7963e8beSErich Keane virtual int barA() {return 1;} 71*7963e8beSErich Keane // expected-error@-1 {{overriding virtual function must specify the same code segment as its overridden function}} 72*7963e8beSErich Keane // expected-note@66 {{previous declaration is here}} barBDerived473*7963e8beSErich Keane virtual int __declspec(code_seg("my_two")) barB() {return 1;} 74*7963e8beSErich Keane // expected-error@-1 {{overriding virtual function must specify the same code segment as its overridden function}} 75*7963e8beSErich Keane // expected-note@67 {{previous declaration is here}} 76*7963e8beSErich Keane }; 77*7963e8beSErich Keane 78*7963e8beSErich Keane // MS gives an error when different code segments are used but a warning when a duplicate is used 79*7963e8beSErich Keane 80*7963e8beSErich Keane // Function bar1()81*7963e8beSErich Keaneint __declspec(code_seg("foo")) __declspec(code_seg("foo")) bar1() { return 1; } 82*7963e8beSErich Keane // expected-warning@-1 {{duplicate code segment specifiers}} bar2()83*7963e8beSErich Keaneint __declspec(code_seg("foo")) __declspec(code_seg("bar")) bar2() { return 1; } 84*7963e8beSErich Keane // expected-error@-1 {{conflicting code segment specifiers}} 85*7963e8beSErich Keane 86*7963e8beSErich Keane // Class 87*7963e8beSErich Keane struct __declspec(code_seg("foo")) __declspec(code_seg("foo")) Foo { 88*7963e8beSErich Keane // expected-warning@-1 {{duplicate code segment specifiers}} bar3Foo89*7963e8beSErich Keane int bar3() {return 0;} 90*7963e8beSErich Keane }; 91*7963e8beSErich Keane struct __declspec(code_seg("foo")) __declspec(code_seg("bar")) FooSix { 92*7963e8beSErich Keane // expected-error@-1 {{conflicting code segment specifiers}} bar3FooSix93*7963e8beSErich Keane int bar3() {return 0;} 94*7963e8beSErich Keane }; 95*7963e8beSErich Keane 96*7963e8beSErich Keane //Class Members 97*7963e8beSErich Keane struct FooThree { bar1FooThree98*7963e8beSErich Keane int __declspec(code_seg("foo")) __declspec(code_seg("foo")) bar1() { return 1; } 99*7963e8beSErich Keane // expected-warning@-1 {{duplicate code segment specifiers}} bar2FooThree100*7963e8beSErich Keane int __declspec(code_seg("foo")) __declspec(code_seg("bar")) bar2() { return 1; } 101*7963e8beSErich Keane // expected-error@-1 {{conflicting code segment specifiers}} 102*7963e8beSErich Keane int bar8(); bar9FooThree103*7963e8beSErich Keane int bar9() { return 9; } 104*7963e8beSErich Keane }; 105*7963e8beSErich Keane 106