Open hubert-reinterpretcast opened 7 years ago
This reproduces (with a slightly different assertion) with the same instructions as was originally provided using a build with assertions enabled:
Can confirm -- I had missed that the original was an assertion (despite it being in the title), so I was testing a release without asserts build. When I test on an asserts build, I get the miscompile. Thanks for reopening!
This reproduces (with a slightly different assertion) with the same instructions as was originally provided using a build with assertions enabled:
/llvm/clang/lib/CodeGen/CGCall.cpp:4669: clang::CodeGen::RValue clang::CodeGen::CodeGenFunction::EmitCall(const clang::CodeGen::CGFunctionInfo &, const clang::CodeGen::CGCallee &, clang::CodeGen::ReturnValueSlot, const clang::CodeGen::CallArgList &, llvm::CallBase **, bool, clang::SourceLocation): Assertion `IRFuncTy == TypeFromVal' failed.
The arguments to the inherited constructor are "passed into the void".
It seems that a different symptom of the same problem is how such arguments with non-trivial destruction fail to get destroyed when compiling for the MS ABI.
https://godbolt.org/z/d4a5x8MYq
struct NonTriv {
NonTriv(int);
~NonTriv();
};
extern "C" void LookForThis(void);
NonTriv::~NonTriv() {
LookForThis();
}
NonTriv LookForThat(void);
struct V { V() = default; V(NonTriv); };
struct A : virtual V {
using V::V;
A() : A(LookForThat()) { }
};
struct B : A { };
void foo() { B b; }
-target x86_64-pc-windows -emit-llvm -O -g0
define dso_local void @"?foo@@YAXXZ"() local_unnamed_addr #2 personality i32 (...)* @__CxxFrameHandler3 {
%1 = alloca %struct.NonTriv, align 1
%2 = getelementptr inbounds %struct.NonTriv, %struct.NonTriv* %1, i64 0, i32 0
call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull %2)
call void @"?LookForThat@@YA?AUNonTriv@@XZ"(%struct.NonTriv* nonnull sret(%struct.NonTriv) align 1 %1)
call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull %2)
ret void
}
It appears that there is no mechanism in the above by which the NonTriv
temporary is destroyed.
Aside: I will open a GCC defect for its failure to process the side-effects of the argument initialization.
I can no longer reproduce this issue with Clang trunk. If you're still seeing the problem with Clang trunk, please reopen this bug with additional details on how to reproduce.
Extended Description
When a mem-initializer selects an inherited constructor from a virtual base and the object it constructs is not a complete object, Clang tries to pass more arguments than it should.
SOURCE (
<stdin>
):COMPILER INVOCATION:
EXPECTED OUTPUT:
(Clean compile)
ACTUAL OUTPUT:
COMPILER VERSION INFO (
clang++ -v
):