Skip to content

relocation diagnostics asserts in response to code that is broken for unrelated reasons #awesome #143325

@ojhunt

Description

@ojhunt

I made an error in one of my test cases and got a crash due to a null value. After much confusion I realized the problem is actually that I had redefined the same struct multiple times, and that's what caused the unexpected state.

The test case:

struct Foo  {
  Foo(const Foo&);
  ~Foo();
};

struct Foo {
  Foo();
  int;
};

struct Wrapper {
  union {
    Foo p;
  } u;
};
static_assert(__builtin_is_cpp_trivially_relocatable(Wrapper));

The assertion is triggered under DiagnoseNonTriviallyRelocatableReason in this code:

  if (!D->hasSimpleMoveConstructor() && !D->hasSimpleCopyConstructor()) {
    const auto *Decl = cast<CXXConstructorDecl>(
        LookupSpecialMemberFromXValue(SemaRef, D, /*Assign=*/false));
    if (Decl && Decl->isUserProvided())
      SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
          << diag::TraitNotSatisfiedReason::UserProvidedCtr
          << Decl->isMoveConstructor() << Decl->getSourceRange();
  }

The issue is the cast< CXXConstructorDecl > as LookupSpecialMemberFromXValue can return null. The cast<> is followed by a null check so it's presumably expected that LookupSpecialMemberFromXValue returns null, in which case the fix is likely just to replace cast with cast_or_null. If it's expected that the cast itself may fail then I assume there's dyn_cast_or_null that should be used.

Metadata

Metadata

Assignees

Labels

clang:frontendLanguage frontend issues, e.g. anything involving "Sema"crashPrefer [crash-on-valid] or [crash-on-invalid]

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions