Skip to content

DiagRuntimeBehavior (and presumably the CFG in general) incorrectly determines reachability in the presence of __builtin_is_constant_evaluated #119928

@zygoloid

Description

@zygoloid

Testcase:

void f(int k) {
  // No UB. But warns about UB.
  const int m = __builtin_is_constant_evaluated() ? 0 : *(int*)0;
}

void g(int k) {
  // Has UB. But does not warn about UB.
  const int m = __builtin_is_constant_evaluated() ? k : *(int*)0;
}

Presumably we get f wrong because the CFG builder evaluates __builtin_is_constant_evaluated() to false when building a CFG for the conditional expression. But I'm unsure why we get g wrong too.

Perhaps the CFG builder could track whether it's within a manifestly constant evaluated context, and pass that information into the constant evaluator. However, with the likely upcoming changes adding reflection to C++, there'll be other ways in which constant evaluation becomes context-dependent, so this might not be a particularly good solution in the longer term.

Another possible option would be to make the CFG builder entirely skip constant expressions, and instead just use the already-known constant values from them. The C++ language rules already require UB checking within constant expressions, so most additional CFG-based checks are likely to be redundant (though not all of them).

Metadata

Metadata

Assignees

No one assigned

    Labels

    clang:diagnosticsNew/improved warning or error message in Clang, but not in clang-tidy or static analyzerclang:frontendLanguage frontend issues, e.g. anything involving "Sema"constexprAnything related to constant evaluation

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions