Bug 58102 - rejects valid initialization of constexpr object with mutable member
Summary: rejects valid initialization of constexpr object with mutable member
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.9.0
: P3 normal
Target Milestone: 5.0
Assignee: Jason Merrill
URL:
Keywords:
Depends on:
Blocks: constexpr
  Show dependency treegraph
 
Reported: 2013-08-07 19:44 UTC by Richard Smith
Modified: 2014-11-18 14:03 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2014-09-01 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Richard Smith 2013-08-07 19:44:43 UTC
Given

  struct S {
    mutable int n;
    constexpr S() : n() {}
  };

GCC correctly accepts:

  constexpr S s {};

but incorrectly rejects:

  constexpr S s = {};

saying:

<stdin>: At global scope:
<stdin>:5:20: error: ‘const S’ cannot be the type of a complete constant expression because it has mutable sub-objects

Per core issue 1405, both the above cases are valid.
Comment 1 Paolo Carlini 2014-09-01 10:42:28 UTC
Mine.
Comment 2 Paolo Carlini 2014-09-15 16:27:11 UTC
Richard I'm trying to fix this bug, and while working on a draft I noticed that current clang accepts:

struct A
{
  int i;
  mutable int j;
};

constexpr A a = { 0, 1 };
constexpr A b = a;

ie, doesn't reject the last line, whereas we actively do and we think we are doing the right thing. What's your opinion?
Comment 3 Richard Smith 2014-09-16 01:33:52 UTC
Thanks, that is (was) a Clang bug; I've just fixed it. And there's a standard defect here too, as far as I can see:

  union U { int a; mutable int b; };
  constexpr U u1 = {1};
  int k = (u1.b = 2);
  constexpr U u2 = u1;

... should be ill-formed, but as far as I can see it's not (the union construction copies the object representation, and never looks at the fields).
Comment 4 Jason Merrill 2014-11-18 13:34:40 UTC
Author: jason
Date: Tue Nov 18 13:34:08 2014
New Revision: 217713

URL: https://gcc.gnu.org/viewcvs?rev=217713&root=gcc&view=rev
Log:
	PR c++/58102
	* typeck2.c (store_init_value): Set it.
	* cp-tree.h (CONSTRUCTOR_MUTABLE_POISON): New.
	* constexpr.c (cxx_eval_outermost_constant_expr): Check it.

Added:
    trunk/gcc/testsuite/g++.dg/cpp0x/constexpr-mutable2.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/constexpr.c
    trunk/gcc/cp/cp-tree.h
    trunk/gcc/cp/typeck2.c
Comment 5 Jason Merrill 2014-11-18 14:03:51 UTC
Fixed for GCC 5.