Files
clang-p2996/clang/test/Analysis/explain-svals.m
Adam Balogh 98db1f990f [Analyzer] [NFC] Parameter Regions
Currently, parameters of functions without their definition present cannot
be represented as regions because it would be difficult to ensure that the
same declaration is used in every case. To overcome this, we split
`VarRegion` to two subclasses: `NonParamVarRegion` and `ParamVarRegion`.
The latter does not store the `Decl` of the parameter variable. Instead it
stores the index of the parameter which enables retrieving the actual
`Decl` every time using the function declaration of the stack frame. To
achieve this we also removed storing of `Decl` from `DeclRegion` and made
`getDecl()` pure virtual. The individual `Decl`s are stored in the
appropriate subclasses, such as `FieldRegion`, `ObjCIvarRegion` and the
newly introduced `NonParamVarRegion`.

Differential Revision: https://reviews.llvm.org/D80522
2020-06-09 12:08:56 +02:00

72 lines
2.6 KiB
Objective-C

// RUN: %clang_analyze_cc1 -w -triple i386-apple-darwin10 -fblocks -verify %s \
// RUN: -analyzer-checker=core.builtin \
// RUN: -analyzer-checker=debug.ExprInspection \
// RUN: -analyzer-config display-checker-name=false
#include "Inputs/system-header-simulator-objc.h"
void clang_analyzer_explain(void *);
@interface Object : NSObject {
@public
Object *x;
}
@end
void test_1(Object *p) {
clang_analyzer_explain(p); // expected-warning-re{{{{^argument 'p'$}}}}
clang_analyzer_explain(p->x); // expected-warning-re{{{{^initial value of instance variable 'x' of object at argument 'p'$}}}}
Object *q = [[Object alloc] init];
clang_analyzer_explain(q); // expected-warning-re{{{{^symbol of type 'Object \*' conjured at statement '\[\[Object alloc\] init\]'$}}}}
clang_analyzer_explain(q->x); // expected-warning-re{{{{^initial value of instance variable 'x' of object at symbol of type 'Object \*' conjured at statement '\[\[Object alloc\] init\]'$}}}}
}
void test_2() {
__block int x;
^{
clang_analyzer_explain(&x); // expected-warning-re{{{{^pointer to block variable 'x'$}}}}
};
clang_analyzer_explain(&x); // expected-warning-re{{{{^pointer to block variable 'x'$}}}}
}
@interface O
+ (instancetype)top_level_class_method:(int)param;
+ (instancetype)non_top_level_class_method:(int)param;
- top_level_instance_method:(int)param;
- non_top_level_instance_method:(int)param;
@end
@implementation O
+ (instancetype)top_level_class_method:(int)param {
clang_analyzer_explain(&param); // expected-warning-re{{{{^pointer to parameter 'param'$}}}}
}
+ (instancetype)non_top_level_class_method:(int)param {
clang_analyzer_explain(&param); // expected-warning-re{{{{^pointer to parameter 'param'$}}}}
}
- top_level_instance_method:(int)param {
clang_analyzer_explain(&param); // expected-warning-re{{{{^pointer to parameter 'param'$}}}}
}
- non_top_level_instance_method:(int)param {
clang_analyzer_explain(&param); // expected-warning-re{{{{^pointer to parameter 'param'$}}}}
}
@end
void test_3(int n, int m) {
O *o = [O non_top_level_class_method:n];
[o non_top_level_instance_method:m];
void (^block_top_level)(int) = ^(int param) {
clang_analyzer_explain(&param); // expected-warning-re{{{{^pointer to parameter 'param'$}}}}
clang_analyzer_explain(&n); // expected-warning-re{{{{^pointer to parameter 'n'$}}}}
};
void (^block_non_top_level)(int) = ^(int param) {
clang_analyzer_explain(&param); // expected-warning-re{{{{^pointer to parameter 'param'$}}}}
clang_analyzer_explain(&n); // expected-warning-re{{{{^pointer to parameter 'n'$}}}}
};
block_non_top_level(n);
}