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()87void testTemplateClass() 88 { 89 tmplClassForParam<Param> paramClass; 90 Param param; 91 paramClass.raw(param); 92 paramClass.rawDefault(); 93 paramClass.const_(param); 94 paramClass.ptr(¶m); 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()134void 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)142void tmplFuncForParam(T x) {} 143 template <typename T> tmplFuncForNonParam(T x)144void 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)146void 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)148void 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)150void tmplFuncForHasNonParamStructImplicit(T x) {} //expected-error {{Type 'HasNonParamStruct' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}} 151 testTemplateFunc()152void 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()166void 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)184void 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)185void 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)188void 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)189void takesAlignasMemberByRef(const AlignasMember& x) { } 190