llvm/llvm-project

Unrelated errors introduce additional runtime diagnostics by skipping CFG construction

Open

#58,276 创建于 2022年10月10日

在 GitHub 查看
 (10 评论) (0 反应) (0 负责人)C++ (10,782 fork)batch import
clang:diagnosticsgood first issue

仓库指标

Star
 (26,378 star)
PR 合并指标
 (平均合并 1天 2小时) (30 天内合并 1,000 个 PR)

描述

Consider: https://gcc.godbolt.org/z/dq6q8xxhY

#include <string.h>
struct Foo {
    virtual ~Foo();
    int x;
};
#error
constexpr bool alwaysFalse = false;
void maywarn(Foo *p) {
    if constexpr (alwaysFalse) {
        memset(p, 0, sizeof(*p));
    }
    if (alwaysFalse) {
        memset(p, 0, sizeof(*p)); // warns
    }
}

This produces this -Wdynamic-class-memaccess warning:

<source>:15:16: warning: destination for this 'memset' call is a pointer to dynamic class 'Foo'; vtable pointer will be overwritten [-Wdynamic-class-memaccess]
        memset(p, 0, sizeof(*p));
        ~~~~~~ ^
<source>:15:16: note: explicitly cast the pointer to silence this warning
        memset(p, 0, sizeof(*p));
               ^
               (void*)

This goes away if you remove the #error.

This causes issues because this latent warning can be present in header files in a warning-clean codebase, and it only appears when developers later introduce an error. The extra warning can obscure the actual problem because, with -Werror, developers end up seeing two errors.

These two conditionals prevent Clang from doing CFG-based warnings in the presence of errors:

To fix the bug, we need to modify those conditionals to either:

  • Always construct a CFG for analysis even in the presence of errors
  • Don't issue any diagnostics about possibly unreachable code in the presence of other errors

I've prototyped both changes, and they break a lot of Clang tests, and I'm filing this issue to track followup.

贡献者指南