Fix bug that prohibited assignments with pointer expressions on the LHS
Previously, code like "*(ptr+1) = foo" would claim that the LHS was invalid for an assignment expression. Issue #138.
This commit is contained in:
25
expr.cpp
25
expr.cpp
@@ -639,6 +639,9 @@ lLLVMConstantValue(const Type *type, llvm::LLVMContext *ctx, double value) {
|
|||||||
|
|
||||||
static llvm::Value *
|
static llvm::Value *
|
||||||
lMaskForSymbol(Symbol *baseSym, FunctionEmitContext *ctx) {
|
lMaskForSymbol(Symbol *baseSym, FunctionEmitContext *ctx) {
|
||||||
|
if (baseSym == NULL)
|
||||||
|
return ctx->GetFullMask();
|
||||||
|
|
||||||
if (dynamic_cast<const PointerType *>(baseSym->type) != NULL ||
|
if (dynamic_cast<const PointerType *>(baseSym->type) != NULL ||
|
||||||
dynamic_cast<const ReferenceType *>(baseSym->type) != NULL)
|
dynamic_cast<const ReferenceType *>(baseSym->type) != NULL)
|
||||||
// FIXME: for pointers, we really only want to do this for
|
// FIXME: for pointers, we really only want to do this for
|
||||||
@@ -659,10 +662,11 @@ lMaskForSymbol(Symbol *baseSym, FunctionEmitContext *ctx) {
|
|||||||
static void
|
static void
|
||||||
lStoreAssignResult(llvm::Value *value, llvm::Value *ptr, const Type *ptrType,
|
lStoreAssignResult(llvm::Value *value, llvm::Value *ptr, const Type *ptrType,
|
||||||
FunctionEmitContext *ctx, Symbol *baseSym) {
|
FunctionEmitContext *ctx, Symbol *baseSym) {
|
||||||
Assert(baseSym != NULL &&
|
Assert(baseSym == NULL ||
|
||||||
baseSym->varyingCFDepth <= ctx->VaryingCFDepth());
|
baseSym->varyingCFDepth <= ctx->VaryingCFDepth());
|
||||||
if (!g->opt.disableMaskedStoreToStore &&
|
if (!g->opt.disableMaskedStoreToStore &&
|
||||||
!g->opt.disableMaskAllOnOptimizations &&
|
!g->opt.disableMaskAllOnOptimizations &&
|
||||||
|
baseSym != NULL &&
|
||||||
baseSym->varyingCFDepth == ctx->VaryingCFDepth() &&
|
baseSym->varyingCFDepth == ctx->VaryingCFDepth() &&
|
||||||
baseSym->storageClass != SC_STATIC &&
|
baseSym->storageClass != SC_STATIC &&
|
||||||
dynamic_cast<const ReferenceType *>(baseSym->type) == NULL &&
|
dynamic_cast<const ReferenceType *>(baseSym->type) == NULL &&
|
||||||
@@ -2017,14 +2021,13 @@ AssignExpr::GetValue(FunctionEmitContext *ctx) const {
|
|||||||
ctx->SetDebugPos(pos);
|
ctx->SetDebugPos(pos);
|
||||||
|
|
||||||
Symbol *baseSym = lvalue->GetBaseSymbol();
|
Symbol *baseSym = lvalue->GetBaseSymbol();
|
||||||
// Should be caught during type-checking...
|
|
||||||
assert(baseSym != NULL);
|
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case Assign: {
|
case Assign: {
|
||||||
llvm::Value *lv = lvalue->GetLValue(ctx);
|
llvm::Value *lv = lvalue->GetLValue(ctx);
|
||||||
if (lv == NULL) {
|
if (lv == NULL) {
|
||||||
Assert(m->errorCount > 0);
|
Error(lvalue->pos, "Left hand side of assignment expression can't "
|
||||||
|
"be assigned to.");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
const Type *lvalueType = lvalue->GetLValueType();
|
const Type *lvalueType = lvalue->GetLValueType();
|
||||||
@@ -2147,13 +2150,13 @@ AssignExpr::TypeCheck() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lvalue->GetBaseSymbol() == NULL) {
|
const Type *lhsType = lvalue->GetType();
|
||||||
Error(lvalue->pos, "Left hand side of assignment statement can't be "
|
if (lhsType->IsConstType()) {
|
||||||
"assigned to.");
|
Error(lvalue->pos, "Can't assign to type \"%s\" on left-hand side of "
|
||||||
|
"expression.", lhsType->GetString().c_str());
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Type *lhsType = lvalue->GetType();
|
|
||||||
if (dynamic_cast<const PointerType *>(lhsType) != NULL) {
|
if (dynamic_cast<const PointerType *>(lhsType) != NULL) {
|
||||||
if (op == AddAssign || op == SubAssign) {
|
if (op == AddAssign || op == SubAssign) {
|
||||||
if (PointerType::IsVoidPointer(lhsType)) {
|
if (PointerType::IsVoidPointer(lhsType)) {
|
||||||
@@ -2187,12 +2190,6 @@ AssignExpr::TypeCheck() {
|
|||||||
if (rvalue == NULL)
|
if (rvalue == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (lhsType->IsConstType()) {
|
|
||||||
Error(pos, "Can't assign to type \"%s\" on left-hand side of "
|
|
||||||
"expression.", lhsType->GetString().c_str());
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure we're not assigning to a struct that has a constant member
|
// Make sure we're not assigning to a struct that has a constant member
|
||||||
const StructType *st = dynamic_cast<const StructType *>(lhsType);
|
const StructType *st = dynamic_cast<const StructType *>(lhsType);
|
||||||
if (st != NULL && lCheckForConstStructMember(pos, st, st))
|
if (st != NULL && lCheckForConstStructMember(pos, st, st))
|
||||||
|
|||||||
16
tests/ptr-assign-lhs-math-1.ispc
Normal file
16
tests/ptr-assign-lhs-math-1.ispc
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
export uniform int width() { return programCount; }
|
||||||
|
|
||||||
|
export void f_f(uniform float RET[], uniform float aFOO[]) {
|
||||||
|
uniform float a[programCount];
|
||||||
|
a[programIndex] = aFOO[programIndex];
|
||||||
|
|
||||||
|
uniform float * uniform ptr = a;
|
||||||
|
*(ptr+1) = 0;
|
||||||
|
RET[programIndex] = a[programIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
export void result(uniform float RET[]) {
|
||||||
|
RET[programIndex] = 1+programIndex;
|
||||||
|
RET[1] = 0;
|
||||||
|
}
|
||||||
15
tests/ptr-assign-lhs-math-2.ispc
Normal file
15
tests/ptr-assign-lhs-math-2.ispc
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
export uniform int width() { return programCount; }
|
||||||
|
|
||||||
|
export void f_f(uniform float RET[], uniform float aFOO[]) {
|
||||||
|
uniform float a[programCount];
|
||||||
|
a[programIndex] = aFOO[programIndex];
|
||||||
|
|
||||||
|
uniform float * varying ptr = a;
|
||||||
|
*(ptr+programIndex) = 0;
|
||||||
|
RET[programIndex] = a[programIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
export void result(uniform float RET[]) {
|
||||||
|
RET[programIndex] = 0;
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
// Left hand side of assignment statement can't be assigned to
|
// Left hand side of assignment expression can't be assigned to
|
||||||
|
|
||||||
int foo() {return 2;}
|
int foo() {return 2;}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Left hand side of assignment statement can't be assigned to
|
// Can't assign to type "const uniform int32" on left-hand side of expression
|
||||||
|
|
||||||
int bar(){
|
int bar(){
|
||||||
4 = 0;
|
4 = 0;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Left hand side of assignment statement can't be assigned to
|
// Can't assign to type "const uniform int32" on left-hand side of expression
|
||||||
|
|
||||||
int bar(){
|
int bar(){
|
||||||
int x;
|
int x;
|
||||||
|
|||||||
Reference in New Issue
Block a user