[clang] 91b3823 - [clang][Sema] Use size of char in bits for void types
Bill Wendling via cfe-commits
cfe-commits at lists.llvm.org
Fri Oct 14 14:46:36 PDT 2022
Author: Bill Wendling
Date: 2022-10-14T14:46:19-07:00
New Revision: 91b3823bd000b1a6ffde96a6363098f59307317a
URL: https://github.com/llvm/llvm-project/commit/91b3823bd000b1a6ffde96a6363098f59307317a
DIFF: https://github.com/llvm/llvm-project/commit/91b3823bd000b1a6ffde96a6363098f59307317a.diff
LOG: [clang][Sema] Use size of char in bits for void types
The extension that allows for pointer arithmetic on 'void' types treats
the 'void' as a 'char'. We should use the 'char' size in bits instead of
1 (the number of bytes) to allow warning when pointer arithmetic would
go out of bounds.
Differential Revision: https://reviews.llvm.org/D135989
Added:
Modified:
clang/lib/Sema/SemaChecking.cpp
clang/test/Sema/array-bounds-ptr-arith.c
Removed:
################################################################################
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index a1e3db1b57af2..c0ecd7b091000 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -16020,16 +16020,22 @@ void Sema::CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr,
llvm::APInt size = ArrayTy->getSize();
if (BaseType != EffectiveType) {
- // Make sure we're comparing apples to apples when comparing index to size
+ // Make sure we're comparing apples to apples when comparing index to
+ // size.
uint64_t ptrarith_typesize = Context.getTypeSize(EffectiveType);
uint64_t array_typesize = Context.getTypeSize(BaseType);
- // Handle ptrarith_typesize being zero, such as when casting to void*
- if (!ptrarith_typesize) ptrarith_typesize = 1;
+
+ // Handle ptrarith_typesize being zero, such as when casting to void*.
+ // Use the size in bits (what "getTypeSize()" returns) rather than bytes.
+ if (!ptrarith_typesize)
+ ptrarith_typesize = Context.getCharWidth();
+
if (ptrarith_typesize != array_typesize) {
- // There's a cast to a
diff erent size type involved
+ // There's a cast to a
diff erent size type involved.
uint64_t ratio = array_typesize / ptrarith_typesize;
+
// TODO: Be smarter about handling cases where array_typesize is not a
- // multiple of ptrarith_typesize
+ // multiple of ptrarith_typesize.
if (ptrarith_typesize * ratio == array_typesize)
size *= llvm::APInt(size.getBitWidth(), ratio);
}
diff --git a/clang/test/Sema/array-bounds-ptr-arith.c b/clang/test/Sema/array-bounds-ptr-arith.c
index a447f19dfe830..57baf9241cf0e 100644
--- a/clang/test/Sema/array-bounds-ptr-arith.c
+++ b/clang/test/Sema/array-bounds-ptr-arith.c
@@ -6,13 +6,12 @@
struct ext2_super_block{
unsigned char s_uuid[8]; // expected-note {{declared here}}
};
-void* ext2_statfs (struct ext2_super_block *es,int a)
-{
- return (void *)es->s_uuid + sizeof(int); // no-warning
+
+void* ext2_statfs (struct ext2_super_block *es,int a) {
+ return (void *)es->s_uuid + sizeof(int); // no-warning
}
-void* broken (struct ext2_super_block *es,int a)
-{
- return (void *)es->s_uuid + 80; // expected-warning {{refers past the end of the array}}
+void* broken (struct ext2_super_block *es,int a) {
+ return (void *)es->s_uuid + 9; // expected-warning {{the pointer incremented by 9 refers past the end of the array}}
}
// Test case reduced from PR11594
More information about the cfe-commits
mailing list