You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[Clang][ARM][Sema] Reject bad sizes of __builtin_arm_ldrex (#150419)
Depending on the particular version of the AArch32 architecture,
load/store exclusive operations might be available for various subset of
8, 16, 32, and 64-bit quantities. Sema knew nothing about this and was
accepting all four sizes, leading to a compiler crash at isel time if
you used a size not available on the target architecture.
Now the Sema checking stage emits a more sensible diagnostic, pointing
at the location in the code.
In order to allow Sema to query the set of supported sizes, I've moved
the enum of LDREX_x sizes out of its Arm-specific header into
`TargetInfo.h`.
Also, in order to allow the diagnostic to specify the correct list of
supported sizes, I've filled it with `%select{}`. (The alternative was
to make separate error messages for each different list of sizes.)
// All these architecture versions provide 1-, 2- or 4-byte exclusive accesses,
6
+
// but don't have the LDREXD instruction which takes two operand registers and
7
+
// performs an 8-byte exclusive access. So the calls with a pointer to long
8
+
// long are rejected.
9
+
10
+
inttest_ldrex(char*addr) {
11
+
intsum=0;
12
+
sum+=__builtin_arm_ldrex(addr);
13
+
sum+=__builtin_arm_ldrex((short*)addr);
14
+
sum+=__builtin_arm_ldrex((int*)addr);
15
+
sum+=__builtin_arm_ldrex((long long*)addr); // expected-error {{address argument to load or store exclusive builtin must be a pointer to 1,2 or 4 byte type}}
16
+
returnsum;
17
+
}
18
+
19
+
inttest_strex(char*addr) {
20
+
intres=0;
21
+
res |= __builtin_arm_strex(4, addr);
22
+
res |= __builtin_arm_strex(42, (short*)addr);
23
+
res |= __builtin_arm_strex(42, (int*)addr);
24
+
res |= __builtin_arm_strex(42, (long long*)addr); // expected-error {{address argument to load or store exclusive builtin must be a pointer to 1,2 or 4 byte type}}
// Armv6 (apart from Armv6-M) provides 4-byte exclusive accesses, but not any
4
+
// other size. So only the calls with a pointer to a 32-bit type are accepted.
5
+
6
+
inttest_ldrex(char*addr) {
7
+
intsum=0;
8
+
sum+=__builtin_arm_ldrex(addr); // expected-error {{address argument to load or store exclusive builtin must be a pointer to 4 byte type}}
9
+
sum+=__builtin_arm_ldrex((short*)addr); // expected-error {{address argument to load or store exclusive builtin must be a pointer to 4 byte type}}
10
+
sum+=__builtin_arm_ldrex((int*)addr);
11
+
sum+=__builtin_arm_ldrex((long long*)addr); // expected-error {{address argument to load or store exclusive builtin must be a pointer to 4 byte type}}
12
+
returnsum;
13
+
}
14
+
15
+
inttest_strex(char*addr) {
16
+
intres=0;
17
+
res |= __builtin_arm_strex(4, addr); // expected-error {{address argument to load or store exclusive builtin must be a pointer to 4 byte type}}
18
+
res |= __builtin_arm_strex(42, (short*)addr); // expected-error {{address argument to load or store exclusive builtin must be a pointer to 4 byte type}}
19
+
res |= __builtin_arm_strex(42, (int*)addr);
20
+
res |= __builtin_arm_strex(42, (long long*)addr); // expected-error {{address argument to load or store exclusive builtin must be a pointer to 4 byte type}}
0 commit comments