Bug 83116 - [6 Regression] Statement with no effect causes wrong code of static object constexpr method
Summary: [6 Regression] Statement with no effect causes wrong code of static object co...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 7.2.0
: P2 normal
Target Milestone: 6.5
Assignee: Marek Polacek
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2017-11-22 20:38 UTC by Grzegorz Gajoch
Modified: 2017-12-19 10:03 UTC (History)
4 users (show)

See Also:
Host: x86_64-pc-linux-gnu
Target: x86_64-pc-linux-gnu
Build: --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/ --enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++ --enable-shared --enable-threads=posix --enable-libm
Known to work: 5.4.0
Known to fail: 6.1.0, 6.2.0, 6.3.0, 7.1.0, 7.2.0
Last reconfirmed: 2017-11-23 00:00:00


Attachments
Preprocessed source (4.02 KB, text/plain)
2017-11-22 20:38 UTC, Grzegorz Gajoch
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Grzegorz Gajoch 2017-11-22 20:38:44 UTC
Created attachment 42685 [details]
Preprocessed source

Following testcase:

$ cat main.cpp 
#include <cstdio>
 
struct foo {
    constexpr foo() : size_(0) {
        (void)size();
    }
    constexpr int size() {
        return size_;
    }
    int size_;
};
 
int main() {
    static foo var;
    var.size_ = 5;
    std::printf("%d %d", var.size_, var.size());
    return 0;
}

$ g++ -Wall -Wextra -pedantic -O0 main.cpp -o main && ./main
5 5

$ g++ -Wall -Wextra -pedantic -O1 main.cpp -o main && ./main
5 0

(Same happens on -Og, -O2 and -O3)

Tested on:
$ g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-linux-gnu/7.2.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: /build/gcc/src/gcc/configure --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/ --enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++ --enable-shared --enable-threads=posix --enable-libmpx --with-system-zlib --with-isl --enable-__cxa_atexit --disable-libunwind-exceptions --enable-clocale=gnu --disable-libstdcxx-pch --disable-libssp --enable-gnu-unique-object --enable-linker-build-id --enable-lto --enable-plugin --enable-install-libiberty --with-linker-hash-style=gnu --enable-gnu-indirect-function --disable-multilib --disable-werror --enable-checking=release --enable-default-pie --enable-default-ssp
Thread model: posix
gcc version 7.2.0 (GCC)


Correct behavior is seen using gcc-5.4, clang and msvc.
Removing constructor body gives correct code - this is stripped version, originally there was assert(this->size() >= 0);
UBSAN gives no results.

This bug occurs also on 6.1.0, 6.2.0, 6.3.0, 7.1.0, 7.2.0 and today's trunk (8.0.0 20171122), as tested on compiler explorer: https://godbolt.org/g/hr4Nq4
Comment 1 Jakub Jelinek 2017-11-23 14:50:30 UTC
Started with r230365.
Guess we need to remove the static var from constexpr caches at the end of construction if the var isn't constexpr.

Testcase modified for the testsuite:

// PR c++/83116
// { dg-do run { target c++14 } }

struct S {
  constexpr S () : s(0) { foo (); }
  constexpr int foo () { return s; }
  int s;
};

int
main ()
{
  static S var;
  var.s = 5;
  if (var.s != 5 || var.foo () != 5)
    __builtin_abort ();
}
Comment 2 Jakub Jelinek 2017-11-23 15:13:45 UTC
No idea where though.
Comment 3 Marek Polacek 2017-12-13 13:39:52 UTC
Seems this is not about cv_cache/fold_cache; the bug is present even if I disable putting anything into those caches.
Comment 4 Marek Polacek 2017-12-13 14:41:25 UTC
Ah, the result seems to be cached in constexpr_call_table!  I'll keep lookin'.
Comment 5 Marek Polacek 2017-12-18 21:25:48 UTC
Author: mpolacek
Date: Mon Dec 18 21:25:16 2017
New Revision: 255788

URL: https://gcc.gnu.org/viewcvs?rev=255788&root=gcc&view=rev
Log:
	PR c++/83116
	* constexpr.c (cxx_eval_call_expression): Only look into
	constexpr_call_table if ctx->strict.

	* g++.dg/cpp1y/constexpr-83116.C: New test.

Added:
    trunk/gcc/testsuite/g++.dg/cpp1y/constexpr-83116.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/constexpr.c
    trunk/gcc/testsuite/ChangeLog
Comment 6 Marek Polacek 2017-12-18 21:38:46 UTC
Fixed on trunk.
Comment 7 Marek Polacek 2017-12-19 10:03:20 UTC
Author: mpolacek
Date: Tue Dec 19 10:02:48 2017
New Revision: 255813

URL: https://gcc.gnu.org/viewcvs?rev=255813&root=gcc&view=rev
Log:
	PR c++/83116
	* constexpr.c (cxx_eval_call_expression): Only look into
	constexpr_call_table if ctx->strict.

	* g++.dg/cpp1y/constexpr-83116.C: New test.

Added:
    branches/gcc-7-branch/gcc/testsuite/g++.dg/cpp1y/constexpr-83116.C
Modified:
    branches/gcc-7-branch/gcc/cp/ChangeLog
    branches/gcc-7-branch/gcc/cp/constexpr.c
Comment 8 Marek Polacek 2017-12-19 10:03:46 UTC
Fixed.