| // Part of the Crubit project, under the Apache License v2.0 with LLVM | |
| // Exceptions. See /LICENSE for license information. | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| // Tests for pointer arithmetic. | |
| // Note that, for example, the increment and decrement operators do not cause | |
| // their operand to become nonnull, even though we know that they may only be | |
| // applied to nonnull pointers. This is consistent with our treatment of other | |
| // operators, such as `*` and `->`; these also do not cause their operand to | |
| // become nonnull. | |
| #include "nullability_test.h" | |
| // This test intentionally contains violations of `-Wunsafe-buffer-usage`, so | |
| // turn it off. | |
| #pragma clang diagnostic push | |
| #pragma clang diagnostic ignored "-Wunsafe-buffer-usage" | |
| TEST void preIncrementType(int *_Nonnull NonnullParam, | |
| int *_Nullable NullableParam, int *UnknownParam) { | |
| type<int *_Nonnull>(++NonnullParam); | |
| type<int *_Nonnull>(++NullableParam); | |
| type<int *_Nonnull>(++UnknownParam); | |
| } | |
| TEST void preIncrementValue(int *_Nonnull NonnullParam, | |
| int *_Nullable NullableParam, int *UnknownParam) { | |
| int *NewVal = ++NonnullParam; | |
| provable(NonnullParam == NewVal); | |
| nonnull(NonnullParam); | |
| NewVal = ++NullableParam; | |
| provable(NullableParam == NewVal); | |
| nonnull(NullableParam); | |
| NewVal = ++UnknownParam; | |
| provable(UnknownParam == NewVal); | |
| nonnull(UnknownParam); | |
| } | |
| TEST void postIncrementType(int *_Nonnull NonnullParam, | |
| int *_Nullable NullableParam, int *UnknownParam) { | |
| type<int *_Nonnull>(NonnullParam++); | |
| type<int *_Nullable>(NullableParam++); | |
| type<int *>(UnknownParam++); | |
| } | |
| TEST void postIncrementValue(int *_Nonnull NonnullParam, | |
| int *_Nullable NullableParam, int *UnknownParam) { | |
| int *OldVal = NonnullParam; | |
| provable(NonnullParam++ == OldVal); | |
| nonnull(NonnullParam); | |
| OldVal = NullableParam; | |
| provable(NullableParam++ == OldVal); | |
| nonnull(NullableParam); | |
| OldVal = UnknownParam; | |
| provable(UnknownParam++ == OldVal); | |
| nonnull(UnknownParam); | |
| } | |
| TEST void add(int *_Nonnull NonnullParam, int *_Nullable NullableParam, | |
| int *UnknownParam, int I) { | |
| type<int *_Nonnull>(NonnullParam + I); | |
| type<int *_Nonnull>(I + NonnullParam); | |
| type<int *_Nonnull>(NullableParam + I); | |
| type<int *_Nonnull>(I + NullableParam); | |
| type<int *_Nonnull>(UnknownParam + I); | |
| type<int *_Nonnull>(I + UnknownParam); | |
| } | |
| TEST void subtract(int *_Nonnull NonnullParam, int *_Nullable NullableParam, | |
| int *UnknownParam, int I) { | |
| // Pointer minus integer. | |
| type<int *_Nonnull>(NonnullParam - I); | |
| type<int *_Nonnull>(NullableParam - I); | |
| type<int *_Nonnull>(UnknownParam - I); | |
| // Pointer minus pointer. | |
| // Spot-checking just a few of the possible combinations. | |
| using Ptrdiff = decltype(UnknownParam - UnknownParam); | |
| type<Ptrdiff>(NonnullParam - NonnullParam); | |
| type<Ptrdiff>(NonnullParam - NullableParam); | |
| type<Ptrdiff>(NullableParam - UnknownParam); | |
| } | |
| TEST void addAssignType(int *_Nonnull NonnullParam, | |
| int *_Nullable NullableParam, int *UnknownParam, | |
| int I) { | |
| type<int *_Nonnull>(NonnullParam += I); | |
| type<int *_Nonnull>(NullableParam += I); | |
| type<int *_Nonnull>(UnknownParam += I); | |
| } | |
| TEST void addAssignValue(int *_Nonnull NonnullParam, | |
| int *_Nullable NullableParam, int *UnknownParam, | |
| int I) { | |
| int *NewVal = (NonnullParam += I); | |
| provable(NonnullParam == NewVal); | |
| nonnull(NonnullParam); | |
| NewVal = (NullableParam += I); | |
| provable(NullableParam == NewVal); | |
| nonnull(NullableParam); | |
| NewVal = (UnknownParam += I); | |
| provable(UnknownParam == NewVal); | |
| nonnull(UnknownParam); | |
| } | |
| TEST void subtractAssignType(int *_Nonnull NonnullParam, | |
| int *_Nullable NullableParam, int *UnknownParam, | |
| int I) { | |
| type<int *_Nonnull>(NonnullParam -= I); | |
| type<int *_Nonnull>(NullableParam -= I); | |
| type<int *_Nonnull>(UnknownParam -= I); | |
| } | |
| TEST void subtractAssignValue(int *_Nonnull NonnullParam, | |
| int *_Nullable NullableParam, int *UnknownParam, | |
| int I) { | |
| int *NewVal = (NonnullParam -= I); | |
| provable(NonnullParam == NewVal); | |
| nonnull(NonnullParam); | |
| NewVal = (NullableParam -= I); | |
| provable(NullableParam == NewVal); | |
| nonnull(NullableParam); | |
| NewVal = (UnknownParam -= I); | |
| provable(UnknownParam == NewVal); | |
| nonnull(UnknownParam); | |
| } | |
| #pragma clang diagnostic pop |