This is something I've stumbled upon when trying to bootstrap with -fsanitize=undefined (doesn't work so far...). It's pretty serious stuff, but clang doesn't handle it either... We errored on e.g. enum e { x = 1 << 1 }; because of the instrumentation. Fixed by doing the instrumentation only when current_function_decl != 0. Perhaps this should be revised later on.
Tested x86_64-pc-linux-gnu, applying to ubsan branch. diff --git a/gcc/c/ChangeLog.ubsan b/gcc/c/ChangeLog.ubsan index 58e931f..11d167f 100644 --- a/gcc/c/ChangeLog.ubsan +++ b/gcc/c/ChangeLog.ubsan @@ -1,3 +1,8 @@ +2013-07-30 Marek Polacek <pola...@redhat.com> + + * c-typeck.c (build_binary_op): Sanitize only when + current_function_decl is not zero. + 2013-07-21 Marek Polacek <pola...@redhat.com> * c-typeck.c (build_binary_op): Call c_fully_fold on both diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index d0f4b0d..7257166 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -10488,7 +10488,8 @@ build_binary_op (location_t location, enum tree_code code, return error_mark_node; } - if (flag_sanitize & SANITIZE_UNDEFINED) + if (flag_sanitize & SANITIZE_UNDEFINED + && current_function_decl != 0) { /* OP0 and/or OP1 might have side-effects. */ op0 = c_save_expr (op0); diff --git a/gcc/cp/ChangeLog.ubsan b/gcc/cp/ChangeLog.ubsan index 0ab2870..f37ce94 100644 --- a/gcc/cp/ChangeLog.ubsan +++ b/gcc/cp/ChangeLog.ubsan @@ -1,3 +1,8 @@ +2013-07-30 Marek Polacek <pola...@redhat.com> + + * typeck.c (cp_build_binary_op): Sanitize only when + current_function_decl is not zero. + 2013-07-05 Marek Polacek <pola...@redhat.com> * typeck.c (cp_build_binary_op): Add division by zero and shift diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 7790830..ebe27e8 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -4885,6 +4885,7 @@ cp_build_binary_op (location_t location, if ((flag_sanitize & SANITIZE_UNDEFINED) && !processing_template_decl + && current_function_decl != 0 && (doing_div_or_mod || doing_shift)) { /* OP0 and/or OP1 might have side-effects. */ diff --git a/gcc/testsuite/ChangeLog.ubsan b/gcc/testsuite/ChangeLog.ubsan index 453bd61..f3f18f9 100644 --- a/gcc/testsuite/ChangeLog.ubsan +++ b/gcc/testsuite/ChangeLog.ubsan @@ -1,3 +1,7 @@ +2013-07-30 Marek Polacek <pola...@redhat.com> + + * c-c++-common/ubsan/const-expr.c: New test. + 2013-07-22 Marek Polacek <pola...@redhat.com> * c-c++-common/ubsan/div-by-zero-3.c: Add more testing. diff --git a/gcc/testsuite/c-c++-common/ubsan/const-expr-1.c b/gcc/testsuite/c-c++-common/ubsan/const-expr-1.c new file mode 100644 index 0000000..f474ec6 --- /dev/null +++ b/gcc/testsuite/c-c++-common/ubsan/const-expr-1.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-fsanitize=shift -w" } */ + +enum e { A = 1 << 1, B, }; +const int arr[] = { + 1 << 2, + 1 << 3, +}; + +int +bar (int a, int b) +{ + return a >> b; +} + +int +foo (void) +{ + int i = 1; + int vla[B << 3]; + return bar (A, (i <<= 6, i + 2)); +} Marek