Skip to content

Commit 4085e87

Browse files
authored
Treat address-of array subscripts the same way as address-of dereferences (checkedc#1163)
* In CheckAddressOfOperand, add case for address-of array subscripts to C99-specific logic * Move address-of array subscript check after other checks such as taking the address of an lvalue * Adjust expected AST output to account for different types of address-of array subscripts * Restore deleted comment about checking for array subscript expressions * Add comment explaining the placement of the address-of array subscript logic * Put &e1[e2] typing rules under a Checked C flag
1 parent c88ca51 commit 4085e87

File tree

4 files changed

+33
-30
lines changed

4 files changed

+33
-30
lines changed

clang/lib/Sema/SemaExpr.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14201,6 +14201,15 @@ QualType Sema::CheckAddressOfOperand(ExprResult &OrigOp, SourceLocation OpLoc) {
1420114201

1420214202
CheckAddressOfPackedMember(op);
1420314203

14204+
// For Checked C, &e1[e2] should be a pointer to T if e1 or e2 is a pointer
14205+
// to T, regardless of checked scope. This avoids the unexpected result of
14206+
// &e1[e2] having a different type than e1 or e2, which could otherwise
14207+
// happen in an unchecked scope if e1 or e2 is a checked pointer.
14208+
if (getLangOpts().CheckedC) {
14209+
if (ArraySubscriptExpr *arrSubscript = dyn_cast<ArraySubscriptExpr>(op))
14210+
return arrSubscript->getBase()->getType();
14211+
}
14212+
1420414213
// Checked scopes change the types of the address-of(&) operator.
1420514214
// In a checked scope, the operator produces an array_ptr<T> except for
1420614215
// function type. For address-of function type, it produces ptr not array_ptr.

clang/test/CheckedC/inferred-bounds/basic.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -431,8 +431,7 @@ void f42(void) {
431431
// CHECK: VarDecl {{0x[0-9a-f]+}} {{.*}} r '_Array_ptr<int>' cinit
432432
// CHECK: |-CountBoundsExpr {{0x[0-9a-f]+}} {{.*}} 'NULL TYPE' Element
433433
// CHECK: | `-IntegerLiteral {{0x[0-9a-f]+}} {{.*}} 'int' 1
434-
// CHECK: `-ImplicitCastExpr {{0x[0-9a-f]+}} {{.*}} '_Array_ptr<int>' <BitCast>
435-
// CHECK: `-UnaryOperator {{0x[0-9a-f]+}} {{.*}} 'int *' prefix '&'
434+
// CHECK: `-UnaryOperator {{0x[0-9a-f]+}} {{.*}} '_Array_ptr<int>' prefix '&'
436435
// CHECK: `-ArraySubscriptExpr {{0x[0-9a-f]+}} {{.*}} 'int' lvalue
437436
// CHECK: |-ImplicitCastExpr {{0x[0-9a-f]+}} {{.*}} '_Array_ptr<int>' <LValueToRValue>
438437
// CHECK: | `-DeclRefExpr {{0x[0-9a-f]+}} {{.*}} '_Array_ptr<int>' lvalue Var {{0x[0-9a-f]+}} 'p' '_Array_ptr<int>'
@@ -521,8 +520,7 @@ void f43(void) {
521520

522521
// CHECK: BinaryOperator {{0x[0-9a-f]+}} {{.*}} '_Array_ptr<int>' '='
523522
// CHECK: |-DeclRefExpr {{0x[0-9a-f]+}} {{.*}} '_Array_ptr<int>' lvalue Var {{0x[0-9a-f]+}} 'r' '_Array_ptr<int>'
524-
// CHECK: `-ImplicitCastExpr {{0x[0-9a-f]+}} {{.*}} '_Array_ptr<int>' <BitCast>
525-
// CHECK: `-UnaryOperator {{0x[0-9a-f]+}} {{.*}} 'int *' prefix '&'
523+
// CHECK: `-UnaryOperator {{0x[0-9a-f]+}} {{.*}} '_Array_ptr<int>' prefix '&'
526524
// CHECK: `-ArraySubscriptExpr {{0x[0-9a-f]+}} {{.*}} 'int' lvalue
527525
// CHECK: |-ImplicitCastExpr {{0x[0-9a-f]+}} {{.*}} '_Array_ptr<int>' <LValueToRValue>
528526
// CHECK: | `-DeclRefExpr {{0x[0-9a-f]+}} {{.*}} '_Array_ptr<int>' lvalue Var {{0x[0-9a-f]+}} 'p' '_Array_ptr<int>'

clang/test/CheckedC/inferred-bounds/equiv-expr-sets.c

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,27 +1027,25 @@ void original_value11(array_ptr<int> p, array_ptr<int> q) {
10271027
// CHECK-NEXT: }
10281028
// CHECK-NEXT: }
10291029

1030-
// Original value of p in (_Array_ptr<int>&p[2]): (int *)p - 2
1031-
// Updated EquivExprs: { { (int *)p - 2 + 1, q } }
1030+
// Original value of p in &p[2]: p - 2
1031+
// Updated EquivExprs: { { p - 2 + 1, q } }
10321032
p = &p[2];
10331033
// CHECK: Statement S:
10341034
// CHECK-NEXT: BinaryOperator {{.*}} '='
10351035
// CHECK-NEXT: DeclRefExpr {{.*}} 'p'
1036-
// CHECK-NEXT: ImplicitCastExpr {{.*}} '_Array_ptr<int>' <BitCast>
1037-
// CHECK-NEXT: UnaryOperator {{.*}} 'int *' prefix '&'
1038-
// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'int'
1039-
// CHECK-NEXT: ImplicitCastExpr {{.*}} <LValueToRValue>
1040-
// CHECK-NEXT: DeclRefExpr {{.*}} 'p'
1041-
// CHECK-NEXT: IntegerLiteral {{.*}} 2
1036+
// CHECK-NEXT: UnaryOperator {{.*}} '_Array_ptr<int>' prefix '&'
1037+
// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'int'
1038+
// CHECK-NEXT: ImplicitCastExpr {{.*}} <LValueToRValue>
1039+
// CHECK-NEXT: DeclRefExpr {{.*}} 'p'
1040+
// CHECK-NEXT: IntegerLiteral {{.*}} 2
10421041
// CHECK: Sets of equivalent expressions after checking S:
10431042
// CHECK-NEXT: {
10441043
// CHECK-NEXT: {
10451044
// CHECK-NEXT: BinaryOperator {{.*}} '+'
10461045
// CHECK-NEXT: BinaryOperator {{.*}} '-'
1047-
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int *' <BitCast>
1048-
// CHECK-NEXT: ImplicitCastExpr {{.*}} <LValueToRValue>
1049-
// CHECK-NEXT: DeclRefExpr {{.*}} 'p'
1050-
// CHECK-NEXT: IntegerLiteral {{.*}} 2
1046+
// CHECK-NEXT: ImplicitCastExpr {{.*}} <LValueToRValue>
1047+
// CHECK-NEXT: DeclRefExpr {{.*}} 'p'
1048+
// CHECK-NEXT: IntegerLiteral {{.*}} 2
10511049
// CHECK-NEXT: IntegerLiteral {{.*}} 1
10521050
// CHECK-NEXT: ImplicitCastExpr {{.*}} <LValueToRValue>
10531051
// CHECK-NEXT: DeclRefExpr {{.*}} 'q'
@@ -1127,28 +1125,26 @@ void original_value13(array_ptr<int> p, array_ptr<int> q) {
11271125
// CHECK-NEXT: }
11281126
// CHECK-NEXT: }
11291127

1130-
// Original value of p in (_Array_ptr<int>)&0[&*p]: (int *)p - 0
1131-
// Updated EquivExprs: { { (int *)p - 0 + 1, q } }
1128+
// Original value of p in &0[&*p]: p - 0
1129+
// Updated EquivExprs: { { p - 0 + 1, q } }
11321130
p = &0[&*p];
11331131
// CHECK: Statement S:
11341132
// CHECK-NEXT: BinaryOperator {{.*}} '='
11351133
// CHECK-NEXT: DeclRefExpr {{.*}} 'p'
1136-
// CHECK-NEXT: ImplicitCastExpr {{.*}} '_Array_ptr<int>' <BitCast>
1137-
// CHECK-NEXT: UnaryOperator {{.*}} 'int *' prefix '&'
1138-
// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'int'
1139-
// CHECK-NEXT: IntegerLiteral {{.*}} 0
1140-
// CHECK-NEXT: UnaryOperator {{.*}} '_Array_ptr<int>' prefix '&'
1141-
// CHECK-NEXT: UnaryOperator {{.*}} '*'
1142-
// CHECK-NEXT: ImplicitCastExpr {{.*}} <LValueToRValue>
1143-
// CHECK-NEXT: DeclRefExpr {{.*}} 'p'
1134+
// CHECK-NEXT: UnaryOperator {{.*}} '_Array_ptr<int>' prefix '&'
1135+
// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'int'
1136+
// CHECK-NEXT: IntegerLiteral {{.*}} 0
1137+
// CHECK-NEXT: UnaryOperator {{.*}} '_Array_ptr<int>' prefix '&'
1138+
// CHECK-NEXT: UnaryOperator {{.*}} '*'
1139+
// CHECK-NEXT: ImplicitCastExpr {{.*}} <LValueToRValue>
1140+
// CHECK-NEXT: DeclRefExpr {{.*}} 'p'
11441141
// CHECK: Sets of equivalent expressions after checking S:
11451142
// CHECK-NEXT: {
11461143
// CHECK-NEXT: {
11471144
// CHECK-NEXT: BinaryOperator {{.*}} '+'
11481145
// CHECK-NEXT: BinaryOperator {{.*}} '-'
1149-
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int *' <BitCast>
1150-
// CHECK-NEXT: ImplicitCastExpr {{.*}} <LValueToRValue>
1151-
// CHECK-NEXT: DeclRefExpr {{.*}} 'p'
1146+
// CHECK-NEXT: ImplicitCastExpr {{.*}} <LValueToRValue>
1147+
// CHECK-NEXT: DeclRefExpr {{.*}} 'p'
11521148
// CHECK-NEXT: IntegerLiteral {{.*}} 0
11531149
// CHECK-NEXT: IntegerLiteral {{.*}} 1
11541150
// CHECK-NEXT: ImplicitCastExpr {{.*}} <LValueToRValue>

clang/test/CheckedC/inferred-bounds/ptr-cast.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ void f2(_Array_ptr<int> p : count(5)) {
7171
// CHECK: | |-ImplicitCastExpr {{0x[0-9a-f]+}} {{.*}} '_Array_ptr<int>' <LValueToRValue>
7272
// CHECK: | | `-DeclRefExpr {{0x[0-9a-f]+}} {{.*}} '_Array_ptr<int>' lvalue ParmVar {{0x[0-9a-f]+}} 'p' '_Array_ptr<int>'
7373
// CHECK: | `-IntegerLiteral {{0x[0-9a-f]+}} {{.*}} 'int' 5
74-
// CHECK: `-UnaryOperator {{0x[0-9a-f]+}} {{.*}} 'int *' prefix '&'
74+
// CHECK: `-UnaryOperator {{0x[0-9a-f]+}} {{.*}} '_Array_ptr<int>' prefix '&'
7575
// CHECK: `-ArraySubscriptExpr {{0x[0-9a-f]+}} {{.*}} 'int' lvalue
7676
// CHECK: |-ImplicitCastExpr {{0x[0-9a-f]+}} {{.*}} '_Array_ptr<int>' <LValueToRValue>
7777
// CHECK: | `-DeclRefExpr {{0x[0-9a-f]+}} {{.*}} '_Array_ptr<int>' lvalue ParmVar {{0x[0-9a-f]+}} 'p' '_Array_ptr<int>'

0 commit comments

Comments
 (0)