1 #define MOZ_NON_PARAM __attribute__((annotate("moz_non_param")))
2 
3 struct Param {};
4 struct MOZ_NON_PARAM NonParam {};
5 union MOZ_NON_PARAM NonParamUnion {};
6 class MOZ_NON_PARAM NonParamClass {};
7 enum MOZ_NON_PARAM NonParamEnum { X, Y, Z };
8 enum class MOZ_NON_PARAM NonParamEnumClass { X, Y, Z };
9 
10 struct HasNonParamStruct { NonParam x; int y; }; // expected-note 14 {{'HasNonParamStruct' is a non-param type because member 'x' is a non-param type 'NonParam'}}
11 union HasNonParamUnion { NonParam x; int y; }; // expected-note 18 {{'HasNonParamUnion' is a non-param type because member 'x' is a non-param type 'NonParam'}}
12 struct HasNonParamStructUnion { HasNonParamUnion z; }; // expected-note 9 {{'HasNonParamStructUnion' is a non-param type because member 'z' is a non-param type 'HasNonParamUnion'}}
13 
14 #define MAYBE_STATIC
15 #include "NonParameterTestCases.h"
16 #undef MAYBE_STATIC
17 
18 // Do not check typedef and using.
19 typedef void (*funcTypeParam)(Param x);
20 typedef void (*funcTypeNonParam)(NonParam x);
21 
22 using usingFuncTypeParam = void (*)(Param x);
23 using usingFuncTypeNonParam = void (*)(NonParam x);
24 
25 class class_
26 {
class_(Param x)27     explicit class_(Param x) {}
class_(NonParam x)28     explicit class_(NonParam x) {} //expected-error {{Type 'NonParam' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
class_(HasNonParamStruct x)29     explicit class_(HasNonParamStruct x) {} //expected-error {{Type 'HasNonParamStruct' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
class_(HasNonParamUnion x)30     explicit class_(HasNonParamUnion x) {} //expected-error {{Type 'HasNonParamUnion' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
class_(HasNonParamStructUnion x)31     explicit class_(HasNonParamStructUnion x) {} //expected-error {{Type 'HasNonParamStructUnion' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
32 
33 #define MAYBE_STATIC
34 #include "NonParameterTestCases.h"
35 #undef MAYBE_STATIC
36 };
37 
38 class classWithStatic
39 {
40 #define MAYBE_STATIC static
41 #include "NonParameterTestCases.h"
42 #undef MAYBE_STATIC
43 };
44 
45 template <typename T>
46 class tmplClassForParam
47 {
48 public:
raw(T x)49     void raw(T x) {}
rawDefault(T x=T ())50     void rawDefault(T x = T()) {}
const_(const T x)51     void const_(const T x) {}
ptr(T * x)52     void ptr(T* x) {}
ref(T & x)53     void ref(T& x) {}
constRef(const T & x)54     void constRef(const T& x) {}
55 
notCalled(T x)56     void notCalled(T x) {}
57 };
58 
59 template <typename T>
60 class tmplClassForNonParam
61 {
62 public:
raw(T x)63     void raw(T x) {} //expected-error {{Type 'NonParam' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
rawDefault(T x=T ())64     void rawDefault(T x = T()) {} //expected-error {{Type 'NonParam' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
const_(const T x)65     void const_(const T x) {} //expected-error {{Type 'NonParam' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
ptr(T * x)66     void ptr(T* x) {}
ref(T & x)67     void ref(T& x) {}
constRef(const T & x)68     void constRef(const T& x) {}
69 
notCalled(T x)70     void notCalled(T x) {}
71 };
72 
73 template <typename T>
74 class tmplClassForHasNonParamStruct
75 {
76 public:
raw(T x)77     void raw(T x) {} //expected-error {{Type 'HasNonParamStruct' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
rawDefault(T x=T ())78     void rawDefault(T x = T()) {} //expected-error {{Type 'HasNonParamStruct' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
const_(const T x)79     void const_(const T x) {} //expected-error {{Type 'HasNonParamStruct' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
ptr(T * x)80     void ptr(T* x) {}
ref(T & x)81     void ref(T& x) {}
constRef(const T & x)82     void constRef(const T& x) {}
83 
notCalled(T x)84     void notCalled(T x) {}
85 };
86 
testTemplateClass()87 void testTemplateClass()
88 {
89     tmplClassForParam<Param> paramClass;
90     Param param;
91     paramClass.raw(param);
92     paramClass.rawDefault();
93     paramClass.const_(param);
94     paramClass.ptr(&param);
95     paramClass.ref(param);
96     paramClass.constRef(param);
97 
98     tmplClassForNonParam<NonParam> nonParamClass; //expected-note 3 {{The bad argument was passed to 'tmplClassForNonParam' here}}
99     NonParam nonParam;
100     nonParamClass.raw(nonParam);
101     nonParamClass.rawDefault();
102     nonParamClass.const_(nonParam);
103     nonParamClass.ptr(&nonParam);
104     nonParamClass.ref(nonParam);
105     nonParamClass.constRef(nonParam);
106 
107     tmplClassForHasNonParamStruct<HasNonParamStruct> hasNonParamStructClass;//expected-note 3 {{The bad argument was passed to 'tmplClassForHasNonParamStruct' here}}
108     HasNonParamStruct hasNonParamStruct;
109     hasNonParamStructClass.raw(hasNonParamStruct);
110     hasNonParamStructClass.rawDefault();
111     hasNonParamStructClass.const_(hasNonParamStruct);
112     hasNonParamStructClass.ptr(&hasNonParamStruct);
113     hasNonParamStructClass.ref(hasNonParamStruct);
114     hasNonParamStructClass.constRef(hasNonParamStruct);
115 }
116 
117 template <typename T>
118 class NestedTemplateInner
119 {
120 public:
raw(T x)121     void raw(T x) {} //expected-error {{Type 'NonParam' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
122 };
123 
124 template <typename T>
125 class nestedTemplateOuter
126 {
127 public:
constRef(const T & x)128     void constRef(const T& x) {
129         NestedTemplateInner<T> inner; //expected-note {{The bad argument was passed to 'NestedTemplateInner' here}}
130         inner.raw(x);
131     }
132 };
133 
testNestedTemplateClass()134 void testNestedTemplateClass()
135 {
136     nestedTemplateOuter<NonParam> outer;
137     NonParam nonParam;
138     outer.constRef(nonParam); // FIXME: this line needs note "The bad argument was passed to 'constRef' here"
139 }
140 
141 template <typename T>
tmplFuncForParam(T x)142 void tmplFuncForParam(T x) {}
143 template <typename T>
tmplFuncForNonParam(T x)144 void tmplFuncForNonParam(T x) {} //expected-error {{Type 'NonParam' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
145 template <typename T>
tmplFuncForNonParamImplicit(T x)146 void tmplFuncForNonParamImplicit(T x) {} //expected-error {{Type 'NonParam' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
147 template <typename T>
tmplFuncForHasNonParamStruct(T x)148 void tmplFuncForHasNonParamStruct(T x) {} //expected-error {{Type 'HasNonParamStruct' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
149 template <typename T>
tmplFuncForHasNonParamStructImplicit(T x)150 void tmplFuncForHasNonParamStructImplicit(T x) {} //expected-error {{Type 'HasNonParamStruct' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
151 
testTemplateFunc()152 void testTemplateFunc()
153 {
154     Param param;
155     tmplFuncForParam<Param>(param);
156 
157     NonParam nonParam;
158     tmplFuncForNonParam<NonParam>(nonParam); // FIXME: this line needs note "The bad argument was passed to 'tmplFuncForNonParam' here"
159     tmplFuncForNonParamImplicit(nonParam); // FIXME: this line needs note "The bad argument was passed to 'tmplFuncForNonParamImplicit' here"
160 
161     HasNonParamStruct hasNonParamStruct;
162     tmplFuncForHasNonParamStruct<HasNonParamStruct>(hasNonParamStruct); // FIXME: this line needs note "The bad argument was passed to 'tmplFuncForHasNonParamStruct' here"
163     tmplFuncForHasNonParamStructImplicit(hasNonParamStruct); // FIXME: this line needs note "The bad argument was passed to 'tmplFuncForHasNonParamStructImplicit' here"
164 }
165 
testLambda()166 void testLambda()
167 {
168     auto paramLambda = [](Param x) -> void {};
169     auto nonParamLambda = [](NonParam x) -> void {}; //expected-error {{Type 'NonParam' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
170     auto nonParamStructLambda = [](HasNonParamStruct x) -> void {}; //expected-error {{Type 'HasNonParamStruct' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
171     auto nonParamUnionLambda = [](HasNonParamUnion x) -> void {}; //expected-error {{Type 'HasNonParamUnion' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
172     auto nonParamStructUnionLambda = [](HasNonParamStructUnion x) -> void {}; //expected-error {{Type 'HasNonParamStructUnion' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
173 
174     (void)[](Param x) -> void {};
175     (void)[](NonParam x) -> void {}; //expected-error {{Type 'NonParam' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
176     (void)[](HasNonParamStruct x) -> void {}; //expected-error {{Type 'HasNonParamStruct' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
177     (void)[](HasNonParamUnion x) -> void {}; //expected-error {{Type 'HasNonParamUnion' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
178     (void)[](HasNonParamStructUnion x) -> void {}; //expected-error {{Type 'HasNonParamStructUnion' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
179 }
180 
181 // Check that alignas() implies the MOZ_NON_PARAM attribute.
182 
183 struct alignas(8) AlignasStruct { char a; }; // expected-note {{'AlignasStruct' is a non-param type because it has an alignas(_) annotation}}
takesAlignasStruct(AlignasStruct x)184 void takesAlignasStruct(AlignasStruct x) { } // expected-error {{Type 'AlignasStruct' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
takesAlignasStructByRef(const AlignasStruct & x)185 void takesAlignasStructByRef(const AlignasStruct& x) { }
186 
187 struct AlignasMember { alignas(8) char a; }; // expected-note {{'AlignasMember' is a non-param type because member 'a' has an alignas(_) annotation}}
takesAlignasMember(AlignasMember x)188 void takesAlignasMember(AlignasMember x) { } // expected-error {{Type 'AlignasMember' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
takesAlignasMemberByRef(const AlignasMember & x)189 void takesAlignasMemberByRef(const AlignasMember& x) { }
190