Skip to content

Compiler assertion failure with -O, zero-size struct, and NonCopyable #10028

@MicahChalmer

Description

@MicahChalmer
Contributor

This program:

use std::util::NonCopyable;
struct Foo {
    nocopies: NonCopyable
}

fn make_foo() -> Foo {
    Foo { nocopies: NonCopyable::new() }
}

fn main() {
    let _f:Foo = make_foo();
}

will cause the compiler to crash and print this when compiled with -O:

Assertion failed: (begin() + idx < end()), function operator[], file /Users/micah/progs/rust/src/llvm/include/llvm/ADT/SmallVector.h, line 140.
Stack dump:
0.  Running pass 'Function Pass Manager' on module 'dag_dawg.rc'.
1.  Running pass 'X86 DAG->DAG Instruction Selection' on function '@_ZN4main19heaa017369cfad4b1ar4v0.0E'

(dag_dawg.rs was the file name I tried to compile.) Without -O it compiles fine. If you replace NonCopyable::new() with just NonCopyable it compiles fine, suggesting that NonCopyable::new() itself is no longer even necessary.

I created my own version of NonCopyable in another crate and linked to it. The crash reproduced only if, like std::NonCopyable, my struct had the attribute #[unsafe_no_drop_flag].

Add a non-zero-length field to the struct and the crash goes away.

Activity

sanxiyn

sanxiyn commented on Jan 17, 2014

@sanxiyn
Member

NonCopyable::new was removed in #10575. Can you provide a test case not depending on NonCopyable::new?

MicahChalmer

MicahChalmer commented on Jan 18, 2014

@MicahChalmer
ContributorAuthor

Yup, I can still reproduce it. You need two files for it. The first is a library crate, which compiles fine--let's call it issue10028.rs:

#[crate_type="lib"];

#[unsafe_no_drop_flag]
pub struct ZeroLengthThingWithDestructor;
impl Drop for ZeroLengthThingWithDestructor {
    fn drop(&mut self) {}
}
impl ZeroLengthThingWithDestructor {
    pub fn new() -> ZeroLengthThingWithDestructor {
        ZeroLengthThingWithDestructor
    }
}

The library crate compiles fine. Now try to compile this file that uses it with rustc -O (allowing it to find the library built from above) and you'll see the same ICE described above:

extern mod issue10028;
use issue10028::ZeroLengthThingWithDestructor;

struct Foo {
    zero_length_thing: ZeroLengthThingWithDestructor
}

fn make_foo() -> Foo {
    Foo { zero_length_thing: ZeroLengthThingWithDestructor::new() }
}

fn main() {
    let _f:Foo = make_foo();
}

This is basically the same test case I had before--I just replaced NonCopyable with another struct that is the same as the old NonCopyable before the new method was eliminated.

If you combine them into the same crate (even issue10028.rs is still its own file as a module) then the problem does not occur. It has to be in a separate crate from the one being compiled.

alexcrichton

alexcrichton commented on Mar 1, 2014

@alexcrichton
Member

This has been fixed, flagging as needstest

added a commit that references this issue on Mar 6, 2014
13e10f5
added a commit that references this issue on Mar 6, 2014
0e95b08
added a commit that references this issue on Feb 10, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    E-needs-testCall for participation: An issue has been fixed and does not reproduce, but no test has been added.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      Participants

      @sanxiyn@alexcrichton@MicahChalmer

      Issue actions

        Compiler assertion failure with -O, zero-size struct, and NonCopyable · Issue #10028 · rust-lang/rust