1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
|
// RUN: %check_clang_tidy %s bugprone-easily-swappable-parameters %t \
// RUN: -config='{CheckOptions: [ \
// RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 2}, \
// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: "bool;MyBool;struct U;MAKE_LOGICAL_TYPE(int)"}, \
// RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 0}, \
// RUN: {key: bugprone-easily-swappable-parameters.ModelImplicitConversions, value: 0}, \
// RUN: {key: bugprone-easily-swappable-parameters.SuppressParametersUsedTogether, value: 0}, \
// RUN: {key: bugprone-easily-swappable-parameters.NamePrefixSuffixSilenceDissimilarityTreshold, value: 0} \
// RUN: ]}' -- -Wno-strict-prototypes -x c
#define bool _Bool
#define true 1
#define false 0
typedef bool MyBool;
#define TheLogicalType bool
void declVoid(void); // NO-WARN: Declaration only.
void decl(); // NO-WARN: Declaration only.
void oneParam(int I) {} // NO-WARN: 1 parameter.
void variadic(int I, ...) {} // NO-WARN: 1 visible parameter.
void trivial(int I, int J) {}
// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: 2 adjacent parameters of 'trivial' of similar type ('int') are easily swapped by mistake [bugprone-easily-swappable-parameters]
// CHECK-MESSAGES: :[[@LINE-2]]:18: note: the first parameter in the range is 'I'
// CHECK-MESSAGES: :[[@LINE-3]]:25: note: the last parameter in the range is 'J'
void qualifier(int I, const int CI) {} // NO-WARN: Distinct types.
void restrictQualifier(char *restrict CPR1, char *restrict CPR2) {}
// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: 2 adjacent parameters of 'restrictQualifier' of similar type ('char *restrict')
// CHECK-MESSAGES: :[[@LINE-2]]:39: note: the first parameter in the range is 'CPR1'
// CHECK-MESSAGES: :[[@LINE-3]]:60: note: the last parameter in the range is 'CPR2'
void pointer1(int *IP1, int *IP2) {}
// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: 2 adjacent parameters of 'pointer1' of similar type ('int *')
// CHECK-MESSAGES: :[[@LINE-2]]:20: note: the first parameter in the range is 'IP1'
// CHECK-MESSAGES: :[[@LINE-3]]:30: note: the last parameter in the range is 'IP2'
void pointerConversion(int *IP, long *LP) {}
// NO-WARN: Even though C can convert any T* to U* back and forth, compiler
// warnings already exist for this.
void testVariadicsCall() {
int IVal = 1;
decl(IVal); // NO-WARN: Particular calls to "variadics" are like template
// instantiations, and we do not model them.
variadic(IVal); // NO-WARN.
variadic(IVal, 2, 3, 4); // NO-WARN.
}
struct S {};
struct T {};
void taggedTypes1(struct S SVar, struct T TVar) {} // NO-WARN: Distinct types.
void taggedTypes2(struct S SVar1, struct S SVar2) {}
// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: 2 adjacent parameters of 'taggedTypes2' of similar type ('struct S')
// CHECK-MESSAGES: :[[@LINE-2]]:28: note: the first parameter in the range is 'SVar1'
// CHECK-MESSAGES: :[[@LINE-3]]:44: note: the last parameter in the range is 'SVar2'
void wrappers(struct { int I; } I1, struct { int I; } I2) {} // NO-WARN: Distinct anonymous types.
void knr(I, J)
int I;
int J;
{}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: 2 adjacent parameters of 'knr' of similar type ('int')
// CHECK-MESSAGES: :[[@LINE-4]]:7: note: the first parameter in the range is 'I'
// CHECK-MESSAGES: :[[@LINE-4]]:7: note: the last parameter in the range is 'J'
void boolAsWritten(bool B1, bool B2) {} // NO-WARN: The type name is ignored.
// Note that "bool" is a macro that expands to "_Bool" internally, but it is
// only "bool" that is ignored from the two.
void underscoreBoolAsWritten(_Bool B1, _Bool B2) {}
// Even though it is "_Bool" that is written in the code, the diagnostic message
// respects the printing policy as defined by the compilation commands. Clang's
// default in C mode seems to say that the type itself is "bool", not "_Bool".
// CHECK-MESSAGES: :[[@LINE-4]]:30: warning: 2 adjacent parameters of 'underscoreBoolAsWritten' of similar type ('bool')
// CHECK-MESSAGES: :[[@LINE-5]]:36: note: the first parameter in the range is 'B1'
// CHECK-MESSAGES: :[[@LINE-6]]:46: note: the last parameter in the range is 'B2'
void typedefdBoolAsWritten(MyBool MB1, MyBool MB2) {} // NO-WARN: "MyBool" as written type name ignored.
void otherBoolMacroAsWritten(TheLogicalType TLT1, TheLogicalType TLT2) {}
// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: 2 adjacent parameters of 'otherBoolMacroAsWritten' of similar type ('bool')
// CHECK-MESSAGES: :[[@LINE-2]]:45: note: the first parameter in the range is 'TLT1'
// CHECK-MESSAGES: :[[@LINE-3]]:66: note: the last parameter in the range is 'TLT2'
struct U {};
typedef struct U U;
void typedefStruct(U X, U Y) {}
// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: 2 adjacent parameters of 'typedefStruct' of similar type ('U')
// CHECK-MESSAGES: :[[@LINE-2]]:22: note: the first parameter in the range is 'X'
// CHECK-MESSAGES: :[[@LINE-3]]:27: note: the last parameter in the range is 'Y'
void ignoredStructU(struct U X, struct U Y) {} // NO-WARN: "struct U" ignored.
#define TYPE_TAG_TO_USE struct // We are in C!
#define MAKE_TYPE_NAME(T) TYPE_TAG_TO_USE T
void macroMagic1(TYPE_TAG_TO_USE T X, TYPE_TAG_TO_USE T Y) {}
// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: 2 adjacent parameters of 'macroMagic1' of similar type ('struct T')
// CHECK-MESSAGES: :[[@LINE-5]]:25: note: expanded from macro 'TYPE_TAG_TO_USE'
// CHECK-MESSAGES: :[[@LINE-3]]:36: note: the first parameter in the range is 'X'
// CHECK-MESSAGES: :[[@LINE-4]]:57: note: the last parameter in the range is 'Y'
void macroMagic2(TYPE_TAG_TO_USE U X, TYPE_TAG_TO_USE U Y) {}
// "struct U" is ignored, but that is not what is written here!
// CHECK-MESSAGES: :[[@LINE-2]]:18: warning: 2 adjacent parameters of 'macroMagic2' of similar type ('struct U')
// CHECK-MESSAGES: :[[@LINE-12]]:25: note: expanded from macro 'TYPE_TAG_TO_USE'
// CHECK-MESSAGES: :[[@LINE-4]]:36: note: the first parameter in the range is 'X'
// CHECK-MESSAGES: :[[@LINE-5]]:57: note: the last parameter in the range is 'Y'
void evenMoreMacroMagic1(MAKE_TYPE_NAME(T) X, MAKE_TYPE_NAME(T) Y) {}
// CHECK-MESSAGES: :[[@LINE-1]]:26: warning: 2 adjacent parameters of 'evenMoreMacroMagic1' of similar type ('struct T')
// CHECK-MESSAGES: :[[@LINE-17]]:27: note: expanded from macro 'MAKE_TYPE_NAME'
// CHECK-MESSAGES: :[[@LINE-19]]:25: note: expanded from macro 'TYPE_TAG_TO_USE'
// CHECK-MESSAGES: :[[@LINE-4]]:44: note: the first parameter in the range is 'X'
// CHECK-MESSAGES: :[[@LINE-5]]:65: note: the last parameter in the range is 'Y'
void evenMoreMacroMagic2(MAKE_TYPE_NAME(U) X, MAKE_TYPE_NAME(U) Y) {}
// "struct U" is ignored, but that is not what is written here!
// CHECK-MESSAGES: :[[@LINE-2]]:26: warning: 2 adjacent parameters of 'evenMoreMacroMagic2' of similar type ('struct U')
// CHECK-MESSAGES: :[[@LINE-25]]:27: note: expanded from macro 'MAKE_TYPE_NAME'
// CHECK-MESSAGES: :[[@LINE-27]]:25: note: expanded from macro 'TYPE_TAG_TO_USE'
// CHECK-MESSAGES: :[[@LINE-5]]:44: note: the first parameter in the range is 'X'
// CHECK-MESSAGES: :[[@LINE-6]]:65: note: the last parameter in the range is 'Y'
#define MAKE_PRIMITIVE_WRAPPER(WRAPPED_TYPE) \
MAKE_TYPE_NAME() { \
WRAPPED_TYPE Member; \
}
void thisIsGettingRidiculous(MAKE_PRIMITIVE_WRAPPER(int) I1,
MAKE_PRIMITIVE_WRAPPER(int) I2) {} // NO-WARN: Distinct anonymous types.
#define MAKE_LOGICAL_TYPE(X) bool
void macroMagic3(MAKE_LOGICAL_TYPE(char) B1, MAKE_LOGICAL_TYPE(long) B2) {}
// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: 2 adjacent parameters of 'macroMagic3' of similar type ('bool')
// CHECK-MESSAGES: :[[@LINE-4]]:30: note: expanded from macro 'MAKE_LOGICAL_TYPE'
// CHECK-MESSAGES: :[[@LINE-136]]:14: note: expanded from macro 'bool'
// CHECK-MESSAGES: :[[@LINE-4]]:42: note: the first parameter in the range is 'B1'
// CHECK-MESSAGES: :[[@LINE-5]]:70: note: the last parameter in the range is 'B2'
void macroMagic4(MAKE_LOGICAL_TYPE(int) B1, MAKE_LOGICAL_TYPE(int) B2) {} // NO-WARN: "Type name" ignored.
|