Wrap a macro in do {} while (0) (PR sanitizer/80063)

Submitted by Martin Sebor on March 20, 2017, 5:35 p.m.

Details

Message ID 3e1921d5-7cc1-7df3-aede-0d300060ddfb@gmail.com
State New
Headers show

Commit Message

Martin Sebor March 20, 2017, 5:35 p.m.
On 03/20/2017 10:53 AM, Jakub Jelinek wrote:
> On Mon, Mar 20, 2017 at 10:44:25AM -0600, Martin Sebor wrote:
>>> /home/marek/src/gcc/gcc/sanitizer.def:459:1: note: in expansion of macro ‘DEF_SANITIZER_BUILTIN’
>>>  DEF_SANITIZER_BUILTIN(BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT
>>
>> I would view these as helpful errors and expect them to be fixed
>> by terminating the macro invocations with a semicolon rather than
>> by adding it to the macro definition itself.  Is there a problem
>> with doing that that I'm not considering?
>
> There is a problem with it, as I wrote.
> The macros are used e.g. like:
> #define DEF_BUILTIN(ENUM, N, C, T, LT, B, F, NA, AT, IM, COND) ENUM,
> enum built_in_function {
> #include "builtins.def"
> };
> (similarly for the names various other cases).
>
> If the *.def files contain the semicolon, then this is not possible.

I see.

I suppose one way to deal with it would be to add yet another macro
and define it to expand to a semicolon before the #include directive
and to nothing after it, and use to terminate the definition of
DEF_SANITIZER_BUILTIN.  It's not pretty and I'm not sure it's worth
it.



Martin

Patch hide | download patch | download mbox

diff --git a/gcc/asan.c b/gcc/asan.c
index edcc6ea..876bb6f 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -2565,15 +2565,21 @@  initialize_sanitizer_builtins (void)
  #define ATTR_PURE_NOTHROW_LEAF_LIST ECF_PURE | ATTR_NOTHROW_LEAF_LIST
  #undef DEF_BUILTIN_STUB
  #define DEF_BUILTIN_STUB(ENUM, NAME)
+
+#define DEF_SANITIZER_BUILTIN_TERM ;
  #undef DEF_SANITIZER_BUILTIN
-#define DEF_SANITIZER_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
+#define DEF_SANITIZER_BUILTIN(ENUM, NAME, TYPE, ATTRS)  do {           \
    decl = add_builtin_function ("__builtin_" NAME, TYPE, ENUM,          \
                                BUILT_IN_NORMAL, NAME, NULL_TREE);       \
    set_call_expr_flags (decl, ATTRS);                                   \
-  set_builtin_decl (ENUM, decl, true);
+  set_builtin_decl (ENUM, decl, true);                                 \
+  } while (0) DEF_SANITIZER_BUILTIN_TERM

  #include "sanitizer.def"

+#undef DEF_SANITIZER_BUILTIN_TERM
+#define DEF_SANITIZER_BUILTIN_TERM /* empty */
+
    /* -fsanitize=object-size uses __builtin_object_size, but that might
       not be available for e.g. Fortran at this point.  We use
       DEF_SANITIZER_BUILTIN here only as a convenience macro.  */
@@ -2581,7 +2587,7 @@  initialize_sanitizer_builtins (void)
        && !builtin_decl_implicit_p (BUILT_IN_OBJECT_SIZE))
      DEF_SANITIZER_BUILTIN (BUILT_IN_OBJECT_SIZE, "object_size",
                            BT_FN_SIZE_CONST_PTR_INT,
-                          ATTR_PURE_NOTHROW_LEAF_LIST)
+                          ATTR_PURE_NOTHROW_LEAF_LIST);

  #undef DEF_SANITIZER_BUILTIN
  #undef DEF_BUILTIN_STUB