On 03/06/2017 02:44 PM, Marek Polacek wrote:
This is an ICE with -fsanitize=undefined on invalid code involving old-style
parameter declarations and nested functions.  Ugh.

Old-style parameter declarations cannot have initializers, and start_decl
errors when it sees that something's trying to initialize a PARM_DECL, but
nonetheless, we still attempt to parse the initializer, eventually arriving in
build_binary_op, which means we will instrument the bogus initializer.

This causes a crash in ubsan_encode_value -> create_tmp_var -> declare_vars: it
thinks it's processing a nested function, but the body of the function is null,
leading to the crash.

I suppose the best fix is to avoid instrumenting such bogus initializers.  In
c_parser_declaration_or_fndef it's easy to determine if we're initializing a
PARM_DECL -- just check DECL's code, but with __auto_type that's not possible,
because start_decl is called *after* parsing the initializer.  So instead of
DECL's code I'm checking nested && !empty_ok.

But we still want to instrument variables with initializers in nested
functions, so I've added two run-time tests for that.

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2017-03-06  Marek Polacek  <pola...@redhat.com>

        PR sanitizer/79757
        * c-parser.c (c_parser_declaration_or_fndef): Don't sanitize old-style
        parameter declarations with initializers.

        * gcc.dg/ubsan/pr79757-1.c: New test.
        * gcc.dg/ubsan/pr79757-2.c: New test.
        * gcc.dg/ubsan/pr79757-3.c: New test.
        * gcc.dg/ubsan/pr79757-4.c: New test.
        * gcc.dg/ubsan/pr79757-5.c: New test.
This isn't marked as a regression, but it clearly is a regression given we didn't ICE prior to r205714.

OK for the trunk.

Thanks for adding tests that verify we are instrumenting initializers in nested functions.

jeff


Reply via email to