diff --git a/expr.cpp b/expr.cpp index cbef1622..a804d733 100644 --- a/expr.cpp +++ b/expr.cpp @@ -3662,7 +3662,19 @@ ExprList::GetConstant(const Type *type) const { if (exprs[i] == NULL) return NULL; const Type *elementType = collectionType->GetElementType(i); - llvm::Constant *c = exprs[i]->GetConstant(elementType); + + Expr *expr = exprs[i]; + if (dynamic_cast(expr) == NULL) { + // If there's a simple type conversion from the type of this + // expression to the type we need, then let the regular type + // conversion machinery handle it. + expr = TypeConvertExpr(exprs[i], elementType, "initializer list"); + Assert(expr != NULL); + // Re-establish const-ness if possible + expr = ::Optimize(expr); + } + + llvm::Constant *c = expr->GetConstant(elementType); if (c == NULL) // If this list element couldn't convert to the right constant // type for the corresponding collection member, then give up. @@ -7503,8 +7515,12 @@ FunctionSymbolExpr::GetConstant(const Type *type) const { if (ft == NULL) return NULL; - if (Type::Equal(type, matchingFunc->type) == false) + if (Type::Equal(type, matchingFunc->type) == false) { + Error(pos, "Type of function symbol \"%s\" doesn't match expected type " + "\"%s\".", matchingFunc->type->GetString().c_str(), + type->GetString().c_str()); return NULL; + } return matchingFunc->function; } diff --git a/tests/func-ptr-initializer.ispc b/tests/func-ptr-initializer.ispc new file mode 100644 index 00000000..96537391 --- /dev/null +++ b/tests/func-ptr-initializer.ispc @@ -0,0 +1,28 @@ + +export uniform int width() { return programCount; } + + +typedef float (*func)(); + +float foo(); +float bar(); + +struct X { func f, g; }; + +static uniform X x = { foo, &bar }; + +export void f_f(uniform float RET[], uniform float aFOO[]) { + RET[programIndex] = x.f() + x.g(); +} + +export void result(uniform float RET[]) { + RET[programIndex] = programIndex; +} + +float foo() { + return 2 * programIndex; +} + +float bar() { + return -programIndex; +}