diff --git a/expr.cpp b/expr.cpp index 2fd3145f..1bcfa70d 100644 --- a/expr.cpp +++ b/expr.cpp @@ -639,6 +639,9 @@ lLLVMConstantValue(const Type *type, llvm::LLVMContext *ctx, double value) { static llvm::Value * lMaskForSymbol(Symbol *baseSym, FunctionEmitContext *ctx) { + if (baseSym == NULL) + return ctx->GetFullMask(); + if (dynamic_cast(baseSym->type) != NULL || dynamic_cast(baseSym->type) != NULL) // FIXME: for pointers, we really only want to do this for @@ -659,10 +662,11 @@ lMaskForSymbol(Symbol *baseSym, FunctionEmitContext *ctx) { static void lStoreAssignResult(llvm::Value *value, llvm::Value *ptr, const Type *ptrType, FunctionEmitContext *ctx, Symbol *baseSym) { - Assert(baseSym != NULL && + Assert(baseSym == NULL || baseSym->varyingCFDepth <= ctx->VaryingCFDepth()); if (!g->opt.disableMaskedStoreToStore && !g->opt.disableMaskAllOnOptimizations && + baseSym != NULL && baseSym->varyingCFDepth == ctx->VaryingCFDepth() && baseSym->storageClass != SC_STATIC && dynamic_cast(baseSym->type) == NULL && @@ -2017,14 +2021,13 @@ AssignExpr::GetValue(FunctionEmitContext *ctx) const { ctx->SetDebugPos(pos); Symbol *baseSym = lvalue->GetBaseSymbol(); - // Should be caught during type-checking... - assert(baseSym != NULL); switch (op) { case Assign: { llvm::Value *lv = lvalue->GetLValue(ctx); if (lv == NULL) { - Assert(m->errorCount > 0); + Error(lvalue->pos, "Left hand side of assignment expression can't " + "be assigned to."); return NULL; } const Type *lvalueType = lvalue->GetLValueType(); @@ -2147,13 +2150,13 @@ AssignExpr::TypeCheck() { } } - if (lvalue->GetBaseSymbol() == NULL) { - Error(lvalue->pos, "Left hand side of assignment statement can't be " - "assigned to."); + const Type *lhsType = lvalue->GetType(); + if (lhsType->IsConstType()) { + Error(lvalue->pos, "Can't assign to type \"%s\" on left-hand side of " + "expression.", lhsType->GetString().c_str()); return NULL; } - const Type *lhsType = lvalue->GetType(); if (dynamic_cast(lhsType) != NULL) { if (op == AddAssign || op == SubAssign) { if (PointerType::IsVoidPointer(lhsType)) { @@ -2187,12 +2190,6 @@ AssignExpr::TypeCheck() { if (rvalue == 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 const StructType *st = dynamic_cast(lhsType); if (st != NULL && lCheckForConstStructMember(pos, st, st)) diff --git a/tests/ptr-assign-lhs-math-1.ispc b/tests/ptr-assign-lhs-math-1.ispc new file mode 100644 index 00000000..2b34cbae --- /dev/null +++ b/tests/ptr-assign-lhs-math-1.ispc @@ -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; +} diff --git a/tests/ptr-assign-lhs-math-2.ispc b/tests/ptr-assign-lhs-math-2.ispc new file mode 100644 index 00000000..0e28cca2 --- /dev/null +++ b/tests/ptr-assign-lhs-math-2.ispc @@ -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; +} diff --git a/tests_errors/lvalue-1.ispc b/tests_errors/lvalue-1.ispc index ada9abf3..8140a2c8 100644 --- a/tests_errors/lvalue-1.ispc +++ b/tests_errors/lvalue-1.ispc @@ -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;} diff --git a/tests_errors/lvalue-2.ispc b/tests_errors/lvalue-2.ispc index ef067008..ae2e3edd 100644 --- a/tests_errors/lvalue-2.ispc +++ b/tests_errors/lvalue-2.ispc @@ -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(){ 4 = 0; diff --git a/tests_errors/lvalue-3.ispc b/tests_errors/lvalue-3.ispc index f4fb830d..eb856bf0 100644 --- a/tests_errors/lvalue-3.ispc +++ b/tests_errors/lvalue-3.ispc @@ -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 x;