================
@@ -475,9 +475,41 @@ struct Empty {};
struct Empty ZeroSizeElements[10];
struct Empty zeroSizeElements(void) {
- // FIXME: We probably shouldn't report this access.
- return ZeroSizeElements[5];
+ // Previously this had produced the false positive warning {{Access of
+ // 'ZeroSizeElements' at byte offset 0, while it holds only 0 bytes}}.
+ return ZeroSizeElements[5]; // no-warning
+}
+
+struct Empty zeroSizeElementsNegativeIndex(void) {
+ // The negative index does not change anything, it still means offset = 0.
+ return ZeroSizeElements[-5]; // no-warning
+}
+
+int zeroSizeContainerIntAccess(void) {
+ return ((int*)ZeroSizeElements)[5];
// expected-warning@-1 {{Out of bound access to memory after the end of
'ZeroSizeElements'}}
- // expected-note@-2 {{Access of 'ZeroSizeElements' at byte offset 0, while
it holds only 0 byte}}
+ // expected-note@-2 {{Access of 'ZeroSizeElements' at index 5, while it
holds only 0 'int' elements}}
}
+
+struct Empty zeroSizeAccessOfPastTheEnd(void) {
+ // We currently allow zero-sized access of past-the-end pointers as a side
+ // effect of the logic that handles the testcase 'zeroSizeElements'.
+ return *(struct Empty *)(TenElements + 10); // no-warning
+}
----------------
NagyDonat wrote:
Under C++ `sizeof(struct Empty)` is 1 (not 0), so it will behave exactly like a
plain `char`, there are no interesting corner cases that are worth testing. I
will mention this in a comment, but I won't duplicate the tests for C++.
A little [godbolt
experiment](https://godbolt.org/#g:!((g:!((g:!((h:codeEditor,i:(filename:'1',fontScale:14,fontUsePx:'0',j:1,lang:___c,selection:(endColumn:2,endLineNumber:9,positionColumn:2,positionLineNumber:9,selectionStartColumn:2,selectionStartLineNumber:9,startColumn:2,startLineNumber:9),source:'struct+Empty+%7B%7D%3B%0A%0Aint+main(int+argc,+char+**argv)+%7B%0A++++struct+Empty+Array%5B10%5D%3B%0A++++void+*p+%3D+(void+*)(Array%2B5)%3B%0A++++void+*q+%3D+(void+*)(Array%2B15)%3B%0A++++struct+Empty+X+%3D+Array%5B10%5D%3B%0A++++return+sizeof(struct+Empty)+%2B+100+*+((char*)p+-+(char*)q)%3B%0A%7D'),l:'5',n:'0',o:'C+source+%231',t:'0')),k:41.734417344173444,l:'4',m:100,n:'0',o:'',s:0,t:'0'),(g:!((g:!((h:compiler,i:(compiler:cclang_trunk,filters:(b:'0',binary:'1',binaryObject:'1',commentOnly:'0',debugCalls:'1',demangle:'0',directives:'0',execute:'0',intel:'1',libraryCode:'0',trim:'1',verboseDemangling:'0'),flagsViewOpen:'1',fontScale:14,fontUsePx:'0',j:1,lang:___c,libs:!(),options:'',overrides:!(),selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:1),l:'5',n:'0',o:'+x86-64+clang+(trunk)+(Editor+%231)',t:'0')),k:50,l:'4',m:50,n:'0',o:'',s:0,t:'0'),(g:!((h:output,i:(compilerName:'x86-64+gcc+16.1',editorid:1,fontScale:14,fontUsePx:'0',j:1,wrap:'1'),l:'5',n:'0',o:'Output+of+x86-64+clang+(trunk)+(Compiler+%231)',t:'0')),header:(),l:'4',m:50,n:'0',o:'',s:0,t:'0')),k:58.265582655826556,l:'3',n:'0',o:'',t:'0')),l:'2',n:'0',o:'',t:'0')),version:4)
shows that:
- The zero-sized elements are indeed zero-sized, so in `struct Empty Array[10]`
all elements like `Array[5]` or even the apparently overflowing `Array[15]`
have offset 0.
- "Loading a `struct Empty` object from the memory" is a no-op, does not
produce any assembly code.
- The builtin `-Warray-bounds` warning reports access of an array when the
_index_ is out of bounds even if the element size is zero and all elements are
at offset 0. This is incompatible with the current model of
`security.ArrayBound` where all calculations are offset-based – but I have
vague plans for implementing index-based bounds checking.
https://github.com/llvm/llvm-project/pull/218712
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits