Skip to content

Incorrect format string determination from manifestly constant-evaluated contexts #135913

Open
@hubert-reinterpretcast

Description

@hubert-reinterpretcast

Clang does not observe the surrounding manifestly constant-evaluated context when attempting -Wformat diagnostics.
In the case below, the program semantics uses the "%d\n" format string.
Clang diagnoses on the basis of the "%!\n" string instead.

https://godbolt.org/z/cGsM5Mjn5

Source (<stdin>)

#include <stdio.h>
#include <stdarg.h>

constexpr auto const_string() {
  if consteval {
    return "%d\n";
  }
  return "%!\n";
}

constexpr auto getvprintf [[gnu::format(__printf__, 1, 0)]](const char *format) {
  return [=](va_list vp) {
    return vprintf(format, vp);
  };
}

constexpr auto myvprintf = getvprintf(const_string());

void q(int x, ...) {
  va_list ap;
  va_start(ap, x);
  myvprintf(ap);
  va_end(ap);
}

int main(void) {
  q(0, 42);
}

Compiler invocation command

clang++ -fsyntax-only -Wall -Wextra -pedantic -std=c++2c -xc++ -

Actual compiler output

<stdin>:17:39: warning: invalid conversion specifier '!' [-Wformat-invalid-specifier]
   17 | constexpr auto myvprintf = getvprintf(const_string());
      |                                       ^~~~~~~~~~~~~~
<stdin>:8:12: note: format string is defined here
    8 |   return "%!\n";
      |           ~^
1 warning generated.

Expected compiler output

(No warning)

Compiler version info (clang++ -v)

clang version 21.0.0git (https://github.com/llvm/llvm-project.git 77f0708b9d4feee8b8a67a5f571be741be4e26af)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /opt/wandbox/clang-head/bin
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/13
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/14
Selected GCC installation: /usr/lib/gcc/x86_64-linux-gnu/14
Candidate multilib: .;@m64
Selected multilib: .;@m64

Metadata

Metadata

Assignees

No one assigned

    Labels

    clang:diagnosticsNew/improved warning or error message in Clang, but not in clang-tidy or static analyzer

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions