How to fix code to avoid warning -Wunsafe-buffer-usage

How to fix code to avoid warning -Wunsafe-buffer-usage


6

Before clang 16.0 I was able to compile all my projects using -Weveything without problems,
fixing my code and paying attention to the (useful) warnings that this option gave.
However, it seems that the -Wunsafe-buffer-usage was added in version 16 (my system updated to it recently)
and then compiling any project is impossible without getting a huge list of useless warnings about any pointer being used, see minimal example below:

$ cat main.c
#include <stdio.h>

int main(int argc, char **argv) {
    if (argc != 2) {
        return 0;
    }
    printf("argv[1] = %sn", argv[1]);
}

$ clang -Weverything main.c
main.c:3:27: warning: 'argv' is an unsafe pointer used for buffer access [-Wunsafe-buffer-usage]
int main(int argc, char **argv) {
                   ~~~~~~~^~~~
main.c:7:30: note: used in buffer access here
    printf("argv[1] = %sn", argv[1]);
                             ^~~~
1 warning generated.

One can’t possibly reason about his code using this warning.

The clang documentation has the following to say:

Since -Weverything enables every diagnostic, we generally don’t recommend using it. -Wall -Wextra are a better choice for most projects. Using -Weverything means that updating your compiler is more difficult because you’re exposed to experimental diagnostics which might be of lower quality than the default ones. If you do use -Weverything then we advise that you address all new compiler diagnostics as they get added to Clang, either by fixing everything they find or explicitly disabling that diagnostic with its corresponding Wno- option.

In this case, how would I "fix everything they find"?

Setting -Wno-unsafe-buffer-usage works, but it is an ugly solution.
It adds clutter to a Makefile and feels like cheating.

New contributor

lucas.mior is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

8

  • 1

    I'd offer that fighting with -Weverything may not be a battle you want to start. You may be able to make -Weverything happy in this case, but there will be many more warnings you'll need to satisfy, many of which may require making your code worse to "fix". For example, satisfying -Wdeclaration-after-statement would require declaring all local variables at the top of functions instead of as needed.

    – Brian61354270

    8 hours ago

  • I think the other warnings I have encountered so far are at least potentially useful. -Wdeclaration-after-statement makes me organize my declarations in the proper scopes. Note that it does not complain about for (int i = 0; i < n; i += 1). If it did, then I would agree with you with this particular example.

    – lucas.mior

    8 hours ago


  • 1

    Where I use -Weverything, I also counter some options with -Wno-xyz variants. One script I use has: -Weverything -Wno-padded -Wno-vla -Wno-reserved-id-macro -Wno-documentation-unknown-command -Wno-poison-system-directories -Wno-format-nonliteral. I build format strings in a number of the programs, hence -Wno-format-nonliteral. I use VLAs in matrix manipulation code (and carefully in other places too), so I need -Wno-vla. I use feature test macros (for POSIX, and also systems like Solaris) to determine how to compile code, so -Wno-reserved-id-macro was necessary. […continued…]

    – Jonathan Leffler

    8 hours ago

  • 1

    […continuation…] I needed -Wno-documentation-unknown-command was because clang undertook to critique a comment containing "** Hex character constant - xHH or xH, where H is a hex digit.". I needed -Wno-poison-system-directories because clang designated /usr/local/include as unsafe for cross-compilation. So, -Weverything is a blunderbuss that, for me, does not work on real-world programs (or, at least, it does not work for me in my tiny little corner of the real world). I've not run afoul of that option yet, but I've not recently checked my code thoroughly on my Mac.

    – Jonathan Leffler

    8 hours ago


  • Re “One can't possibly reason about his code using this warning”: How so? One can enable the warning, compiler, and manually evaluate every place in the code it reports an error. Nothing prevents you from using reasoning on those places. Did you mean one cannot rely on every warning it produces to be an actual error in the code? That is a different thing. And it is not necessary that every warning it produces be an actual error for it to be useful in pointing out places where there are errors.

    – Eric Postpischil

    2 hours ago


1 Answer
1


6

I made several attempts at addressing this particular warning with version 16.0.0 at godbolt, i.e. checking argv != NULL && argv[1] != NULL before the call to printf, but was unsuccessful. In fact, even this particular check triggered the warning.

Given that the documentation explicitly recommends not using -Weverything and if you do to use the corresponding -Wno- option for warnings that are not useful, and that it’s not clear exactly how this warning could be addressed (I’m unable to find documentation on this option), adding -Wno-unsafe-buffer-usage is probably the best option.

12

  • 2

    Yes, but the documentation says "either by fixing everything they find or explicitly disabling …" What is the point of a warning whose code it warns against can't be fixed even in such central aspect of a program?

    – lucas.mior

    8 hours ago


  • 2

    @lucas.mior I think you may not have an option but to ignore in this case. It also seems you're not the only person to have trouble with this option.

    – dbush

    8 hours ago

  • 1

    @lucas.mior Re: "What is the point of a warning whose code it warns against can't be fixed even in such central aspect of a program" I think that's part of "experimental diagnostics" .

    – dbush

    7 hours ago

  • 1

    @lucas.mior: Re “What is the point of a warning whose code it warns against can't be fixed even in such central aspect of a program?”: As the documentation states, the additional warnings in -Weverything are experimental. The purpose of the experiment is to get feedback: The Clang maintainers test warning options to see how useful they are and what problems there might be with them. People using -Weverything should report problems to the Clang maintainers, including sample code that demonstrates the problems, so the Clang maintainers can consider improvements. That is the point.

    – Eric Postpischil

    6 hours ago

  • 1

    @EricPostpischil "can consider improvements" is a bit questionable, discourse.llvm.org/t/rfc-c-buffer-hardening/65734/85 says this warning currently fires at "int main(int argc, char const** argv)" where (afaict) there is no getting around it

    – yvs2014

    2 hours ago



Leave a Reply

Your email address will not be published. Required fields are marked *