From d84cfb766b089c03f9545588a8590efea1749770 Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Mon, 15 Jun 2020 12:05:04 -0700 Subject: Remove implicit conversions to `void` (#1388) * Remove implicit conversions to `void` Fixes #1372 The standard library code had accidentally introduced implicit-conversion `__init` operations on the `void` type that accepted each of the other basic types, so that a function written like: ```hlsl void bad() { return 1; } ``` would translate to: ```hlsl void bad() { return (void)1; } ``` The dual problesm are that the input code should have produced a diagnostic of some kind, and the output code doesn't appear to compile correctly through fxc. This change introduces several fixes aimed at this issue: * First, the problem in the stdlib code is plugged: we don't introduce implicit conversion operations *to* or *from* `void` (we'd only been banning it in one direction before) * Next, an explicit `__init` was added to `void` that accepts *any* type so that existing HLSL code that might do `(void) someExpression` to ignore a result will continue to work. This is a compatibility feature, and it might be argued that we should at least warn when it is used. Note that this function is expected to never appear in output HLSL/GLSL because its result will never be used, and it is marked `[__readNone]` allowing calls to it to be eliminated as dead code. * During IR lowering, we now take care to only emit the `IRReturnVal` instruction type if there is a non-`void` value being returned, and use `IRReturnVoid` for both the case where no expression was used in the `return` statement *and* the case where an expression of type `void` is returned. * A test case was added to confirm that returning `1` from a `void` function isn't allowed, while returning `(void) 1` *is*. The net result of these changes is that we now produce an error for the bad input code, we allow explicit casts to `void` as a compatibility feature, and we are more robust about treating `void` as if it is an ordinary type in the front-end. * fixup: missing file --- source/slang/core.meta.slang | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'source/slang/core.meta.slang') diff --git a/source/slang/core.meta.slang b/source/slang/core.meta.slang index 0c39f2c2f..b56ca3085 100644 --- a/source/slang/core.meta.slang +++ b/source/slang/core.meta.slang @@ -192,7 +192,9 @@ ${{{{ // Declare initializers to convert from various other types for (int ss = 0; ss < kBaseTypeCount; ++ss) { - // Don't allow conversion from `void` + // Don't allow conversion to or from `void` + if (kBaseTypes[tt].tag == BaseType::Void) + continue; if (kBaseTypes[ss].tag == BaseType::Void) continue; @@ -250,6 +252,21 @@ ${{{{ ${{{{ break; } + + // If this is the `void` type, then we want to allow + // explicit conversion to it from any other type, using + // `(void) someExpression`. + // + if( kBaseTypes[tt].tag == BaseType::Void ) + { +}}}} + __generic + [__readNone] + __init(T value) + {} +${{{{ + } + }}}} } -- cgit v1.2.3