aboutsummaryrefslogtreecommitdiff
path: root/src/check_builtin.cpp
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2022-04-02 15:00:28 +0100
committergingerBill <bill@gingerbill.org>2022-04-02 15:00:28 +0100
commit1ec997461d52a4d847e702ea33b40773719a592a (patch)
tree5b627b79c406636e8e006dfe46f5c5b4ef612184 /src/check_builtin.cpp
parentec5fc109887fa6054f339f5ce62554b615356830 (diff)
Add extra checks to atomic intrinsics
Diffstat (limited to 'src/check_builtin.cpp')
-rw-r--r--src/check_builtin.cpp45
1 files changed, 45 insertions, 0 deletions
diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp
index abe58855b..24025f08c 100644
--- a/src/check_builtin.cpp
+++ b/src/check_builtin.cpp
@@ -3392,6 +3392,21 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
check_expr_with_type_hint(c, &x, ce->args[1], elem);
check_assignment(c, &x, elem, builtin_name);
+ Type *t = type_deref(operand->type);
+ switch (id) {
+ case BuiltinProc_atomic_add:
+ case BuiltinProc_atomic_sub:
+ if (!is_type_numeric(t)) {
+ gbString str = type_to_string(t);
+ error(operand->expr, "Expected a numeric type for '%.*s', got %s", LIT(builtin_name), str);
+ gb_string_free(str);
+ } else if (is_type_different_to_arch_endianness(t)) {
+ gbString str = type_to_string(t);
+ error(operand->expr, "Expected a numeric type of the same platform endianness for '%.*s', got %s", LIT(builtin_name), str);
+ gb_string_free(str);
+ }
+ }
+
operand->type = elem;
operand->mode = Addressing_Value;
break;
@@ -3419,6 +3434,22 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
return false;
}
+ Type *t = type_deref(operand->type);
+ switch (id) {
+ case BuiltinProc_atomic_add_explicit:
+ case BuiltinProc_atomic_sub_explicit:
+ if (!is_type_numeric(t)) {
+ gbString str = type_to_string(t);
+ error(operand->expr, "Expected a numeric type for '%.*s', got %s", LIT(builtin_name), str);
+ gb_string_free(str);
+ } else if (is_type_different_to_arch_endianness(t)) {
+ gbString str = type_to_string(t);
+ error(operand->expr, "Expected a numeric type of the same platform endianness for '%.*s', got %s", LIT(builtin_name), str);
+ gb_string_free(str);
+ }
+ break;
+ }
+
operand->type = elem;
operand->mode = Addressing_Value;
break;
@@ -3439,6 +3470,13 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
check_assignment(c, &x, elem, builtin_name);
check_assignment(c, &y, elem, builtin_name);
+ Type *t = type_deref(operand->type);
+ if (!is_type_comparable(t)) {
+ gbString str = type_to_string(t);
+ error(operand->expr, "Expected a comparable type for '%.*s', got %s", LIT(builtin_name), str);
+ gb_string_free(str);
+ }
+
operand->mode = Addressing_OptionalOk;
operand->type = elem;
break;
@@ -3468,6 +3506,13 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
return false;
}
+ Type *t = type_deref(operand->type);
+ if (!is_type_comparable(t)) {
+ gbString str = type_to_string(t);
+ error(operand->expr, "Expected a comparable type for '%.*s', got %s", LIT(builtin_name), str);
+ gb_string_free(str);
+ }
+
bool invalid_combination = false;
switch (success_memory_order) {