From 45b76418f9da2248b069f2058c6a1d52b05a8c74 Mon Sep 17 00:00:00 2001 From: ArielG-NV <159081215+ArielG-NV@users.noreply.github.com> Date: Wed, 14 Aug 2024 13:05:57 -0400 Subject: Do not zero-initialize groupshared and rayquery variables (#4838) * Do not zero-initialize groupshared and rayquery variables Fixes: #4824 `-zero-initialize` option will explicitly not: 1. Set any groupshared values to defaults 2. Set any rayQuery object to a default state (currently invalid code generation) * grammer * disallow groupshared initializers disallow groupshared initializers & adjust tests accordingly * remove disallowed groupshared-init expression * do not default init if non-copyable --------- Co-authored-by: Yong He --- source/slang/slang-check-decl.cpp | 52 ++++++++++++++++++++++++++++++++++++ source/slang/slang-diagnostic-defs.h | 2 ++ 2 files changed, 54 insertions(+) (limited to 'source') diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp index 7211565dd..2e5e13360 100644 --- a/source/slang/slang-check-decl.cpp +++ b/source/slang/slang-check-decl.cpp @@ -1922,10 +1922,59 @@ namespace Slang checkVisibility(classDecl); } + bool DiagnoseIsAllowedInitExpr(VarDeclBase* varDecl, DiagnosticSink* sink) + { + // find groupshared modifier + if (varDecl->findModifier()) + { + if (sink && varDecl->initExpr) + sink->diagnose(varDecl, Diagnostics::cannotHaveInitializer, varDecl, "groupshared"); + return false; + } + + return true; + } + + bool isDefaultInitializable(VarDeclBase* varDecl) + { + if (!DiagnoseIsAllowedInitExpr(varDecl, nullptr)) + return false; + + // Find struct and modifiers associated with varDecl + StructDecl* structDecl = as(varDecl); + if (auto declRefType = as(varDecl->getType())) + { + if (auto genericAppRefDecl = as(declRefType->getDeclRefBase())) + { + auto baseGenericRefType = genericAppRefDecl->getBase()->getDecl(); + if (auto baseTypeStruct = as(baseGenericRefType)) + { + structDecl = baseTypeStruct; + } + else if (auto genericDecl = as(baseGenericRefType)) + { + if(auto innerTypeStruct = as(genericDecl->inner)) + structDecl = innerTypeStruct; + } + } + } + if (structDecl) + { + // find if a type is non-copyable + if (structDecl->findModifier()) + return false; + } + + return true; + } + static Expr* constructDefaultInitExprForVar(SemanticsVisitor* visitor, VarDeclBase* varDecl) { if (!varDecl->type || !varDecl->type.type) return nullptr; + + if (!isDefaultInitializable(varDecl)) + return nullptr; ConstructorDecl* defaultCtor = nullptr; auto declRefType = as(varDecl->type.type); @@ -1951,8 +2000,11 @@ namespace Slang return defaultCall; } } + void SemanticsDeclBodyVisitor::checkVarDeclCommon(VarDeclBase* varDecl) { + DiagnoseIsAllowedInitExpr(varDecl, getSink()); + // if zero initialize is true, set everything to a default if (getOptionSet().hasOption(CompilerOptionName::ZeroInitialize) && !varDecl->initExpr diff --git a/source/slang/slang-diagnostic-defs.h b/source/slang/slang-diagnostic-defs.h index 44e8aa13d..03e8efbc0 100644 --- a/source/slang/slang-diagnostic-defs.h +++ b/source/slang/slang-diagnostic-defs.h @@ -520,6 +520,8 @@ DIAGNOSTIC(30504, Error, cannotUseInitializerListForType, "cannot use initialize // 3062x: variables DIAGNOSTIC(30620, Error, varWithoutTypeMustHaveInitializer, "a variable declaration without an initial-value expression must be given an explicit type") DIAGNOSTIC(30622, Error, ambiguousDefaultInitializerForType, "more than one default initializer was found for type '$0'") +DIAGNOSTIC(30623, Error, cannotHaveInitializer, "'$0' cannot have an initializer because it is $1") + // 307xx: parameters DIAGNOSTIC(30700, Error, outputParameterCannotHaveDefaultValue, "an 'out' or 'inout' parameter cannot have a default-value expression") -- cgit v1.2.3