Bug 57335 - internal compiler error: in cxx_eval_bit_field_ref, at cp/semantics.c:6977
Summary: internal compiler error: in cxx_eval_bit_field_ref, at cp/semantics.c:6977
Status: RESOLVED DUPLICATE of bug 79681
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.7.2
: P3 normal
Target Milestone: 6.4
Assignee: Kai Tietz
URL:
Keywords: ice-on-invalid-code, ice-on-valid-code
Depends on:
Blocks: constexpr
  Show dependency treegraph
 
Reported: 2013-05-20 10:41 UTC by Chet Simpson
Modified: 2018-02-11 19:55 UTC (History)
7 users (show)

See Also:
Host:
Target:
Build:
Known to work: 6.4.0
Known to fail: 4.9.3, 5.3.0, 6.0, 6.3.0
Last reconfirmed: 2013-05-20 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Chet Simpson 2013-05-20 10:41:39 UTC
This error appears to be caused though the static_assert on a constexpr containing a union.

prog.cpp: In function ‘int main()’:
prog.cpp:29:48:   in constexpr expansion of ‘BitsOrderCheck().BitsOrderCheck::IsLsbBottom()’
prog.cpp:29:58: internal compiler error: in cxx_eval_bit_field_ref, at cp/semantics.c:6977
Please submit a full bug report,
with preprocessed source if appropriate.
See <file:///usr/share/doc/gcc-4.7/README.Bugs> for instructions.
Preprocessed source stored into /home/nUBliJ/ccd38zvW.out file, please attach this to your bugreport.



#include <stdint.h>
#include <iostream>

struct BitsOrderCheck
{
    union Data
    {
        struct Bitfield
        {
            const unsigned char   clear:7;
            const unsigned char   set:1;
        };

        const unsigned char   byte;
        const Bitfield        bits;
        constexpr Data() : byte(1) {}
    };
    constexpr BitsOrderCheck() {}
    constexpr bool IsLsbBottom() const
    {
        return 1 == data_.bits.set;
    }

    const Data    data_;
};

int main()
{
    static_assert(BitsOrderCheck().IsLsbBottom(), "blah");
    std::cout << "LSB: " << BitsOrderCheck().IsLsbBottom() << std::endl;
    return 0;
}
Comment 1 Paolo Carlini 2013-05-20 10:56:07 UTC
Note: all the other compilers I have at hand reject the snippet with an error message about the static_assert expression not being constant (which behavior, in case the analysis shows it's correct, would be easy to obtain with GCC too)
Comment 2 Daniel Krügler 2013-05-20 11:37:05 UTC
(In reply to Paolo Carlini from comment #1)
I agree that the code should be rejected, because the created BitsOrderCheck object initializes the member 'byte' of the union and later attempts to read the member 'bits', thus causing the exclusion case of core constant expressions:

"an lvalue-to-rvalue conversion (4.1) or modification (5.17, 5.2.6, 5.3.2) that is applied to a glvalue that refers to a non-active member of a union or a subobject thereof;"
Comment 3 Paolo Carlini 2014-09-03 14:29:25 UTC
... but we ICE with the testcase adjusted too.
Comment 4 Paolo Carlini 2014-09-03 16:07:17 UTC
The code in cxx_eval_bit_field_ref needs some work, doesn't handle CONSTRUCTORs inside CONSTRUCTORs. This is a reduced testcase:

struct BitsOrderCheck
{
  struct Data
  {
    const unsigned char   set:1;
    constexpr Data() : set{1} {}
  };

  constexpr bool IsLsbBottom() const
  {
    return 1 == data_.set;
  }

  const Data    data_;
};

static_assert(BitsOrderCheck().IsLsbBottom(), "blah");
Comment 5 Jason Merrill 2014-11-18 03:41:27 UTC
Kai's delayed folding work ought to fix this by avoiding creating BIT_FIELD_REFs so soon.
Comment 6 Kai Tietz 2014-11-18 10:03:21 UTC
Yes, delayed folding fixes wrong-code/valid-code samples.

For invalid-code I see with delayed folding the following error-messages:

t_pr57335.C: In function 'int main()':
t_pr57335.C:29:5: error: non-constant condition for static assertion
     static_assert(BitsOrderCheck().IsLsbBottom(), "blah");
     ^
t_pr57335.C:29:47:   in constexpr expansion of 'BitsOrderCheck().BitsOrderCheck::IsLsbBottom()'
t_pr57335.C:29:5: error: accessing 'BitsOrderCheck::Data::bits' member instead of initialized 'BitsOrderCheck::Data::byte' member in constant expression

Not sure if this is desired.
Comment 7 Jason Merrill 2014-11-18 13:43:26 UTC
(In reply to Kai Tietz from comment #6)
> t_pr57335.C:29:5: error: accessing 'BitsOrderCheck::Data::bits' member
> instead of initialized 'BitsOrderCheck::Data::byte' member in constant
> expression

Yes, that's the desired behavior for this testcase.
Comment 8 Paolo Carlini 2014-11-21 10:37:12 UTC
Good. What about the snippet in Comment #4, though? That one seems Ok to me and meaning that cxx_eval_bit_field_ref needs some work.
Comment 9 Kai Tietz 2014-11-21 12:45:00 UTC
Yes, that works without any warnings with delayed-folding patch.
(I mentioned it in comment #6 as *valid-code* sample)
Comment 10 Paolo Carlini 2014-11-21 13:40:57 UTC
Ah, excellent.
Comment 11 Kai Tietz 2015-04-27 17:49:47 UTC
Mine.
Comment 12 Paolo Carlini 2015-11-18 10:46:57 UTC
Surprisingly, no progress on this!? Any quick idea? Otherwise, I'm going to look into it a bit (again)...
Comment 13 Martin Sebor 2016-03-09 03:39:07 UTC
Reconfirming as still failing with today's top of trunk (6.0), plus 5.x and 4.9.3.  I get the following stack trace on the small test case from comment #4:

z.c:18:43:   in constexpr expansion of ‘BitsOrderCheck().BitsOrderCheck::IsLsbBottom()’
z.c:18:54: internal compiler error: in cxx_eval_bit_field_ref, at cp/constexpr.c:2095
 static_assert(BitsOrderCheck().IsLsbBottom(), "blah");
                                                      ^
0xa49fd0 cxx_eval_bit_field_ref
	/home/msebor/scm/fsf/gcc-svn/gcc/cp/constexpr.c:2095
0xa4fe83 cxx_eval_constant_expression
	/home/msebor/scm/fsf/gcc-svn/gcc/cp/constexpr.c:3657
0xa48278 cxx_eval_binary_expression
	/home/msebor/scm/fsf/gcc-svn/gcc/cp/constexpr.c:1617
0xa4fcde cxx_eval_constant_expression
	/home/msebor/scm/fsf/gcc-svn/gcc/cp/constexpr.c:3614
0xa48278 cxx_eval_binary_expression
	/home/msebor/scm/fsf/gcc-svn/gcc/cp/constexpr.c:1617
0xa4fcde cxx_eval_constant_expression
	/home/msebor/scm/fsf/gcc-svn/gcc/cp/constexpr.c:3614
0xa4d68e cxx_eval_store_expression
	/home/msebor/scm/fsf/gcc-svn/gcc/cp/constexpr.c:2938
0xa4f5bb cxx_eval_constant_expression
	/home/msebor/scm/fsf/gcc-svn/gcc/cp/constexpr.c:3441
0xa4f6b0 cxx_eval_constant_expression
	/home/msebor/scm/fsf/gcc-svn/gcc/cp/constexpr.c:3454
0xa477b2 cxx_eval_call_expression
	/home/msebor/scm/fsf/gcc-svn/gcc/cp/constexpr.c:1393
0xa4ee03 cxx_eval_constant_expression
	/home/msebor/scm/fsf/gcc-svn/gcc/cp/constexpr.c:3364
0xa50f6f cxx_eval_outermost_constant_expr
	/home/msebor/scm/fsf/gcc-svn/gcc/cp/constexpr.c:3929
0xa51970 maybe_constant_value_1
	/home/msebor/scm/fsf/gcc-svn/gcc/cp/constexpr.c:4117
0xa51a6d maybe_constant_value(tree_node*, tree_node*)
	/home/msebor/scm/fsf/gcc-svn/gcc/cp/constexpr.c:4138
0x9ba7a2 finish_static_assert(tree_node*, tree_node*, unsigned int, bool)
	/home/msebor/scm/fsf/gcc-svn/gcc/cp/semantics.c:8673
0x8ec892 cp_parser_static_assert
	/home/msebor/scm/fsf/gcc-svn/gcc/cp/parser.c:13034
0x8eb80b cp_parser_block_declaration
	/home/msebor/scm/fsf/gcc-svn/gcc/cp/parser.c:12228
0x8eb5ad cp_parser_declaration
	/home/msebor/scm/fsf/gcc-svn/gcc/cp/parser.c:12129
0x8eb0ff cp_parser_declaration_seq_opt
	/home/msebor/scm/fsf/gcc-svn/gcc/cp/parser.c:12008
0x8db2aa cp_parser_translation_unit
	/home/msebor/scm/fsf/gcc-svn/gcc/cp/parser.c:4321
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <http://gcc.gnu.org/bugs.html> for instructions.
Comment 14 Orgad Shaneh 2016-05-14 20:35:41 UTC
With 6.1, this doesn't only fail for static_assert. Even a simple function call fails:

struct Bits {
    unsigned char a : 7;
    unsigned char b : 1;
    constexpr Bits() : a(0), b(0) {}
};

struct Foo
{
    constexpr Foo(int) { }

    constexpr bool b() const { return bits.b; }

private:
    Bits bits;
};

void func(bool) {}

void foo() {
    constexpr Foo foo(42);
    func(foo.b());
}


../test/foo.cpp: In function ‘void foo()’:
../test/foo.cpp:21:14:   in constexpr expansion of ‘foo.Foo::b()’
../test/foo.cpp:21:16: internal compiler error: in cxx_eval_bit_field_ref, at cp/constexpr.c:2226
     func(foo.b());
                 ^
0x6fbb43 cxx_eval_bit_field_ref
	../../src/gcc/cp/constexpr.c:2226
0x6fbb43 cxx_eval_constant_expression
	../../src/gcc/cp/constexpr.c:3849
0x6fed08 cxx_eval_binary_expression
	../../src/gcc/cp/constexpr.c:1725
0x6f9c52 cxx_eval_constant_expression
	../../src/gcc/cp/constexpr.c:3806
0x6fed08 cxx_eval_binary_expression
	../../src/gcc/cp/constexpr.c:1725
0x6f9c52 cxx_eval_constant_expression
	../../src/gcc/cp/constexpr.c:3806
0x6fc651 cxx_eval_store_expression
	../../src/gcc/cp/constexpr.c:3123
0x6fa39c cxx_eval_constant_expression
	../../src/gcc/cp/constexpr.c:3633
0x6f9f88 cxx_eval_constant_expression
	../../src/gcc/cp/constexpr.c:3645
0x6f92d2 cxx_eval_call_expression
	../../src/gcc/cp/constexpr.c:1494
0x6fab6f cxx_eval_constant_expression
	../../src/gcc/cp/constexpr.c:3556
0x6f9f08 cxx_eval_constant_expression
	../../src/gcc/cp/constexpr.c:3901
0x6fd1f6 cxx_eval_outermost_constant_expr
	../../src/gcc/cp/constexpr.c:4121
0x6feabc maybe_constant_value_1
	../../src/gcc/cp/constexpr.c:4316
0x6feabc maybe_constant_value(tree_node*, tree_node*)
	../../src/gcc/cp/constexpr.c:4340
0x5d6b11 build_over_call
	../../src/gcc/cp/call.c:7561
0x5d879f build_new_function_call(tree_node*, vec<tree_node*, va_gc, vl_embed>**, bool, int)
	../../src/gcc/cp/call.c:4152
0x6acaca finish_call_expr(tree_node*, vec<tree_node*, va_gc, vl_embed>**, bool, bool, int)
	../../src/gcc/cp/semantics.c:2461
0x65eaf2 cp_parser_postfix_expression
	../../src/gcc/cp/parser.c:6904
0x65cee2 cp_parser_unary_expression
	../../src/gcc/cp/parser.c:7988
Comment 15 Volker Reichelt 2018-02-11 19:55:59 UTC
This was fixed in GCC 6.4.0, possibly by the fix for PR79681.

*** This bug has been marked as a duplicate of bug 79681 ***