Skip to content

Commit 0fcca41

Browse files
authored
[CIR] Allow user-defined casts in emitPointerWithAlignment (#193078)
In CIR, we use a fully-covered switch for casts in emitPointerWithAlignment and only allow casts that are known to be safe to fall through without handling. Classic codegen uses a default and all casts that don't already have special handling fall through. This change moves CK_UserDefinedConversion to the group that we allow to fall through and changes the unanalyzed group to emit an NYI diagnostic rather than calling llvm_unreachable.
1 parent a6f9a0d commit 0fcca41

2 files changed

Lines changed: 28 additions & 2 deletions

File tree

clang/lib/CIR/CodeGen/CIRGenExpr.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ Address CIRGenFunction::emitPointerWithAlignment(const Expr *expr,
203203
case CK_NullToMemberPointer:
204204
case CK_NullToPointer:
205205
case CK_ReinterpretMemberPointer:
206+
case CK_UserDefinedConversion:
206207
// Common pointer conversions, nothing to do here.
207208
// TODO: Is there any reason to treat base-to-derived conversions
208209
// specially?
@@ -254,10 +255,16 @@ Address CIRGenFunction::emitPointerWithAlignment(const Expr *expr,
254255
case CK_PointerToIntegral:
255256
case CK_ToUnion:
256257
case CK_ToVoid:
257-
case CK_UserDefinedConversion:
258258
case CK_VectorSplat:
259259
case CK_ZeroToOCLOpaqueType:
260-
llvm_unreachable("unexpected cast for emitPointerWithAlignment");
260+
// Classic codegen has a default that does nothing. In CIR, we are issuing
261+
// a diagnostic so we can examine casts that are reached here to be sure
262+
// no action is needed. If nothing is needed, the cast can be moved to the
263+
// group above that does nothing.
264+
cgm.errorNYI(ce->getSourceRange(),
265+
"unexpected cast for emitPointerWithAlignment: ",
266+
ce->getCastKindName());
267+
break;
261268
}
262269
}
263270

clang/test/CIR/CodeGen/cast.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,3 +164,22 @@ void null_cast(long) {
164164
// CIR: cir.store{{.*}} %{{.*}}, %[[NULLPTR]] : !s32i, !cir.ptr<!s32i>
165165
// CIR: %[[NULLPTR_A:.*]] = cir.const #cir.ptr<null> : !cir.ptr<!rec_A>
166166
// CIR: %[[A_X:.*]] = cir.get_member %[[NULLPTR_A]][0] {name = "x"} : !cir.ptr<!rec_A> -> !cir.ptr<!s32i>
167+
168+
struct B {
169+
int *p;
170+
operator int *() const { return p; }
171+
};
172+
173+
int test_unser_defined_cast_with_aligned_load(B x) {
174+
return *x;
175+
}
176+
177+
// CIR: cir.func{{.*}} @_Z41test_unser_defined_cast_with_aligned_load1B
178+
// CIR: cir.store %{{.*}}, %[[B_PTR:.*]] : !rec_B, !cir.ptr<!rec_B>
179+
// CIR: %[[CAST:.*]] = cir.call @_ZNK1BcvPiEv(%[[B_PTR]])
180+
// CIR: %[[LOAD:.*]] = cir.load{{.*}} %[[CAST]]
181+
182+
// LLVM: define{{.*}} i32 @_Z41test_unser_defined_cast_with_aligned_load1B
183+
// LLVM: store %struct.B %{{.*}}, ptr %[[B_PTR:.*]], align 8
184+
// LLVM: %[[CAST:.*]] = call {{.*}} ptr @_ZNK1BcvPiEv(ptr {{.*}} %[[B_PTR]])
185+
// LLVM: %[[LOAD:.*]] = load i32, ptr %[[CAST]]

0 commit comments

Comments
 (0)