From 0651ffb6489282f0f902ec5f630821a7b9d848bb Mon Sep 17 00:00:00 2001 From: ArielG-NV <159081215+ArielG-NV@users.noreply.github.com> Date: Fri, 16 May 2025 10:44:44 -0700 Subject: Enforce rule that `export`/`extern` (non cpp) must be `const` (#7113) * Enforce rule that `export`/`extern` (non cpp) must be `const` fixes: #5570 Problem: 1. we allow non-const-link-time-var to be linked to a const-link-time-var. 2. problem is that: module use site has const var, so, we emit OpStore %Ptr %Const in IR, this is expected, this is good. We fail because we in reality have a OpStore %Ptr %Var (fails since we need a OpLoad in-between) in IR since the module with our link-time-variable-value is a regular variable. 3. We loose the float_litteral talked about inside the github issue since, we technically don't use our variable "VAL" (we never OpLoad from it), so spirv-opt removes the float_litteral, this is a byproduct of the actual issue. Solution: * `export`/`extern` variables must always be `const`. This excludes `__extern_cpp` since `cpp` does not exhibit this issue and works differently. * format code * changel logic and tests to only ensure `static const` with `export`/`extern` * changing the rules: only reqirement is that if we have const we must have static * remove a spirrious change made * fix merge --------- Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com> Co-authored-by: Yong He --- source/slang/slang-check-decl.cpp | 25 +++++++++++++++++++++++++ source/slang/slang-diagnostic-defs.h | 7 ++++++- 2 files changed, 31 insertions(+), 1 deletion(-) (limited to 'source/slang') diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp index 79482ea6e..daa761d3d 100644 --- a/source/slang/slang-check-decl.cpp +++ b/source/slang/slang-check-decl.cpp @@ -42,6 +42,31 @@ struct SemanticsDeclModifiersVisitor : public SemanticsDeclVisitorBase, void visitDeclGroup(DeclGroup*) {} + void visitVarDecl(VarDecl* decl) + { + visitDecl(decl); + + // Export'd/Extern'd variables must be `const`, otherwise we may have a mismatch + // causing errors. + bool hasConst = false; + bool hasExportOrExtern = false; + bool hasStatic = false; + for (auto m : decl->modifiers) + { + if (as(m) || as(m)) + hasExportOrExtern = true; + else if (as(m)) + hasConst = true; + else if (as(m)) + hasStatic = true; + } + if (hasExportOrExtern && hasConst != hasStatic) + getSink()->diagnose( + decl, + Diagnostics::ExternAndExportVarDeclMustBeConst, + decl->getName()); + } + void visitDecl(Decl* decl) { checkModifiers(decl); } void visitStructDecl(StructDecl* structDecl); diff --git a/source/slang/slang-diagnostic-defs.h b/source/slang/slang-diagnostic-defs.h index 6bedcfe3e..cafd61062 100644 --- a/source/slang/slang-diagnostic-defs.h +++ b/source/slang/slang-diagnostic-defs.h @@ -1366,13 +1366,18 @@ DIAGNOSTIC( Error, variableCannotBePushAndSpecializationConstant, "'$0' cannot be a push constant and a specialization constant at the same time") - DIAGNOSTIC(31221, Error, invalidHLSLRegisterName, "invalid HLSL register name '$0'.") DIAGNOSTIC( 31222, Error, invalidHLSLRegisterNameForType, "invalid HLSL register name '$0' for type '$1'.") +DIAGNOSTIC( + 31223, + Error, + ExternAndExportVarDeclMustBeConst, + "extern and export variables must be static const: '$0'") + // Enums DIAGNOSTIC(32000, Error, invalidEnumTagType, "invalid tag type for 'enum': '$0'") -- cgit v1.2.3