xref: /llvm-project/clang/test/SemaCXX/code-seg.cpp (revision 7963e8bebb90543d997bf99ae5f8cf9be579d9ea)
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 Keane int __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 Keane int __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 Keane int __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 Keane int __declspec(code_seg("foo")) __declspec(code_seg("foo")) bar1() { return 1; }
82*7963e8beSErich Keane // expected-warning@-1 {{duplicate code segment specifiers}}
bar2()83*7963e8beSErich Keane int __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