Skip to content

Commit 44be794

Browse files
authored
[clang][bytecode] Not all null pointers are 0 (#118601)
Get the Value from the ASTContext instead.
1 parent 0993335 commit 44be794

File tree

4 files changed

+32
-14
lines changed

4 files changed

+32
-14
lines changed

clang/lib/AST/ByteCode/Compiler.cpp

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,9 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
355355
std::nullopt, true, false,
356356
/*IsMutable=*/false, nullptr);
357357
}
358-
return this->emitNull(classifyPrim(CE->getType()), Desc, CE);
358+
359+
uint64_t Val = Ctx.getASTContext().getTargetNullPointerValue(CE->getType());
360+
return this->emitNull(classifyPrim(CE->getType()), Val, Desc, CE);
359361
}
360362

361363
case CK_PointerToIntegral: {
@@ -3817,7 +3819,7 @@ template <class Emitter> bool Compiler<Emitter>::visitBool(const Expr *E) {
38173819

38183820
// Convert pointers to bool.
38193821
if (T == PT_Ptr || T == PT_FnPtr) {
3820-
if (!this->emitNull(*T, nullptr, E))
3822+
if (!this->emitNull(*T, 0, nullptr, E))
38213823
return false;
38223824
return this->emitNE(*T, E);
38233825
}
@@ -3857,11 +3859,12 @@ bool Compiler<Emitter>::visitZeroInitializer(PrimType T, QualType QT,
38573859
case PT_IntAPS:
38583860
return this->emitZeroIntAPS(Ctx.getBitWidth(QT), E);
38593861
case PT_Ptr:
3860-
return this->emitNullPtr(nullptr, E);
3862+
return this->emitNullPtr(Ctx.getASTContext().getTargetNullPointerValue(QT),
3863+
nullptr, E);
38613864
case PT_FnPtr:
3862-
return this->emitNullFnPtr(nullptr, E);
3865+
return this->emitNullFnPtr(0, nullptr, E);
38633866
case PT_MemberPtr:
3864-
return this->emitNullMemberPtr(nullptr, E);
3867+
return this->emitNullMemberPtr(0, nullptr, E);
38653868
case PT_Float:
38663869
return this->emitConstFloat(APFloat::getZero(Ctx.getFloatSemantics(QT)), E);
38673870
case PT_FixedPoint: {
@@ -4421,7 +4424,7 @@ bool Compiler<Emitter>::visitAPValue(const APValue &Val, PrimType ValType,
44214424

44224425
if (Val.isLValue()) {
44234426
if (Val.isNullPointer())
4424-
return this->emitNull(ValType, nullptr, E);
4427+
return this->emitNull(ValType, 0, nullptr, E);
44254428
APValue::LValueBase Base = Val.getLValueBase();
44264429
if (const Expr *BaseExpr = Base.dyn_cast<const Expr *>())
44274430
return this->visit(BaseExpr);
@@ -4431,7 +4434,7 @@ bool Compiler<Emitter>::visitAPValue(const APValue &Val, PrimType ValType,
44314434
} else if (Val.isMemberPointer()) {
44324435
if (const ValueDecl *MemberDecl = Val.getMemberPointerDecl())
44334436
return this->emitGetMemberPtr(MemberDecl, E);
4434-
return this->emitNullMemberPtr(nullptr, E);
4437+
return this->emitNullMemberPtr(0, nullptr, E);
44354438
}
44364439

44374440
return false;
@@ -4783,7 +4786,8 @@ bool Compiler<Emitter>::VisitCXXNullPtrLiteralExpr(
47834786
if (DiscardResult)
47844787
return true;
47854788

4786-
return this->emitNullPtr(nullptr, E);
4789+
uint64_t Val = Ctx.getASTContext().getTargetNullPointerValue(E->getType());
4790+
return this->emitNullPtr(Val, nullptr, E);
47874791
}
47884792

47894793
template <class Emitter>
@@ -5333,7 +5337,7 @@ bool Compiler<Emitter>::emitLambdaStaticInvokerBody(const CXXMethodDecl *MD) {
53335337
// one here, and we don't need one either because the lambda cannot have
53345338
// any captures, as verified above. Emit a null pointer. This is then
53355339
// special-cased when interpreting to not emit any misleading diagnostics.
5336-
if (!this->emitNullPtr(nullptr, MD))
5340+
if (!this->emitNullPtr(0, nullptr, MD))
53375341
return false;
53385342

53395343
// Forward all arguments from the static invoker to the lambda call operator.
@@ -6483,7 +6487,7 @@ bool Compiler<Emitter>::emitBuiltinBitCast(const CastExpr *E) {
64836487
if (!this->discard(SubExpr))
64846488
return false;
64856489

6486-
return this->emitNullPtr(nullptr, E);
6490+
return this->emitNullPtr(0, nullptr, E);
64876491
}
64886492

64896493
if (FromType->isNullPtrType() && ToT) {

clang/lib/AST/ByteCode/Interp.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2432,9 +2432,11 @@ static inline bool ZeroIntAPS(InterpState &S, CodePtr OpPC, uint32_t BitWidth) {
24322432
}
24332433

24342434
template <PrimType Name, class T = typename PrimConv<Name>::T>
2435-
inline bool Null(InterpState &S, CodePtr OpPC, const Descriptor *Desc) {
2436-
// Note: Desc can be null.
2437-
S.Stk.push<T>(0, Desc);
2435+
inline bool Null(InterpState &S, CodePtr OpPC, uint64_t Value,
2436+
const Descriptor *Desc) {
2437+
// FIXME(perf): This is a somewhat often-used function and the value of a
2438+
// null pointer is almost always 0.
2439+
S.Stk.push<T>(Value, Desc);
24382440
return true;
24392441
}
24402442

clang/lib/AST/ByteCode/Opcodes.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ def ZeroIntAPS : Opcode {
281281
// [] -> [Pointer]
282282
def Null : Opcode {
283283
let Types = [PtrTypeClass];
284-
let Args = [ArgDesc];
284+
let Args = [ArgUint64, ArgDesc];
285285
let HasGroup = 1;
286286
}
287287

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// RUN: %clang_cc1 -no-enable-noundef-analysis %s -cl-std=CL2.0 -triple amdgcn -emit-llvm -o - | FileCheck %s
2+
3+
// RUN: %clang_cc1 -no-enable-noundef-analysis %s -cl-std=CL2.0 -triple amdgcn -emit-llvm -fexperimental-new-constant-interpreter -o - | FileCheck %s
4+
5+
6+
// CHECK: @fold_priv ={{.*}} local_unnamed_addr addrspace(1) global ptr addrspace(5) addrspacecast (ptr addrspace(1) null to ptr addrspace(5)), align 4
7+
private short *fold_priv = (private short*)(generic int*)(global void*)0;
8+
9+
// CHECK: @fold_priv_arith ={{.*}} local_unnamed_addr addrspace(1) global ptr addrspace(5) inttoptr (i32 9 to ptr addrspace(5)), align 4
10+
private char *fold_priv_arith = (private char*)0 + 10;
11+
12+

0 commit comments

Comments
 (0)