@@ -73,6 +73,10 @@ ubsan_instrument_division (location_t lo
x = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, x, tt);
t = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t, x);
}
+
+ /* In case we have a SAVE_EXPR in a conditional context, we need to
+ make sure it gets evaluated before the condition. */
+ t = fold_build2 (COMPOUND_EXPR, TREE_TYPE (t), op0, t);
tree data = ubsan_create_data ("__ubsan_overflow_data",
loc, ubsan_type_descriptor (type),
NULL_TREE);
@@ -133,6 +137,10 @@ ubsan_instrument_shift (location_t loc,
build_int_cst (type0, 0));
tt = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, x, tt);
}
+
+ /* In case we have a SAVE_EXPR in a conditional context, we need to
+ make sure it gets evaluated before the condition. */
+ t = fold_build2 (COMPOUND_EXPR, TREE_TYPE (t), op0, t);
tree data = ubsan_create_data ("__ubsan_shift_data",
loc, ubsan_type_descriptor (type0),
ubsan_type_descriptor (type1), NULL_TREE);
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-fsanitize=shift -Wall -Werror -O" } */
+
+static int x;
+int
+main (void)
+{
+ int o = 1;
+ int y = x << o;
+ return y;
+}
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-fsanitize=shift -Wall -Werror -O" } */
+
+int
+foo (int i, unsigned int u)
+{
+ return u / i;
+}
+
+int
+bar (int i, unsigned int u)
+{
+ return u % i;
+}
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-fsanitize=shift -Wall -Werror -O" } */
+
+int x;
+
+int
+foo (int i, int u)
+{
+ return (i << u) << x;
+}
+
+int
+bar (int i, int u)
+{
+ return (i >> u) >> x;
+}
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-fsanitize=shift -Wall -Werror -O" } */
+
+int x;
+
+int
+foo (int i, unsigned int u)
+{
+ return (i % u) << (x / u);
+}
+
+int
+bar (int i, unsigned int u)
+{
+ return (((x % u) << (u / i)) >> x);
+}