diff options
| -rw-r--r-- | source/slang/slang-check-decl.cpp | 25 | ||||
| -rw-r--r-- | source/slang/slang-diagnostic-defs.h | 7 | ||||
| -rw-r--r-- | tests/language-feature/constants/link-time-vardecl-must-be-static-const-or-neither.slang | 32 |
3 files changed, 63 insertions, 1 deletions
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<ExternModifier>(m) || as<HLSLExportModifier>(m)) + hasExportOrExtern = true; + else if (as<ConstModifier>(m)) + hasConst = true; + else if (as<HLSLStaticModifier>(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'") diff --git a/tests/language-feature/constants/link-time-vardecl-must-be-static-const-or-neither.slang b/tests/language-feature/constants/link-time-vardecl-must-be-static-const-or-neither.slang new file mode 100644 index 000000000..a1ae810e1 --- /dev/null +++ b/tests/language-feature/constants/link-time-vardecl-must-be-static-const-or-neither.slang @@ -0,0 +1,32 @@ +//TEST:SIMPLE(filecheck=CHECK_PASS): -target spirv -entry computeMain -stage compute -DUSE_EXTERN +//TEST:SIMPLE(filecheck=CHECK_PASS): -target spirv -entry computeMain -stage compute +//TEST:SIMPLE(filecheck=CHECK_PASS): -target spirv -entry computeMain -stage compute -DUSE_EXTERN -DUSE_CONST -DUSE_STATIC +//TEST:SIMPLE(filecheck=CHECK_PASS): -target spirv -entry computeMain -stage compute -DUSE_CONST -DUSE_STATIC +//CHECK_PASS-NOT: error 31223 + +//TEST:SIMPLE(filecheck=CHECK_FAIL): -target spirv -entry computeMain -stage compute -DUSE_EXTERN -DUSE_CONST +//TEST:SIMPLE(filecheck=CHECK_FAIL): -target spirv -entry computeMain -stage compute -DUSE_CONST +//TEST:SIMPLE(filecheck=CHECK_FAIL): -target spirv -entry computeMain -stage compute -DUSE_EXTERN -DUSE_STATIC +//TEST:SIMPLE(filecheck=CHECK_FAIL): -target spirv -entry computeMain -stage compute -DUSE_STATIC +//CHECK_FAIL: error 31223 + + +#ifdef USE_CONST +const +#endif +#ifdef USE_STATIC +static +#endif +#ifdef USE_EXTERN +extern int num; +#else +export int num = 10; +#endif + +RWStructuredBuffer<float> outputBuffer; + +[numthreads(1,1,1)] +void computeMain() +{ + outputBuffer[0] = num; +} |
