diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -739,6 +739,8 @@ which specifies constrained lambdas and constrained template *template-parameter*\s. - Required parameter pack to be provided at the end of the concept parameter list. This fixes `Issue 48182 `_. +- Fixed a assert triggered in some cases of a ``consteval`` implicit cast constructor. Fixes + `Issue 53983 `_. - Do not hide templated base members introduced via using-decl in derived class (useful specially for constrained members). Fixes `GH50886 `_. diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -1334,7 +1334,8 @@ void CodeGenFunction::EmitAggregateStore(llvm::Value *Val, Address Dest, bool DestIsVolatile) { // Prefer scalar stores to first-class aggregate stores. - if (llvm::StructType *STy = dyn_cast(Val->getType())) { + llvm::StructType *STy = dyn_cast(Val->getType()); + if (STy && STy->canLosslesslyBitCastTo(Dest.getElementType())) { for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { Address EltPtr = Builder.CreateStructGEP(Dest, i); llvm::Value *Elt = Builder.CreateExtractValue(Val, i); diff --git a/clang/test/CodeGenCXX/cxx20-consteval-crash.cpp b/clang/test/CodeGenCXX/cxx20-consteval-crash.cpp --- a/clang/test/CodeGenCXX/cxx20-consteval-crash.cpp +++ b/clang/test/CodeGenCXX/cxx20-consteval-crash.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 %s -emit-llvm -o - | FileCheck %s -// RUN: %clang_cc1 -emit-obj -debug-info-kind=constructor -std=c++20 %s -o - +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 -fexceptions -fcxx-exceptions %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -emit-obj -debug-info-kind=constructor -std=c++20 -fexceptions -fcxx-exceptions %s -o - namespace PR50787 { // This code would previously cause a crash. @@ -92,3 +92,41 @@ } } // namespace Issue55065 +namespace Issue53983 { +// This code would previously cause a crash in code generation +// for the `bar` element in the `MyStruct` constructor. +struct Base { + constexpr Base() : a(), b() {} + char a : 1; + char b; +}; + +struct Foo : private Base { + constexpr Foo(bool b) { + if (b) throw "test"; + } +}; + +struct Bar : private Base { + consteval Bar(bool) {} +}; + +struct MyStruct { + Foo foo = true; + Bar bar = false; +}; +MyStruct structTest; + +// clang should issue a constructor for MyStruct that calls Foo and Bar, +// and a constructor for Bar that calls Base. +// CHECK: define{{.*}} void @_ZN10Issue539838MyStructC2Ev( +// CHECK: entry: +// CHECK: call void @_ZN10Issue539833FooC2Eb( +// CHECK: call void @_ZN10Issue539833BarC2Eb( +// CHECK: ret void + +// CHECK: define{{.*}} void @_ZN10Issue539833BarC2Eb( +// CHECK: entry: +// CHECK: call void @_ZN10Issue539834BaseC2Ev( +// CHECK: ret void +} // namespace Issue53983