@@ -233,7 +233,7 @@ bool isAcceptedSpecConstantBinaryOp(spv::Op op) {
233233
234234/// Returns true if the given expression is an accepted initializer for a spec
235235/// constant.
236- bool isAcceptedSpecConstantInit(const Expr *init) {
236+ bool isAcceptedSpecConstantInit(const Expr *init, ASTContext &astContext ) {
237237 // Allow numeric casts
238238 init = init->IgnoreParenCasts();
239239
@@ -244,7 +244,12 @@ bool isAcceptedSpecConstantInit(const Expr *init) {
244244 // Allow the minus operator which is used to specify negative values
245245 if (const auto *unaryOp = dyn_cast<UnaryOperator>(init))
246246 return unaryOp->getOpcode() == UO_Minus &&
247- isAcceptedSpecConstantInit(unaryOp->getSubExpr());
247+ isAcceptedSpecConstantInit(unaryOp->getSubExpr(), astContext);
248+
249+ // Allow values that can be evaluated to const.
250+ if (init->isEvaluatable(astContext)) {
251+ return true;
252+ }
248253
249254 return false;
250255}
@@ -7847,7 +7852,7 @@ void SpirvEmitter::createSpecConstant(const VarDecl *varDecl) {
78477852 emitError("missing default value for specialization constant",
78487853 varDecl->getLocation());
78497854 hasError = true;
7850- } else if (!isAcceptedSpecConstantInit(init)) {
7855+ } else if (!isAcceptedSpecConstantInit(init, astContext )) {
78517856 emitError("unsupported specialization constant initializer",
78527857 init->getLocStart())
78537858 << init->getSourceRange();
@@ -7859,7 +7864,8 @@ void SpirvEmitter::createSpecConstant(const VarDecl *varDecl) {
78597864
78607865 SpecConstantEnvRAII specConstantEnvRAII(&isSpecConstantMode);
78617866
7862- const auto specConstant = doExpr(init);
7867+ const auto specConstant =
7868+ constEvaluator.tryToEvaluateAsConst(init, isSpecConstantMode);
78637869
78647870 // We are not creating a variable to hold the spec constant, instead, we
78657871 // translate the varDecl directly into the spec constant here.
0 commit comments