[PATCH] D62571: Implement codegen for MSVC unions with reference members
Dominic Ferreira via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Mon Aug 26 18:25:17 PDT 2019
domdom updated this revision to Diff 217289.
domdom added a comment.
Rebased onto master, clang format the patch.
Merge conflict resolve by having the bitcast of the field reference happening after recording access index.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D62571/new/
https://reviews.llvm.org/D62571
Files:
clang/lib/CodeGen/CGExpr.cpp
clang/test/CodeGenCXX/ms-union-member-ref.cpp
Index: clang/test/CodeGenCXX/ms-union-member-ref.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGenCXX/ms-union-member-ref.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -fms-extensions %s -emit-llvm -o- | FileCheck %s
+
+union A {
+ int *&ref;
+ int **ptr;
+};
+
+int *f1(A *a) {
+ return a->ref;
+}
+// CHECK-LABEL: define {{.*}}i32* @_Z2f1P1A(%union.A* %a)
+// CHECK: [[REF:%[^[:space:]]+]] = bitcast %union.A* %{{.*}} to i32***
+// CHECK: [[IPP:%[^[:space:]]+]] = load i32**, i32*** [[REF]]
+// CHECK: [[IP:%[^[:space:]]+]] = load i32*, i32** [[IPP]]
+// CHECK: ret i32* [[IP]]
+
+void f2(A *a) {
+ *a->ref = 1;
+}
+// CHECK-LABEL: define {{.*}}void @_Z2f2P1A(%union.A* %a)
+// CHECK: [[REF:%[^[:space:]]+]] = bitcast %union.A* %{{.*}} to i32***
+// CHECK: [[IPP:%[^[:space:]]+]] = load i32**, i32*** [[REF]]
+// CHECK: [[IP:%[^[:space:]]+]] = load i32*, i32** [[IPP]]
+// CHECK: store i32 1, i32* [[IP]]
+
+bool f3(A *a, int *b) {
+ return a->ref != b;
+}
+// CHECK-LABEL: define {{.*}}i1 @_Z2f3P1APi(%union.A* %a, i32* %b)
+// CHECK: [[REF:%[^[:space:]]+]] = bitcast %union.A* %{{.*}} to i32***
+// CHECK: [[IPP:%[^[:space:]]+]] = load i32**, i32*** [[REF]]
+// CHECK: [[IP:%[^[:space:]]+]] = load i32*, i32** [[IPP]]
+// CHECK: [[IP2:%[^[:space:]]+]] = load i32*, i32** %b.addr
+// CHECK: icmp ne i32* [[IP]], [[IP2]]
Index: clang/lib/CodeGen/CGExpr.cpp
===================================================================
--- clang/lib/CodeGen/CGExpr.cpp
+++ clang/lib/CodeGen/CGExpr.cpp
@@ -4057,7 +4057,6 @@
unsigned RecordCVR = base.getVRQualifiers();
if (rec->isUnion()) {
// For unions, there is no pointer adjustment.
- assert(!FieldType->isReferenceType() && "union has reference member");
if (CGM.getCodeGenOpts().StrictVTablePointers &&
hasAnyVptr(FieldType, getContext()))
// Because unions can easily skip invariant.barriers, we need to add
@@ -4074,27 +4073,30 @@
addr.getPointer(), getDebugInfoFIndex(rec, field->getFieldIndex()), DbgInfo),
addr.getAlignment());
}
- } else {
+ if (FieldType->isReferenceType())
+ addr = Builder.CreateElementBitCast(
+ addr, CGM.getTypes().ConvertTypeForMem(FieldType), field->getName());
+ } else {
if (!IsInPreservedAIRegion)
// For structs, we GEP to the field that the record layout suggests.
addr = emitAddrOfFieldStorage(*this, addr, field);
else
// Remember the original struct field index
addr = emitPreserveStructAccess(*this, addr, field);
+ }
- // If this is a reference field, load the reference right now.
- if (FieldType->isReferenceType()) {
- LValue RefLVal = MakeAddrLValue(addr, FieldType, FieldBaseInfo,
- FieldTBAAInfo);
- if (RecordCVR & Qualifiers::Volatile)
- RefLVal.getQuals().addVolatile();
- addr = EmitLoadOfReference(RefLVal, &FieldBaseInfo, &FieldTBAAInfo);
-
- // Qualifiers on the struct don't apply to the referencee.
- RecordCVR = 0;
- FieldType = FieldType->getPointeeType();
- }
+ // If this is a reference field, load the reference right now.
+ if (FieldType->isReferenceType()) {
+ LValue RefLVal =
+ MakeAddrLValue(addr, FieldType, FieldBaseInfo, FieldTBAAInfo);
+ if (RecordCVR & Qualifiers::Volatile)
+ RefLVal.getQuals().addVolatile();
+ addr = EmitLoadOfReference(RefLVal, &FieldBaseInfo, &FieldTBAAInfo);
+
+ // Qualifiers on the struct don't apply to the referencee.
+ RecordCVR = 0;
+ FieldType = FieldType->getPointeeType();
}
// Make sure that the address is pointing to the right type. This is critical
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D62571.217289.patch
Type: text/x-patch
Size: 3797 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20190827/f171c19b/attachment.bin>
More information about the cfe-commits
mailing list