brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.0 KiB · cdc32eb Raw
384 lines · c
1// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-config suppress-null-return-paths=false -verify %s2// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify -DSUPPRESSED=1 %s3// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-config avoid-suppressing-null-argument-paths=true -DSUPPRESSED=1 -DNULL_ARGS=1 -verify %s4 5int opaquePropertyCheck(void *object);6int coin(void);7 8int *getNull(void) {9  return 0;10}11 12int* getPtr(void);13 14int *dynCastToInt(void *ptr) {15  if (opaquePropertyCheck(ptr))16    return (int *)ptr;17  return 0;18}19 20int *dynCastOrNull(void *ptr) {21  if (!ptr)22    return 0;23  if (opaquePropertyCheck(ptr))24    return (int *)ptr;25  return 0;26}27 28 29void testDynCast(void *p) {30  int *casted = dynCastToInt(p);31  *casted = 1;32#ifndef SUPPRESSED33  // expected-warning@-2 {{Dereference of null pointer}}34#endif35}36 37void testDynCastOrNull(void *p) {38  int *casted = dynCastOrNull(p);39  *casted = 1;40#ifndef SUPPRESSED41  // expected-warning@-2 {{Dereference of null pointer}}42#endif43}44 45 46void testBranch(void *p) {47  int *casted;48 49  // Although the report will be suppressed on one branch, it should still be50  // valid on the other.51  if (coin()) {52    casted = dynCastToInt(p);53  } else {54    if (p)55      return;56    casted = (int *)p;57  }58 59  *casted = 1; // expected-warning {{Dereference of null pointer}}60}61 62void testBranchReversed(void *p) {63  int *casted;64 65  // Although the report will be suppressed on one branch, it should still be66  // valid on the other.67  if (coin()) {68    if (p)69      return;70    casted = (int *)p;71  } else {72    casted = dynCastToInt(p);73  }74 75  *casted = 1; // expected-warning {{Dereference of null pointer}}76}77 78void testMultipleStore(void *p) {79  int *casted = 0;80  casted = dynCastToInt(p);81  *casted = 1;82#ifndef SUPPRESSED83  // expected-warning@-2 {{Dereference of null pointer}}84#endif85}86 87// Test that div by zero does not get suppressed. This is a policy choice.88int retZero(void) {89  return 0;90}91int triggerDivZero (void) {92  int y = retZero();93  return 5/y; // expected-warning {{Division by zero}}94}95 96// Treat a function-like macro similarly to an inlined function, so suppress97// warnings along paths resulting from inlined checks.98#define MACRO_WITH_CHECK(a) ( ((a) != 0) ? *a : 17)99void testInlineCheckInMacro(int *p) {100  int i = MACRO_WITH_CHECK(p);101  (void)i;102 103  *p = 1; // no-warning104}105 106#define MACRO_WITH_NESTED_CHECK(a) ( { int j = MACRO_WITH_CHECK(a); j; } )107void testInlineCheckInNestedMacro(int *p) {108  int i = MACRO_WITH_NESTED_CHECK(p);109  (void)i;110 111  *p = 1; // no-warning112}113 114#define NON_FUNCTION_MACRO_WITH_CHECK ( ((p) != 0) ? *p : 17)115void testNonFunctionMacro(int *p) {116  int i = NON_FUNCTION_MACRO_WITH_CHECK ;117  (void)i;118 119  *p = 1; // no-warning120}121 122 123// This macro will dereference its argument if the argument is NULL.124#define MACRO_WITH_ERROR(a) ( ((a) != 0) ? 0 : *a)125void testErrorInMacro(int *p) {126  int i = MACRO_WITH_ERROR(p); // expected-warning {{Dereference of null pointer (loaded from variable 'p')}}127  (void)i;128}129 130// Here the check (the "if") is not in a macro, so we should still warn.131#define MACRO_IN_GUARD(a) (!(a))132void testMacroUsedAsGuard(int *p) {133  if (MACRO_IN_GUARD(p))134    *p = 1; // expected-warning {{Dereference of null pointer (loaded from variable 'p')}}135}136 137// When a nil case split is introduced in a macro and the macro is in a guard,138// we still shouldn't warn.139int isNull(int *p);140int isEqual(int *p, int *q);141#define ISNULL(ptr)    ((ptr) == 0 || isNull(ptr))142#define ISEQUAL(a, b)    ((int *)(a) == (int *)(b) || (ISNULL(a) && ISNULL(b)) || isEqual(a,b))143#define ISNOTEQUAL(a, b)   (!ISEQUAL(a, b))144void testNestedDisjunctiveMacro(int *p, int *q) {145  if (ISNOTEQUAL(p,q)) {146    *p = 1; // no-warning147    *q = 1; // no-warning148  }149 150  *p = 1; // no-warning151  *q = 1; // no-warning152}153 154void testNestedDisjunctiveMacro2(int *p, int *q) {155  if (ISEQUAL(p,q)) {156    return;157  }158 159  *p = 1; // no-warning160  *q = 1; // no-warning161}162 163 164 165// Here the check is entirely in non-macro code even though the code itself166// is a macro argument.167#define MACRO_DO_IT(a) (a)168void testErrorInArgument(int *p) {169  int i = MACRO_DO_IT((p ? 0 : *p)); // expected-warning {{Dereference of null pointer (loaded from variable 'p')}}c170  (void)i;171}172 173// No warning should be emitted if dereference is performed from a different174// macro.175#define MACRO_CHECK(a) if (a) {}176#define MACRO_DEREF(a) (*a)177int testDifferentMacro(int *p) {178  MACRO_CHECK(p);179  return MACRO_DEREF(p); // no-warning180}181 182// --------------------------183// "Suppression suppression"184// --------------------------185 186void testDynCastOrNullOfNull(void) {187  // Don't suppress when one of the arguments is NULL.188  int *casted = dynCastOrNull(0);189  *casted = 1;190#if !SUPPRESSED || NULL_ARGS191  // expected-warning@-2 {{Dereference of null pointer}}192#endif193}194 195void testDynCastOfNull(void) {196  // Don't suppress when one of the arguments is NULL.197  int *casted = dynCastToInt(0);198  *casted = 1;199#if !SUPPRESSED || NULL_ARGS200  // expected-warning@-2 {{Dereference of null pointer}}201#endif202}203 204int *lookUpInt(int unused) {205  if (coin())206    return 0;207  static int x;208  return &x;209}210 211void testZeroIsNotNull(void) {212  // /Do/ suppress when the argument is 0 (an integer).213  int *casted = lookUpInt(0);214  *casted = 1;215#ifndef SUPPRESSED216  // expected-warning@-2 {{Dereference of null pointer}}217#endif218}219 220void testTrackNull(void) {221  // /Do/ suppress if the null argument came from another call returning null.222  int *casted = dynCastOrNull(getNull());223  *casted = 1;224#ifndef SUPPRESSED225  // expected-warning@-2 {{Dereference of null pointer}}226#endif227}228 229void testTrackNullVariable(void) {230  // /Do/ suppress if the null argument came from another call returning null.231  int *ptr;232  ptr = getNull();233  int *casted = dynCastOrNull(ptr);234  *casted = 1;235#ifndef SUPPRESSED236  // expected-warning@-2 {{Dereference of null pointer}}237#endif238}239 240void inlinedIsDifferent(int inlined) {241  int i;242 243  // We were erroneously picking up the inner stack frame's initialization,244  // even though the error occurs in the outer stack frame!245  int *p = inlined ? &i : getNull();246 247  if (!inlined)248    inlinedIsDifferent(1);249 250  *p = 1;251#ifndef SUPPRESSED252  // expected-warning@-2 {{Dereference of null pointer}}253#endif254}255 256void testInlinedIsDifferent(void) {257  inlinedIsDifferent(0);258}259 260 261// ---------------------------------------262// FALSE NEGATIVES (over-suppression)263// ---------------------------------------264 265void testNoArguments(void) {266  // In this case the function has no branches, and MUST return null.267  int *casted = getNull();268  *casted = 1;269#ifndef SUPPRESSED270  // expected-warning@-2 {{Dereference of null pointer}}271#endif272}273 274int *getNullIfNonNull(void *input) {275  if (input)276    return 0;277  static int x;278  return &x;279}280 281void testKnownPath(void *input) {282  if (!input)283    return;284 285  // In this case we have a known value for the argument, and thus the path286  // through the function doesn't ever split.287  int *casted = getNullIfNonNull(input);288  *casted = 1;289#ifndef SUPPRESSED290  // expected-warning@-2 {{Dereference of null pointer}}291#endif292}293 294int *alwaysReturnNull(void *input) {295  if (opaquePropertyCheck(input))296    return 0;297  return 0;298}299 300void testAlwaysReturnNull(void *input) {301  // In this case all paths out of the function return 0, but they are all302  // dominated by a branch whose condition we don't know!303  int *casted = alwaysReturnNull(input);304  *casted = 1;305#ifndef SUPPRESSED306  // expected-warning@-2 {{Dereference of null pointer}}307#endif308}309 310int derefArg(int *p) {311	return *p;312#ifndef SUPPRESSED313  // expected-warning@-2 {{Dereference of null pointer}}314#endif315}316void ternaryArg(char cond) {317	static int x;318	derefArg(cond ? &x : getNull());319}320 321int derefArgCast(char *p) {322	return *p;323#ifndef SUPPRESSED324  // expected-warning@-2 {{Dereference of null pointer}}325#endif326}327void ternaryArgCast(char cond) {328	static int x;329	derefArgCast((char*)((unsigned)cond ? &x : getNull()));330}331 332int derefAssignment(int *p) {333	return *p;334#ifndef SUPPRESSED335  // expected-warning@-2 {{Dereference of null pointer}}336#endif337}338 339void ternaryAssignment(char cond) {340  static int x;341  int *p = cond ? getNull() : getPtr();342  derefAssignment(p);343}344 345int *retNull(char cond) {346  static int x;347  return cond ? &x : getNull();348}349int ternaryRetNull(char cond) {350  int *p = retNull(cond);351  return *p;352#ifndef SUPPRESSED353  // expected-warning@-2 {{Dereference of null pointer}}354#endif355}356 357// Test suppression of nested conditional operators.358int testConditionalOperatorSuppress(int x) {359  return *(x ? getNull() : getPtr());360#ifndef SUPPRESSED361  // expected-warning@-2 {{Dereference of null pointer}}362#endif363}364int testNestedConditionalOperatorSuppress(int x) {365  return *(x ? (x ? getNull() : getPtr()) : getPtr());366#ifndef SUPPRESSED367  // expected-warning@-2 {{Dereference of null pointer}}368#endif369}370int testConditionalOperator(int x) {371  return *(x ? 0 : getPtr()); // expected-warning {{Dereference of null pointer}}372}373int testNestedConditionalOperator(int x) {374  return *(x ? (x ? 0 : getPtr()) : getPtr()); // expected-warning {{Dereference of null pointer}}375}376 377int testConditionalOperatorSuppressFloatCond(float x) {378  return *(x ? getNull() : getPtr());379#ifndef SUPPRESSED380  // expected-warning@-2 {{Dereference of null pointer}}381#endif382}383 384