Skip to content

Commit 5099dc3

Browse files
authored
[Clang][CodeGen] Fix use of CXXThisValue with StrictVTablePointers (#68169)
1 parent 0738953 commit 5099dc3

File tree

2 files changed

+5
-13
lines changed

2 files changed

+5
-13
lines changed

clang/lib/CodeGen/CGClass.cpp

+3-4
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "clang/CodeGen/CGFunctionInfo.h"
2929
#include "llvm/IR/Intrinsics.h"
3030
#include "llvm/IR/Metadata.h"
31+
#include "llvm/Support/SaveAndRestore.h"
3132
#include "llvm/Transforms/Utils/SanitizerStats.h"
3233
#include <optional>
3334

@@ -1291,10 +1292,10 @@ void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD,
12911292
assert(BaseCtorContinueBB);
12921293
}
12931294

1294-
llvm::Value *const OldThis = CXXThisValue;
12951295
for (; B != E && (*B)->isBaseInitializer() && (*B)->isBaseVirtual(); B++) {
12961296
if (!ConstructVBases)
12971297
continue;
1298+
SaveAndRestore ThisRAII(CXXThisValue);
12981299
if (CGM.getCodeGenOpts().StrictVTablePointers &&
12991300
CGM.getCodeGenOpts().OptimizationLevel > 0 &&
13001301
isInitializerOfDynamicClass(*B))
@@ -1311,16 +1312,14 @@ void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD,
13111312
// Then, non-virtual base initializers.
13121313
for (; B != E && (*B)->isBaseInitializer(); B++) {
13131314
assert(!(*B)->isBaseVirtual());
1314-
1315+
SaveAndRestore ThisRAII(CXXThisValue);
13151316
if (CGM.getCodeGenOpts().StrictVTablePointers &&
13161317
CGM.getCodeGenOpts().OptimizationLevel > 0 &&
13171318
isInitializerOfDynamicClass(*B))
13181319
CXXThisValue = Builder.CreateLaunderInvariantGroup(LoadCXXThis());
13191320
EmitBaseInitializer(*this, ClassDecl, *B);
13201321
}
13211322

1322-
CXXThisValue = OldThis;
1323-
13241323
InitializeVTablePointers(ClassDecl);
13251324

13261325
// And finally, initialize class members.
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
// RUN: %clang_cc1 %s -I%S -triple=x86_64-pc-windows-msvc -fstrict-vtable-pointers -disable-llvm-passes -disable-llvm-verifier -O1 -emit-llvm -o %t.ll
1+
// RUN: %clang_cc1 %s -I%S -triple=x86_64-pc-windows-msvc -fstrict-vtable-pointers -disable-llvm-passes -O1 -emit-llvm -o %t.ll
22
// RUN: FileCheck %s < %t.ll
3-
// RUN: not llvm-as < %t.ll -o /dev/null 2>&1 | FileCheck %s --check-prefix=CHECK-VERIFIER
43

54
struct A {
65
virtual ~A();
@@ -9,11 +8,6 @@ struct B : virtual A {};
98
class C : B {};
109
C foo;
1110

12-
// FIXME: This is not supposed to generate invalid IR!
13-
// CHECK-VERIFIER: Instruction does not dominate all uses!
14-
// CHECK-VERIFIER-NEXT: %1 = call ptr @llvm.launder.invariant.group.p0(ptr %this1)
15-
// CHECK-VERIFIER-NEXT: %3 = call ptr @llvm.launder.invariant.group.p0(ptr %1)
16-
1711
// CHECK-LABEL: define {{.*}} @"??0C@@QEAA@XZ"(ptr {{.*}} %this, i32 {{.*}} %is_most_derived)
1812
// CHECK: ctor.init_vbases:
1913
// CHECK-NEXT: %0 = getelementptr inbounds i8, ptr %this1, i64 0
@@ -24,6 +18,5 @@ C foo;
2418
// CHECK-NEXT: br label %ctor.skip_vbases
2519
// CHECK-EMPTY:
2620
// CHECK-NEXT: ctor.skip_vbases:
27-
// FIXME: Should be using '%this1' instead of %1 below.
28-
// CHECK-NEXT: %3 = call ptr @llvm.launder.invariant.group.p0(ptr %1)
21+
// CHECK-NEXT: %3 = call ptr @llvm.launder.invariant.group.p0(ptr %this1)
2922
// CHECK-NEXT: %call3 = call noundef ptr @"??0B@@QEAA@XZ"(ptr {{.*}} %3, i32 noundef 0) #2

0 commit comments

Comments
 (0)