1
+ // RUN: %clang_cc1 -fbounds-safety -ast-dump %s | FileCheck %s
2
+ // RUN: %clang_cc1 -fbounds-safety -x objective-c -fexperimental-bounds-safety-objc -ast-dump %s | FileCheck %s
3
+
4
+ #include <ptrcheck.h>
5
+
6
+ char * __counted_by (len ) returns_counted_by (const char * __counted_by (len ) p , unsigned len );
7
+
8
+ // CHECK: FunctionDecl [[func_pass:0x[^ ]+]] {{.+}} pass_as_argument 'void (const char *__single __terminated_by(0))'
9
+ // CHECK-NEXT: |-ParmVarDecl [[var_src:0x[^ ]+]] {{.+}} src 'const char *__single __terminated_by(0)':'const char *__single'
10
+ // CHECK-NEXT: `-CompoundStmt {{.+}}
11
+ // CHECK-NEXT: `-MaterializeSequenceExpr {{.+}} <Unbind>
12
+ // CHECK-NEXT: |-MaterializeSequenceExpr {{.+}} <Bind>
13
+ // CHECK-NEXT: | |-BoundsSafetyPointerPromotionExpr {{.+}}
14
+ // CHECK-NEXT: | | |-OpaqueValueExpr [[ove_call:0x[^ ]+]] {{.+}} 'char *__single __counted_by(len)':'char *__single'
15
+ // CHECK-NEXT: | | | `-BoundsCheckExpr {{.+}}
16
+ // CHECK-NEXT: | | | |-CallExpr {{.+}}
17
+ // CHECK-NEXT: | | | | |-ImplicitCastExpr {{.+}} <FunctionToPointerDecay>
18
+ // CHECK-NEXT: | | | | | `-DeclRefExpr {{.+}} Function {{.+}} 'returns_counted_by'
19
+ // CHECK-NEXT: | | | | |-ImplicitCastExpr {{.+}} <BoundsSafetyPointerCast>
20
+ // CHECK-NEXT: | | | | | `-OpaqueValueExpr [[ove_indexable:0x[^ ]+]] {{.+}} 'const char *__indexable'
21
+ // CHECK-NEXT: | | | | | `-TerminatedByToIndexableExpr [[term_expr:0x[^ ]+]] {{.+}} 'const char *__indexable'
22
+ // CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.+}} 'const char *__single __terminated_by(0)':'const char *__single' <LValueToRValue>
23
+ // CHECK-NEXT: | | | | | | `-ParenExpr {{.+}} 'const char *__single __terminated_by(0)':'const char *__single' lvalue
24
+ // CHECK-NEXT: | | | | | | `-DeclRefExpr {{.+}} 'const char *__single __terminated_by(0)':'const char *__single' lvalue ParmVar [[var_src]] 'src'
25
+ // CHECK-NEXT: | | | | | `-IntegerLiteral {{.+}} 'int' 0
26
+ // CHECK-NEXT: | | | | `-OpaqueValueExpr [[ove_len:0x[^ ]+]] {{.+}} 'unsigned int'
27
+ // CHECK-NEXT: | | | | `-ImplicitCastExpr {{.+}} <IntegralCast>
28
+ // CHECK-NEXT: | | | | `-IntegerLiteral {{.+}} 'int' 10
29
+ // CHECK-NEXT: | | | `-BinaryOperator {{.+}} '&&'
30
+ // CHECK-NEXT: | | | |-BinaryOperator {{.+}} '&&'
31
+ // CHECK-NEXT: | | | | |-BinaryOperator {{.+}} '<='
32
+ // CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.+}} <BoundsSafetyPointerCast>
33
+ // CHECK-NEXT: | | | | | | `-OpaqueValueExpr [[ove_indexable]] {{.*}} 'const char *__indexable'
34
+ // CHECK-NEXT: | | | | | | `-TerminatedByToIndexableExpr [[term_expr]] {{.*}} 'const char *__indexable'
35
+ void pass_as_argument (const char * src ) {
36
+ returns_counted_by (__unsafe_null_terminated_to_indexable (src ), 10 );
37
+ }
38
+
39
+ // CHECK: FunctionDecl [[func_assign:0x[^ ]+]] {{.+}} assign 'void (char *__single __counted_by(*len)*__single, unsigned int *__single, char *__single __terminated_by(0))'
40
+ // CHECK-NEXT: |-ParmVarDecl [[var_p:0x[^ ]+]] {{.+}} p 'char *__single __counted_by(*len)*__single'
41
+ // CHECK-NEXT: |-ParmVarDecl [[var_len:0x[^ ]+]] {{.+}} len 'unsigned int *__single'
42
+ // CHECK-NEXT: | `-DependerDeclsAttr {{.+}} Implicit IsDeref [[var_p]]
43
+ // CHECK-NEXT: |-ParmVarDecl [[var_src2:0x[^ ]+]] {{.+}} src 'char *__single __terminated_by(0)':'char *__single'
44
+ // CHECK-NEXT: `-CompoundStmt {{.+}}
45
+ // CHECK-NEXT: |-MaterializeSequenceExpr {{.+}} <Bind>
46
+ // CHECK-NEXT: | |-BoundsCheckExpr {{.+}}
47
+ // CHECK-NEXT: | | |-BinaryOperator {{.+}} '='
48
+ // CHECK-NEXT: | | | |-UnaryOperator {{.+}} lvalue prefix '*' cannot overflow
49
+ // CHECK-NEXT: | | | | `-ImplicitCastExpr {{.+}} <LValueToRValue>
50
+ // CHECK-NEXT: | | | | `-DeclRefExpr {{.+}} lvalue ParmVar [[var_p]] 'p'
51
+ // CHECK-NEXT: | | | `-ImplicitCastExpr {{.+}} <BoundsSafetyPointerCast>
52
+ // CHECK-NEXT: | | | `-OpaqueValueExpr [[ove_assign:0x[^ ]+]] {{.+}} 'char *__indexable'
53
+ // CHECK-NEXT: | | | `-TerminatedByToIndexableExpr [[term_assign:0x[^ ]+]] {{.+}} 'char *__indexable'
54
+ // CHECK-NEXT: | | | |-ImplicitCastExpr {{.+}} <LValueToRValue>
55
+ // CHECK-NEXT: | | | | `-ParenExpr {{.+}} lvalue
56
+ // CHECK-NEXT: | | | | `-DeclRefExpr {{.+}} lvalue ParmVar [[var_src2]] 'src'
57
+ // CHECK-NEXT: | | | `-IntegerLiteral {{.+}} 'int' 0
58
+ // CHECK-NEXT: | | `-BinaryOperator {{.+}} '&&'
59
+ // CHECK-NEXT: | | |-BinaryOperator {{.+}} '&&'
60
+ // CHECK-NEXT: | | | |-BinaryOperator {{.+}} '<='
61
+ // CHECK-NEXT: | | | | |-ImplicitCastExpr {{.+}} <BoundsSafetyPointerCast>
62
+ // CHECK-NEXT: | | | | | `-OpaqueValueExpr [[ove_assign]] {{.*}} 'char *__indexable'
63
+ // CHECK-NEXT: | | | | | `-TerminatedByToIndexableExpr [[term_assign]] {{.*}} 'char *__indexable'
64
+ // CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.+}} <LValueToRValue>
65
+ // CHECK-NEXT: | | | | | | `-ParenExpr {{.+}} lvalue
66
+ // CHECK-NEXT: | | | | | | `-DeclRefExpr {{.+}} lvalue ParmVar [[var_src2]] 'src'
67
+ // CHECK-NEXT: | | | | | `-IntegerLiteral {{.+}} 'int' 0
68
+ // CHECK-NEXT: | | | | `-GetBoundExpr {{.+}} upper
69
+ // CHECK-NEXT: | | | | `-ImplicitCastExpr {{.+}} <BoundsSafetyPointerCast>
70
+ // CHECK-NEXT: | | | | `-OpaqueValueExpr [[ove_assign]] {{.*}} 'char *__indexable'
71
+ // CHECK-NEXT: | | | | `-TerminatedByToIndexableExpr [[term_assign]] {{.*}} 'char *__indexable'
72
+ // CHECK-NEXT: | | | | |-ImplicitCastExpr {{.+}} <LValueToRValue>
73
+ // CHECK-NEXT: | | | | | `-ParenExpr {{.+}} lvalue
74
+ // CHECK-NEXT: | | | | | `-DeclRefExpr {{.+}} lvalue ParmVar [[var_src2]] 'src'
75
+ // CHECK-NEXT: | | | | `-IntegerLiteral {{.+}} 'int' 0
76
+ // CHECK-NEXT: | | | `-BinaryOperator {{.+}} '<='
77
+ // CHECK-NEXT: | | | |-GetBoundExpr {{.+}} lower
78
+ // CHECK-NEXT: | | | | `-ImplicitCastExpr {{.+}} <BoundsSafetyPointerCast>
79
+ // CHECK-NEXT: | | | | `-OpaqueValueExpr [[ove_assign]] {{.*}} 'char *__indexable'
80
+ // CHECK-NEXT: | | | | `-TerminatedByToIndexableExpr [[term_assign]] {{.*}} 'char *__indexable'
81
+ // CHECK-NEXT: | | | | |-ImplicitCastExpr {{.+}} <LValueToRValue>
82
+ // CHECK-NEXT: | | | | | `-ParenExpr {{.+}} lvalue
83
+ // CHECK-NEXT: | | | | | `-DeclRefExpr {{.+}} lvalue ParmVar [[var_src2]] 'src'
84
+ // CHECK-NEXT: | | | | `-IntegerLiteral {{.+}} 'int' 0
85
+ // CHECK-NEXT: | | | `-ImplicitCastExpr {{.+}} <BoundsSafetyPointerCast>
86
+ // CHECK-NEXT: | | | `-OpaqueValueExpr [[ove_assign]] {{.*}} 'char *__indexable'
87
+ // CHECK-NEXT: | | | `-TerminatedByToIndexableExpr [[term_assign]] {{.*}} 'char *__indexable'
88
+ // CHECK-NEXT: | | | |-ImplicitCastExpr {{.+}} <LValueToRValue>
89
+ // CHECK-NEXT: | | | | `-ParenExpr {{.+}} lvalue
90
+ // CHECK-NEXT: | | | | `-DeclRefExpr {{.+}} lvalue ParmVar [[var_src2]] 'src'
91
+ // CHECK-NEXT: | | | `-IntegerLiteral {{.+}} 'int' 0
92
+ // CHECK-NEXT: | | `-BinaryOperator {{.+}} '<='
93
+ // CHECK-NEXT: | | |-ImplicitCastExpr {{.+}} <IntegralCast>
94
+ // CHECK-NEXT: | | | `-OpaqueValueExpr [[ove_len2:0x[^ ]+]] {{.+}} 'unsigned int'
95
+ // CHECK-NEXT: | | | `-ImplicitCastExpr {{.+}} <IntegralCast>
96
+ // CHECK-NEXT: | | | `-IntegerLiteral {{.+}} 'int' 10
97
+ // CHECK-NEXT: | | `-BinaryOperator {{.+}} '-'
98
+ // CHECK-NEXT: | | |-GetBoundExpr {{.+}} upper
99
+ // CHECK-NEXT: | | | `-ImplicitCastExpr {{.+}} <BoundsSafetyPointerCast>
100
+ // CHECK-NEXT: | | | `-OpaqueValueExpr [[ove_assign]] {{.*}} 'char *__indexable'
101
+ // CHECK-NEXT: | | | `-TerminatedByToIndexableExpr [[term_assign]] {{.*}} 'char *__indexable'
102
+ // CHECK-NEXT: | | | |-ImplicitCastExpr {{.+}} <LValueToRValue>
103
+ // CHECK-NEXT: | | | | `-ParenExpr {{.+}} lvalue
104
+ // CHECK-NEXT: | | | | `-DeclRefExpr {{.+}} lvalue ParmVar [[var_src2]] 'src'
105
+ // CHECK-NEXT: | | | `-IntegerLiteral {{.+}} 'int' 0
106
+ // CHECK-NEXT: | | `-ImplicitCastExpr {{.+}} <BoundsSafetyPointerCast>
107
+ // CHECK-NEXT: | | `-OpaqueValueExpr [[ove_assign]] {{.*}} 'char *__indexable'
108
+ // CHECK-NEXT: | | `-TerminatedByToIndexableExpr [[term_assign]] {{.*}} 'char *__indexable'
109
+ // CHECK-NEXT: | | |-ImplicitCastExpr {{.+}} <LValueToRValue>
110
+ // CHECK-NEXT: | | | `-ParenExpr {{.+}} lvalue
111
+ // CHECK-NEXT: | | | `-DeclRefExpr {{.+}} lvalue ParmVar [[var_src2]] 'src'
112
+ // CHECK-NEXT: | | `-IntegerLiteral {{.+}} 'int' 0
113
+ // CHECK-NEXT: | |-OpaqueValueExpr [[ove_assign]] {{.*}} 'char *__indexable'
114
+ // CHECK-NEXT: | | `-TerminatedByToIndexableExpr [[term_assign]] {{.*}} 'char *__indexable'
115
+ // CHECK-NEXT: | | |-ImplicitCastExpr {{.+}} <LValueToRValue>
116
+ // CHECK-NEXT: | | | `-ParenExpr {{.+}} lvalue
117
+ // CHECK-NEXT: | | | `-DeclRefExpr {{.+}} lvalue ParmVar [[var_src2]] 'src'
118
+ // CHECK-NEXT: | | `-IntegerLiteral {{.+}} 'int' 0
119
+ // CHECK-NEXT: | `-OpaqueValueExpr [[ove_len2]] {{.*}} 'unsigned int'
120
+ // CHECK-NEXT: | `-ImplicitCastExpr {{.+}} <IntegralCast>
121
+ // CHECK-NEXT: | `-IntegerLiteral {{.+}} 'int' 10
122
+ // CHECK-NEXT: `-MaterializeSequenceExpr {{.+}} <Unbind>
123
+ // CHECK-NEXT: |-BinaryOperator {{.+}} '='
124
+ // CHECK-NEXT: | |-UnaryOperator {{.+}} lvalue prefix '*' cannot overflow
125
+ // CHECK-NEXT: | | `-ImplicitCastExpr {{.+}} <LValueToRValue>
126
+ // CHECK-NEXT: | | `-DeclRefExpr {{.+}} lvalue ParmVar [[var_len]] 'len'
127
+ // CHECK-NEXT: | `-OpaqueValueExpr [[ove_len2]] {{.*}} 'unsigned int'
128
+ // CHECK-NEXT: | `-ImplicitCastExpr {{.+}} <IntegralCast>
129
+ // CHECK-NEXT: | `-IntegerLiteral {{.+}} 'int' 10
130
+ // CHECK-NEXT: |-OpaqueValueExpr [[ove_assign]] {{.*}} 'char *__indexable'
131
+ // CHECK-NEXT: | `-TerminatedByToIndexableExpr [[term_assign]] {{.*}} 'char *__indexable'
132
+ // CHECK-NEXT: | |-ImplicitCastExpr {{.+}} <LValueToRValue>
133
+ // CHECK-NEXT: | | `-ParenExpr {{.+}} lvalue
134
+ // CHECK-NEXT: | | `-DeclRefExpr {{.+}} lvalue ParmVar [[var_src2]] 'src'
135
+ // CHECK-NEXT: | `-IntegerLiteral {{.+}} 'int' 0
136
+ // CHECK-NEXT: `-OpaqueValueExpr [[ove_len2]] {{.*}} 'unsigned int'
137
+ // CHECK-NEXT: `-ImplicitCastExpr {{.+}} <IntegralCast>
138
+ // CHECK-NEXT: `-IntegerLiteral {{.+}} 'int' 10
139
+ void assign (char * __counted_by (* len ) * p , unsigned * len , char * __null_terminated src ) {
140
+ * p = __unsafe_null_terminated_to_indexable (src );
141
+ * len = 10 ;
142
+ }
0 commit comments