Convert arrays to pointers in expressions like (a+5)
This was one instance of the C-style array/pointer duality that was missed the first time around.
This commit is contained in:
55
expr.cpp
55
expr.cpp
@@ -135,6 +135,21 @@ lMaybeIssuePrecisionWarning(const AtomicType *toAtomicType,
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static Expr *
|
||||
lArrayToPointer(Expr *expr) {
|
||||
assert(expr && dynamic_cast<const ArrayType *>(expr->GetType()));
|
||||
|
||||
Expr *zero = new ConstExpr(AtomicType::UniformInt32, 0, expr->pos);
|
||||
Expr *index = new IndexExpr(expr, zero, expr->pos);
|
||||
Expr *addr = new AddressOfExpr(index, expr->pos);
|
||||
addr = addr->TypeCheck();
|
||||
assert(addr != NULL);
|
||||
addr = addr->Optimize();
|
||||
assert(addr != NULL);
|
||||
return addr;
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
lIsAllIntZeros(Expr *expr) {
|
||||
const Type *type = expr->GetType();
|
||||
@@ -1652,6 +1667,16 @@ BinaryExpr::TypeCheck() {
|
||||
assert(type1 != NULL);
|
||||
}
|
||||
|
||||
// Convert arrays to pointers to their first elements
|
||||
if (dynamic_cast<const ArrayType *>(type0) != NULL) {
|
||||
arg0 = lArrayToPointer(arg0);
|
||||
type0 = arg0->GetType();
|
||||
}
|
||||
if (dynamic_cast<const ArrayType *>(type1) != NULL) {
|
||||
arg1 = lArrayToPointer(arg1);
|
||||
type1 = arg1->GetType();
|
||||
}
|
||||
|
||||
const PointerType *pt0 = dynamic_cast<const PointerType *>(type0);
|
||||
const PointerType *pt1 = dynamic_cast<const PointerType *>(type1);
|
||||
if (pt0 != NULL && pt1 != NULL && op == Sub) {
|
||||
@@ -5241,24 +5266,18 @@ TypeCastExpr::GetValue(FunctionEmitContext *ctx) const {
|
||||
|
||||
if (fromArrayType != NULL && toPointerType != NULL) {
|
||||
// implicit array to pointer to first element
|
||||
Expr *zero = new ConstExpr(AtomicType::UniformInt32, 0, pos);
|
||||
Expr *index = new IndexExpr(expr, zero, pos);
|
||||
Expr *addr = new AddressOfExpr(index, pos);
|
||||
addr = addr->TypeCheck();
|
||||
assert(addr != NULL);
|
||||
addr = addr->Optimize();
|
||||
assert(addr != NULL);
|
||||
if (Type::EqualIgnoringConst(addr->GetType(), toPointerType) == false) {
|
||||
assert(Type::EqualIgnoringConst(addr->GetType()->GetAsVaryingType(),
|
||||
Expr *arrayAsPtr = lArrayToPointer(expr);
|
||||
if (Type::EqualIgnoringConst(arrayAsPtr->GetType(), toPointerType) == false) {
|
||||
assert(Type::EqualIgnoringConst(arrayAsPtr->GetType()->GetAsVaryingType(),
|
||||
toPointerType) == true);
|
||||
addr = new TypeCastExpr(toPointerType, addr, false, pos);
|
||||
addr = addr->TypeCheck();
|
||||
assert(addr != NULL);
|
||||
addr = addr->Optimize();
|
||||
assert(addr != NULL);
|
||||
arrayAsPtr = new TypeCastExpr(toPointerType, arrayAsPtr, false, pos);
|
||||
arrayAsPtr = arrayAsPtr->TypeCheck();
|
||||
assert(arrayAsPtr != NULL);
|
||||
arrayAsPtr = arrayAsPtr->Optimize();
|
||||
assert(arrayAsPtr != NULL);
|
||||
}
|
||||
assert(Type::EqualIgnoringConst(addr->GetType(), toPointerType));
|
||||
return addr->GetValue(ctx);
|
||||
assert(Type::EqualIgnoringConst(arrayAsPtr->GetType(), toPointerType));
|
||||
return arrayAsPtr->GetValue(ctx);
|
||||
}
|
||||
|
||||
// This also should be caught during typechecking
|
||||
@@ -5738,8 +5757,8 @@ DereferenceExpr::GetValue(FunctionEmitContext *ctx) const {
|
||||
return NULL;
|
||||
|
||||
Symbol *baseSym = expr->GetBaseSymbol();
|
||||
assert(baseSym != NULL);
|
||||
llvm::Value *mask = lMaskForSymbol(baseSym, ctx);
|
||||
llvm::Value *mask = baseSym ? lMaskForSymbol(baseSym, ctx) :
|
||||
ctx->GetFullMask();
|
||||
|
||||
ctx->SetDebugPos(pos);
|
||||
return ctx->LoadInst(ptr, mask, type, "deref_load");
|
||||
|
||||
Reference in New Issue
Block a user