Skip to content

Commit a929550

Browse files
committed
[clang][bytecode] Not all null pointers are 0
Get the Value from the ASTContext insteaed.
1 parent 61c2ac0 commit a929550

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: {
@@ -3814,7 +3816,7 @@ template <class Emitter> bool Compiler<Emitter>::visitBool(const Expr *E) {
38143816

38153817
// Convert pointers to bool.
38163818
if (T == PT_Ptr || T == PT_FnPtr) {
3817-
if (!this->emitNull(*T, nullptr, E))
3819+
if (!this->emitNull(*T, 0, nullptr, E))
38183820
return false;
38193821
return this->emitNE(*T, E);
38203822
}
@@ -3854,11 +3856,12 @@ bool Compiler<Emitter>::visitZeroInitializer(PrimType T, QualType QT,
38543856
case PT_IntAPS:
38553857
return this->emitZeroIntAPS(Ctx.getBitWidth(QT), E);
38563858
case PT_Ptr:
3857-
return this->emitNullPtr(nullptr, E);
3859+
return this->emitNullPtr(Ctx.getASTContext().getTargetNullPointerValue(QT),
3860+
nullptr, E);
38583861
case PT_FnPtr:
3859-
return this->emitNullFnPtr(nullptr, E);
3862+
return this->emitNullFnPtr(0, nullptr, E);
38603863
case PT_MemberPtr:
3861-
return this->emitNullMemberPtr(nullptr, E);
3864+
return this->emitNullMemberPtr(0, nullptr, E);
38623865
case PT_Float:
38633866
return this->emitConstFloat(APFloat::getZero(Ctx.getFloatSemantics(QT)), E);
38643867
case PT_FixedPoint: {
@@ -4418,7 +4421,7 @@ bool Compiler<Emitter>::visitAPValue(const APValue &Val, PrimType ValType,
44184421

44194422
if (Val.isLValue()) {
44204423
if (Val.isNullPointer())
4421-
return this->emitNull(ValType, nullptr, E);
4424+
return this->emitNull(ValType, 0, nullptr, E);
44224425
APValue::LValueBase Base = Val.getLValueBase();
44234426
if (const Expr *BaseExpr = Base.dyn_cast<const Expr *>())
44244427
return this->visit(BaseExpr);
@@ -4428,7 +4431,7 @@ bool Compiler<Emitter>::visitAPValue(const APValue &Val, PrimType ValType,
44284431
} else if (Val.isMemberPointer()) {
44294432
if (const ValueDecl *MemberDecl = Val.getMemberPointerDecl())
44304433
return this->emitGetMemberPtr(MemberDecl, E);
4431-
return this->emitNullMemberPtr(nullptr, E);
4434+
return this->emitNullMemberPtr(0, nullptr, E);
44324435
}
44334436

44344437
return false;
@@ -4780,7 +4783,8 @@ bool Compiler<Emitter>::VisitCXXNullPtrLiteralExpr(
47804783
if (DiscardResult)
47814784
return true;
47824785

4783-
return this->emitNullPtr(nullptr, E);
4786+
uint64_t Val = Ctx.getASTContext().getTargetNullPointerValue(E->getType());
4787+
return this->emitNullPtr(Val, nullptr, E);
47844788
}
47854789

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

53365340
// Forward all arguments from the static invoker to the lambda call operator.
@@ -6477,7 +6481,7 @@ bool Compiler<Emitter>::emitBuiltinBitCast(const CastExpr *E) {
64776481
if (!this->discard(SubExpr))
64786482
return false;
64796483

6480-
return this->emitNullPtr(nullptr, E);
6484+
return this->emitNullPtr(0, nullptr, E);
64816485
}
64826486

64836487
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)