https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127297

            Bug ID: 127297
           Summary: [c++26][contracts] the postcondition const-parameter
                    diagnostic is emitted twice for a non-template
                    function
           Product: gcc
           Version: 16.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: berne at notadragon dot com
  Target Milestone: ---

Created attachment 65543
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=65543&action=edit
One line; the const-parameter diagnostic is emitted twice for it

For a non-template function, the [dcl.contract.func] const-parameter
diagnostic is emitted twice: byte-identical message, byte-identical
location, and an identical note each time.

```
int f(int v) post(r : v == r) { return v; }
```

```
$ ./gcc-16.2.0/bin/g++ -std=c++26 -fsyntax-only \
    postcondition-const-nontemplate.C
postcondition-const-nontemplate.C:7:23: error: a value parameter used in a
postcondition must be const
    7 | int f(int v) post(r : v == r) { return v; }
      |                       ^
postcondition-const-nontemplate.C:7:11: note: parameter declared here
    7 | int f(int v) post(r : v == r) { return v; }
      |       ~~~~^
postcondition-const-nontemplate.C:7:23: error: a value parameter used in a
postcondition must be const
    7 | int f(int v) post(r : v == r) { return v; }
      |                       ^
postcondition-const-nontemplate.C:7:11: note: parameter declared here
    7 | int f(int v) post(r : v == r) { return v; }
      |       ~~~~^
```

The diagnosis itself is correct -- the program is ill-formed and should be
rejected.  Only the duplication is the defect.

Worth distinguishing from a case that is not a defect: for a function
template, two different diagnostics are emitted, one naming the parameter
and one pointing at the contract.  Those come from two mechanisms that
deliberately anchor at different places, and with more than one parameter or
more than one postcondition they say genuinely different things.  It is only
the non-template path above, where the same mechanism fires twice with the
same words at the same column, that is wrong.

DISCOVERY

Found while fixing a neighbouring defect in the same rule, by reading the
diagnostics the fix produced rather than only whether the program was
rejected -- the duplication is invisible to a test that just checks for an
error.

ANALYSIS

Both emissions come from the same place with the same location, so this is
the odr-use walk reaching the parameter twice rather than the two distinct
mechanisms firing.  A postcondition's predicate is examined once through the
declaration and once more when the definition is processed, and for a
non-template both examinations reach the same tree.

VERSIONS -- all on x86_64-linux-gnu

  source              version                       emitted twice
  compiler-explorer   16.1.0                        yes
  compiler-explorer   16.2.0                        yes
  compiler-explorer   17.0.0 20260909, 919c0d16c91  yes
  local build -g      17.0.0 20260909, 7dab38c9d71  yes

```
$ ./gcc-16.2.0/bin/g++ -v
Using built-in specs.
COLLECT_GCC=./gcc-16.2.0/bin/g++
COLLECT_LTO_WRAPPER=/home/jberne4/repos/compilers/gcc-16.2.0/bin/../libexec/gcc/x86_64-linux-gnu/16.2.0/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../gcc-16.2.0/configure
--prefix=/opt/compiler-explorer/gcc-build/staging --build=x86_64-linux-gnu
--host=x86_64-linux-gnu --target=x86_64-linux-gnu --disable-bootstrap
--enable-multiarch --with-abi=m64 --with-multilib-list=m32,m64,mx32
--enable-multilib --enable-clocale=gnu
--enable-languages=c,c++,fortran,ada,objc,obj-c++,go,d,m2,rust,cobol,algol68
--enable-ld=yes --enable-gold=yes --enable-libstdcxx-time=yes
--enable-linker-build-id --enable-lto --enable-plugins --enable-threads=posix
--with-pkgversion=Compiler-Explorer-Build-gcc--binutils-2.44
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 16.2.0 (Compiler-Explorer-Build-gcc--binutils-2.44)
```

Reply via email to