Skip to content

Commit fc6ec9b

Browse files
committed
[Sema] Fix for PR50741
Fixed crash when doing pointer math on a void pointer. Also, reworked test to use -verify rather than FileCheck. Reviewed By: erichkeane Differential Revision: https://reviews.llvm.org/D104424
1 parent fa1de88 commit fc6ec9b

File tree

2 files changed

+39
-32
lines changed

2 files changed

+39
-32
lines changed

clang/lib/Sema/SemaChecking.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14567,8 +14567,13 @@ void Sema::CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr,
1456714567
EffectiveType->getCanonicalTypeInternal()));
1456814568
if (index.getBitWidth() < AddrBits)
1456914569
index = index.zext(AddrBits);
14570-
CharUnits ElemCharUnits = ASTC.getTypeSizeInChars(EffectiveType);
14571-
llvm::APInt ElemBytes(index.getBitWidth(), ElemCharUnits.getQuantity());
14570+
Optional<CharUnits> ElemCharUnits =
14571+
ASTC.getTypeSizeInCharsIfKnown(EffectiveType);
14572+
// PR50741 - If EffectiveType has unknown size (e.g., if it's a void
14573+
// pointer) bounds-checking isn't meaningful.
14574+
if (!ElemCharUnits)
14575+
return;
14576+
llvm::APInt ElemBytes(index.getBitWidth(), ElemCharUnits->getQuantity());
1457214577
// If index has more active bits than address space, we already know
1457314578
// we have a bounds violation to warn about. Otherwise, compute
1457414579
// address of (index + 1)th element, and warn about bounds violation
@@ -14599,7 +14604,7 @@ void Sema::CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr,
1459914604
DiagRuntimeBehavior(BaseExpr->getBeginLoc(), BaseExpr,
1460014605
PDiag(DiagID)
1460114606
<< toString(index, 10, true) << AddrBits
14602-
<< (unsigned)ASTC.toBits(ElemCharUnits)
14607+
<< (unsigned)ASTC.toBits(*ElemCharUnits)
1460314608
<< toString(ElemBytes, 10, false)
1460414609
<< toString(MaxElems, 10, false)
1460514610
<< (unsigned)MaxElems.getLimitedValue(~0U)
Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
1-
// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only %s 2>&1 | FileCheck --check-prefix=CHECK-X86-ADDR64 %s \
2-
// RUN: --implicit-check-not 'past the last possible element'
3-
// RUN: %clang_cc1 -triple i386-pc-linux-gnu -fsyntax-only %s 2>&1 | FileCheck --check-prefix=CHECK-I386-ADDR32 %s \
4-
// RUN: --implicit-check-not 'past the last possible element'
5-
// RUN: %clang_cc1 -triple avr-pc-linux-gnu -fsyntax-only %s 2>&1 | FileCheck --check-prefix=CHECK-AVR-ADDR16 %s \
6-
// RUN: --implicit-check-not 'past the last possible element'
1+
// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -Wno-unused -verify=addr64,expected %s
2+
// RUN: %clang_cc1 -triple i386-pc-linux-gnu -fsyntax-only -Wno-unused -verify=addr32,expected %s
3+
// RUN: %clang_cc1 -triple avr-pc-linux-gnu -fsyntax-only -Wno-unused -verify=addr16,expected %s
74

85
struct S {
96
long long a;
@@ -12,61 +9,61 @@ struct S {
129
short d;
1310
};
1411

15-
struct S s[];
12+
struct S s[]; // expected-warning {{tentative array definition}} expected-note {{declared here}} addr16-note {{declared here}}
1613

1714
void f1() {
1815
++s[3].a;
1916
++s[7073650413200313099].b;
20-
// CHECK-X86-ADDR64: :[[@LINE-1]]:5: warning: array index 7073650413200313099 refers past the last possible element for an array in 64-bit address space containing 256-bit (32-byte) elements (max possible 576460752303423488 elements)
21-
// CHECK-I386-ADDR32: :[[@LINE-2]]:5: warning: {{.*}} past the last possible element {{.*}} in 32-bit {{.*}} (max possible 178956970 elements)
22-
// CHECK-AVR-ADDR16: :[[@LINE-3]]:5: warning: {{.*}} past the last possible element {{.*}} in 16-bit {{.*}} (max possible 3276 elements)
17+
// addr16-warning@-1 {{array index 7073650413200313099 refers past the last possible element for an array in 16-bit address space containing 160-bit (20-byte) elements (max possible 3276 elements)}}
18+
// addr32-warning@-2 {{array index 7073650413200313099 refers past the last possible element for an array in 32-bit address space containing 192-bit (24-byte) elements (max possible 178956970 elements)}}
19+
// addr64-warning@-3 {{array index 7073650413200313099 refers past the last possible element for an array in 64-bit address space containing 256-bit (32-byte) elements (max possible 576460752303423488 elements)}}
2320
++s[7073650].c;
24-
// CHECK-AVR-ADDR16: :[[@LINE-1]]:5: warning: {{.*}} past the last possible element {{.*}} in 16-bit {{.*}} (max possible 3276 elements)
21+
// addr16-warning@-1 {{array index 7073650 refers past the last possible element for an array in 16-bit address space containing 160-bit (20-byte) elements (max possible 3276 elements)}}
2522
}
2623

27-
long long ll[];
24+
long long ll[]; // expected-warning {{tentative array definition}} expected-note {{declared here}} addr16-note {{declared here}} addr32-note {{declared here}}
2825

2926
void f2() {
3027
++ll[3];
3128
++ll[2705843009213693952];
32-
// CHECK-X86-ADDR64: :[[@LINE-1]]:5: warning: {{.*}} past the last possible element {{.*}} in 64-bit {{.*}} (max possible 2305843009213693952 elements)
33-
// CHECK-I386-ADDR32: :[[@LINE-2]]:5: warning: {{.*}} past the last possible element {{.*}} in 32-bit {{.*}} (max possible 536870912 elements)
34-
// CHECK-AVR-ADDR16: :[[@LINE-3]]:5: warning: {{.*}} past the last possible element {{.*}} in 16-bit {{.*}} (max possible 8192 elements)
29+
// addr16-warning@-1 {{array index 2705843009213693952 refers past the last possible element for an array in 16-bit address space containing 64-bit (8-byte) elements (max possible 8192 elements)}}
30+
// addr32-warning@-2 {{array index 2705843009213693952 refers past the last possible element for an array in 32-bit address space containing 64-bit (8-byte) elements (max possible 536870912 elements)}}
31+
// addr64-warning@-3 {{array index 2705843009213693952 refers past the last possible element for an array in 64-bit address space containing 64-bit (8-byte) elements (max possible 2305843009213693952 elements)}}
3532
++ll[847073650];
36-
// CHECK-I386-ADDR32: :[[@LINE-1]]:5: warning: {{.*}} past the last possible element {{.*}} in 32-bit {{.*}} (max possible 536870912 elements)
37-
// CHECK-AVR-ADDR16: :[[@LINE-2]]:5: warning: {{.*}} past the last possible element {{.*}} in 16-bit {{.*}} (max possible 8192 elements)
33+
// addr16-warning@-1 {{array index 847073650 refers past the last possible element for an array in 16-bit address space containing 64-bit (8-byte) elements (max possible 8192 elements)}}
34+
// addr32-warning@-2 {{array index 847073650 refers past the last possible element for an array in 32-bit address space containing 64-bit (8-byte) elements (max possible 536870912 elements)}}
3835
}
3936

40-
void f3(struct S p[]) {
37+
void f3(struct S p[]) { // expected-note {{declared here}} addr16-note {{declared here}}
4138
++p[3].a;
4239
++p[7073650413200313099].b;
43-
// CHECK-X86-ADDR64: :[[@LINE-1]]:5: warning: {{.*}} past the last possible element {{.*}} in 64-bit {{.*}} (max possible 576460752303423488 elements)
44-
// CHECK-I386-ADDR32: :[[@LINE-2]]:5: warning: {{.*}} past the last possible element {{.*}} in 32-bit {{.*}} (max possible 178956970 elements)
45-
// CHECK-AVR-ADDR16: :[[@LINE-3]]:5: warning: {{.*}} past the last possible element {{.*}} in 16-bit {{.*}} (max possible 3276 elements)
40+
// addr16-warning@-1 {{array index 7073650413200313099 refers past the last possible element for an array in 16-bit address space containing 160-bit (20-byte) elements (max possible 3276 elements)}}
41+
// addr32-warning@-2 {{array index 7073650413200313099 refers past the last possible element for an array in 32-bit address space containing 192-bit (24-byte) elements (max possible 178956970 elements)}}
42+
// addr64-warning@-3 {{array index 7073650413200313099 refers past the last possible element for an array in 64-bit address space containing 256-bit (32-byte) elements (max possible 576460752303423488 elements)}}
4643
++p[7073650].c;
47-
// CHECK-AVR-ADDR16: :[[@LINE-1]]:5: warning: {{.*}} past the last possible element {{.*}} in 16-bit {{.*}} (max possible 3276 elements)
44+
// addr16-warning@-1 {{array index 7073650 refers past the last possible element for an array in 16-bit address space containing 160-bit (20-byte) elements (max possible 3276 elements)}}
4845
}
4946

50-
void f4(struct S *p) {
47+
void f4(struct S *p) { // expected-note {{declared here}} addr16-note {{declared here}}
5148
p += 3;
5249
p += 7073650413200313099;
53-
// CHECK-X86-ADDR64: :[[@LINE-1]]:3: warning: the pointer incremented by 7073650413200313099 refers past the last possible element for an array in 64-bit address space containing 256-bit (32-byte) elements (max possible 576460752303423488 elements)
54-
// CHECK-I386-ADDR32: :[[@LINE-2]]:3: warning: {{.*}} past the last possible element {{.*}} in 32-bit {{.*}} (max possible 178956970 elements)
55-
// CHECK-AVR-ADDR16: :[[@LINE-3]]:3: warning: {{.*}} past the last possible element {{.*}} in 16-bit {{.*}} (max possible 3276 elements)
50+
// addr16-warning@-1 {{the pointer incremented by 7073650413200313099 refers past the last possible element for an array in 16-bit address space containing 160-bit (20-byte) elements (max possible 3276 elements)}}
51+
// addr32-warning@-2 {{the pointer incremented by 7073650413200313099 refers past the last possible element for an array in 32-bit address space containing 192-bit (24-byte) elements (max possible 178956970 elements)}}
52+
// addr64-warning@-3 {{the pointer incremented by 7073650413200313099 refers past the last possible element for an array in 64-bit address space containing 256-bit (32-byte) elements (max possible 576460752303423488 elements)}}
5653
p += 7073650;
57-
// CHECK-AVR-ADDR16: :[[@LINE-1]]:3: warning: {{.*}} past the last possible element {{.*}} in 16-bit {{.*}} (max possible 3276 elements)
54+
// addr16-warning@-1 {{the pointer incremented by 7073650 refers past the last possible element for an array in 16-bit address space containing 160-bit (20-byte) elements (max possible 3276 elements)}}
5855
}
5956

6057
struct BQ {
6158
struct S bigblock[3276];
6259
};
6360

64-
struct BQ bq[];
61+
struct BQ bq[]; // expected-warning {{tentative array definition}} addr16-note {{declared here}}
6562

6663
void f5() {
6764
++bq[0].bigblock[0].a;
6865
++bq[1].bigblock[0].a;
69-
// CHECK-AVR-ADDR16: :[[@LINE-1]]:5: warning: {{.*}} past the last possible element {{.*}} in 16-bit {{.*}} (max possible 1 element)
66+
// addr16-warning@-1 {{array index 1 refers past the last possible element for an array in 16-bit address space containing 524160-bit (65520-byte) elements (max possible 1 element)}}
7067
}
7168

7269
void f6() {
@@ -78,3 +75,8 @@ void f6() {
7875
// Should NOT produce a warning.
7976
*(middle + 5 - N) = 22;
8077
}
78+
79+
void pr50741() {
80+
(void *)0 + 0xdead000000000000UL;
81+
// no array-bounds warning, and no crash
82+
}

0 commit comments

Comments
 (0)