llvm-project/clang/test/AST/ast-dump-array.cpp
YexuanXiao 7c402b8b81
Reland [Clang] Make the SizeType, SignedSizeType and PtrdiffType be named sugar types (#149613)
The checks for the 'z' and 't' format specifiers added in the original
PR #143653 had some issues and were overly strict, causing some build
failures and were consequently reverted at
4c85bf2fe8.

In the latest commit
27c58629ec,
I relaxed the checks for the 'z' and 't' format specifiers, so warnings
are now only issued when they are used with mismatched types.

The original intent of these checks was to diagnose code that assumes
the underlying type of `size_t` is `unsigned` or `unsigned long`, for
example:

```c
printf("%zu", 1ul); // Not portable, but not an error when size_t is unsigned long
```  

However, it produced a significant number of false positives. This was
partly because Clang does not treat the `typedef` `size_t` and
`__size_t` as having a common "sugar" type, and partly because a large
amount of existing code either assumes `unsigned` (or `unsigned long`)
is `size_t`, or they define the equivalent of size_t in their own way
(such as
sanitizer_internal_defs.h).2e67dcfdcd/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h (L203)
2025-07-19 03:44:14 -03:00

84 lines
2.7 KiB
C++

// Test without serialization:
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -ast-dump %s \
// RUN: | FileCheck --strict-whitespace %s
//
// Test with serialization:
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-pch -o %t %s
// RUN: %clang_cc1 -x c++ -triple x86_64-unknown-unknown -include-pch %t -ast-dump-all /dev/null \
// RUN: | sed -e "s/ <undeserialized declarations>//" -e "s/ imported//" \
// RUN: | FileCheck --strict-whitespace %s
void testArrayInitExpr()
{
int a[10];
auto l = [a]{
};
// CHECK: |-ArrayInitLoopExpr 0x{{[^ ]*}} <col:15> 'int[10]'
// CHECK: | `-ArrayInitIndexExpr 0x{{[^ ]*}} <<invalid sloc>> '__size_t':'unsigned long'
}
template<typename T, int Size>
class array {
T data[Size];
using array_T_size = T[Size];
// CHECK: `-DependentSizedArrayType 0x{{[^ ]*}} 'T[Size]' dependent
using const_array_T_size = const T[Size];
// CHECK: `-DependentSizedArrayType 0x{{[^ ]*}} 'const T[Size]' dependent
};
struct V {};
template <typename U, typename Idx, int N>
void testDependentSubscript() {
U* a;
U b[5];
Idx i{};
enum E { One = 1 };
// Can types of subscript expressions can be determined?
// LHS is a type-dependent array, RHS is a known integer type.
a[1];
// CHECK: ArraySubscriptExpr {{.*}}line:[[@LINE-1]]{{.*}} 'U'
b[1];
// CHECK: ArraySubscriptExpr {{.*}}line:[[@LINE-1]]{{.*}} 'U'
// Reverse case: RHS is a type-dependent array, LHS is an integer.
1[a];
// CHECK: ArraySubscriptExpr {{.*}}line:[[@LINE-1]]{{.*}} 'U'
1[b];
// CHECK: ArraySubscriptExpr {{.*}}line:[[@LINE-1]]{{.*}} 'U'
// LHS is a type-dependent array, RHS is type-dependent.
a[i];
// CHECK: ArraySubscriptExpr {{.*}}line:[[@LINE-1]]{{.*}} '<dependent type>'
b[i];
// CHECK: ArraySubscriptExpr {{.*}}line:[[@LINE-1]]{{.*}} '<dependent type>'
V *a2;
V b2[5];
// LHS is a known array, RHS is type-dependent.
a2[i];
// CHECK: ArraySubscriptExpr {{.*}}line:[[@LINE-1]]{{.*}} '<dependent type>'
b2[i];
// CHECK: ArraySubscriptExpr {{.*}}line:[[@LINE-1]]{{.*}} '<dependent type>'
// LHS is a known array, RHS is a type-dependent index.
// We know the element type is V, but insist on some dependent type.
a2[One];
// CHECK: ArraySubscriptExpr {{.*}}line:[[@LINE-1]]{{.*}} '<dependent type>'
b2[One];
// CHECK: ArraySubscriptExpr {{.*}}line:[[@LINE-1]]{{.*}} '<dependent type>'
V b3[N];
// LHS is an array with dependent bounds but known elements.
// We insist on a dependent type.
b3[0];
// CHECK: ArraySubscriptExpr {{.*}}line:[[@LINE-1]]{{.*}} '<dependent type>'
U b4[N];
// LHS is an array with dependent bounds and dependent elements.
b4[0];
// CHECK: ArraySubscriptExpr {{.*}}line:[[@LINE-1]]{{.*}} 'U'
}