diff options
| author | ArielG-NV <159081215+ArielG-NV@users.noreply.github.com> | 2025-07-15 08:04:17 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-07-15 15:04:17 +0000 |
| commit | 73e9987c9fc86dd91c20267e9cd79efd2d33d1af (patch) | |
| tree | abb30bda486b65adf5a304f9ebbe85c0cd5a8a9a | |
| parent | d964555d2ee83fac2ba357e4ec81e2a393a7b12f (diff) | |
Fix `slang-generate` segfault when parsing `$(()...)` (#7683)
* Fix `slang-generate` segfault when parsing `(...)`
Currently the following code causes a failure:
* `myFunc($((int)val))`
* This fails since we parse it as `int)val` due to trying to find a body with repeating `(`.
The primary issue here is that auto-format prefers `$((...))` over `$( (...))`, making this an annoying bug.
* only read first char with `(`
* format code
---------
Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
| -rw-r--r-- | source/slang/core.meta.slang | 56 | ||||
| -rw-r--r-- | tools/slang-generate/main.cpp | 12 |
2 files changed, 37 insertions, 31 deletions
diff --git a/source/slang/core.meta.slang b/source/slang/core.meta.slang index 85cf3cf11..380f79a6a 100644 --- a/source/slang/core.meta.slang +++ b/source/slang/core.meta.slang @@ -89,7 +89,7 @@ syntax __extern_cpp : ExternCppModifier; __magic_type(DefaultInitializableType) interface IDefaultInitializable { - __builtin_requirement($( (int)BuiltinRequirementKind::DefaultInitializableConstructor)) + __builtin_requirement($((int)BuiltinRequirementKind::DefaultInitializableConstructor)) __init(); } @@ -99,15 +99,15 @@ interface IDefaultInitializable interface IComparable { /// Returns true if two values of the conforming type are equal. - __builtin_requirement($( (int)BuiltinRequirementKind::Equals)) + __builtin_requirement($((int)BuiltinRequirementKind::Equals)) bool equals(This other); /// Returns true if `this` is less than `other`. - __builtin_requirement($( (int)BuiltinRequirementKind::LessThan)) + __builtin_requirement($((int)BuiltinRequirementKind::LessThan)) bool lessThan(This other); /// Returns true if `this` is less than or equal to `other`. - __builtin_requirement($( (int)BuiltinRequirementKind::LessThanOrEquals)) + __builtin_requirement($((int)BuiltinRequirementKind::LessThanOrEquals)) bool lessThanOrEquals(This other); } @@ -169,42 +169,42 @@ interface IArithmetic : IComparable interface ILogical : IComparable { /// Shifts the bits of this value to the left by the specified number of positions. - __builtin_requirement($( (int)BuiltinRequirementKind::Shl) ) + __builtin_requirement($((int)BuiltinRequirementKind::Shl)) This shl(int value); /// Shifts the bits of this value to the right by the specified number of positions. - __builtin_requirement($( (int)BuiltinRequirementKind::Shr) ) + __builtin_requirement($((int)BuiltinRequirementKind::Shr)) This shr(int value); /// Performs a bitwise AND operation on this value with another value of the same type. - __builtin_requirement($( (int)BuiltinRequirementKind::BitAnd) ) + __builtin_requirement($((int)BuiltinRequirementKind::BitAnd)) This bitAnd(This other); /// Performs a bitwise OR operation on this value with another value of the same type. - __builtin_requirement($( (int)BuiltinRequirementKind::BitOr) ) + __builtin_requirement($((int)BuiltinRequirementKind::BitOr)) This bitOr(This other); /// Performs a bitwise XOR operation on this value with another value of the same type. - __builtin_requirement($( (int)BuiltinRequirementKind::BitXor) ) + __builtin_requirement($((int)BuiltinRequirementKind::BitXor)) This bitXor(This other); /// Performs a bitwise NOT operation on this value, flipping all bits. - __builtin_requirement($( (int)BuiltinRequirementKind::BitNot) ) + __builtin_requirement($((int)BuiltinRequirementKind::BitNot)) This bitNot(); /// Performs a logical AND operation on this value with another value of the same type. - __builtin_requirement($( (int)BuiltinRequirementKind::And) ) + __builtin_requirement($((int)BuiltinRequirementKind::And)) This and(This other); /// Performs a logical OR operation on this value with another value of the same type. - __builtin_requirement($( (int)BuiltinRequirementKind::Or) ) + __builtin_requirement($((int)BuiltinRequirementKind::Or)) This or(This other); /// Performs a logical NOT operation on this value, returning the logical negation. - __builtin_requirement($( (int)BuiltinRequirementKind::Not) ) + __builtin_requirement($((int)BuiltinRequirementKind::Not)) This not(); - __builtin_requirement($( (int)BuiltinRequirementKind::InitLogicalFromInt) ) + __builtin_requirement($((int)BuiltinRequirementKind::InitLogicalFromInt)) __init(int val); } @@ -609,19 +609,19 @@ interface IDifferentiable // Note: the compiler implementation requires the `Differential` associated type to be defined // before anything else. - __builtin_requirement($( (int)BuiltinRequirementKind::DifferentialType) ) + __builtin_requirement($((int)BuiltinRequirementKind::DifferentialType)) associatedtype Differential : IDifferentiable; /// Returns a zero-initialized value of the differential type. - __builtin_requirement($( (int)BuiltinRequirementKind::DZeroFunc) ) + __builtin_requirement($((int)BuiltinRequirementKind::DZeroFunc)) static Differential dzero(); /// Adds two differential values and returns the result. - __builtin_requirement($( (int)BuiltinRequirementKind::DAddFunc) ) + __builtin_requirement($((int)BuiltinRequirementKind::DAddFunc)) static Differential dadd(Differential, Differential); /// Multiplies a scalar value of a built-in real type with a differential value and returns the result. - __builtin_requirement($( (int)BuiltinRequirementKind::DMulFunc) ) + __builtin_requirement($((int)BuiltinRequirementKind::DMulFunc)) __generic<T : __BuiltinRealType> static Differential dmul(T, Differential); }; @@ -649,7 +649,7 @@ __magic_type(DifferentiablePtrType) [KnownBuiltin($( (int)KnownBuiltinDeclName::IDifferentiablePtr))] interface IDifferentiablePtrType { - __builtin_requirement($( (int)BuiltinRequirementKind::DifferentialPtrType) ) + __builtin_requirement($((int)BuiltinRequirementKind::DifferentialPtrType)) associatedtype Differential : IDifferentiablePtrType; }; @@ -831,7 +831,7 @@ interface __EnumType : ILogical // conflict if a user had an `enum` case called `Tag` associatedtype __Tag : __BuiltinIntegerType; - __builtin_requirement($( (int)BuiltinRequirementKind::InitLogicalFromInt) ) + __builtin_requirement($((int)BuiltinRequirementKind::InitLogicalFromInt)) __init(__Tag value); }; @@ -1256,7 +1256,7 @@ struct __none_t /// Represents a pointer type. /// @param T The type of the value pointed to. /// @remarks `T* val` is equivalent to `Ptr<T> val`. -__generic<T, let addrSpace : uint64_t = $( (uint64_t)AddressSpace::UserPointer)ULL> +__generic<T, let addrSpace : uint64_t = $((uint64_t)AddressSpace::UserPointer)ULL> __magic_type(PtrType) __intrinsic_type($(kIROp_PtrType)) struct Ptr @@ -1444,7 +1444,7 @@ __intrinsic_type($(kIROp_ConstRefType)) struct ConstRef {}; -typealias __Addr<T> = Ptr<T, $( (uint64_t)AddressSpace::Generic)ULL>; +typealias __Addr<T> = Ptr<T, $((uint64_t)AddressSpace::Generic)ULL>; //@public: @@ -2584,7 +2584,7 @@ __prefix Ref<T> operator*(Ptr<T, addrSpace> value); __generic<T> __intrinsic_op(0) [require(cpp_cuda_spirv)] -__prefix Ptr<T, $( (uint64_t)AddressSpace::UserPointer)ULL> operator&(__ref T value); +__prefix Ptr<T, $((uint64_t)AddressSpace::UserPointer)ULL> operator&(__ref T value); __generic<T> __intrinsic_op(0) @@ -4040,10 +4040,10 @@ attribute_syntax [__readNone] : ReadNoneAttribute; /// Represents the applicable target for an attribute. enum _AttributeTargets { - Struct = $( (int) UserDefinedAttributeTargets::Struct), /// Struct types. - Var = $( (int) UserDefinedAttributeTargets::Var), /// Global and local variables and constants. - Function = $( (int) UserDefinedAttributeTargets::Function), /// Functions or member functions. - Param = $( (int) UserDefinedAttributeTargets::Param), /// Function parameters. + Struct = $((int) UserDefinedAttributeTargets::Struct), /// Struct types. + Var = $((int) UserDefinedAttributeTargets::Var), /// Global and local variables and constants. + Function = $((int) UserDefinedAttributeTargets::Function), /// Functions or member functions. + Param = $((int) UserDefinedAttributeTargets::Param), /// Function parameters. }; /// Mark a struct type as a user defined attribute type. @@ -4275,7 +4275,7 @@ __attributeTarget(FuncDecl) attribute_syntax [RequireFullQuads] : RequireFullQuadsAttribute; __generic<T> -typealias NodePayloadPtr = Ptr<T, $( (uint64_t)AddressSpace::NodePayloadAMDX)>; +typealias NodePayloadPtr = Ptr<T, $((uint64_t)AddressSpace::NodePayloadAMDX)>; __attributeTarget(StructDecl) attribute_syntax [raypayload] : RayPayloadAttribute; diff --git a/tools/slang-generate/main.cpp b/tools/slang-generate/main.cpp index 3cb733471..9039e8c58 100644 --- a/tools/slang-generate/main.cpp +++ b/tools/slang-generate/main.cpp @@ -204,12 +204,18 @@ enum kNodeReadFlag_AllowEscape = 1 << 0, }; +template<bool onlyReadFirstOpenChar> Node* readBody(Reader& reader, NodeReadFlags flags, char openChar, int openCount, char closeChar) { while (peek(reader) == openChar) { get(reader); openCount++; + + // This case allows parsing `myFunc($((int)val))` correctly, else we parse + // body as `int)val`, causing non obvious segfault. + if constexpr (onlyReadFirstOpenChar) + break; } Node* nodes = nullptr; @@ -317,7 +323,7 @@ Node* readBody(Reader& reader, NodeReadFlags flags, char openChar, int openCount // addTextSpan(link, spanBegin, spanEnd); - Node* body = readBody(reader, 0, '(', 0, ')'); + Node* body = readBody<true>(reader, 0, '(', 0, ')'); addSpliceSpan(link, body); @@ -331,7 +337,7 @@ Node* readBody(Reader& reader, NodeReadFlags flags, char openChar, int openCount addTextSpan(link, spanBegin, lineBegin); - Node* body = readBody(reader, 0, '{', 0, '}'); + Node* body = readBody<false>(reader, 0, '{', 0, '}'); addEscapeSpan(link, body); @@ -419,7 +425,7 @@ Node* readInput(char const* inputBegin, char const* inputEnd) reader.cursor = inputBegin; reader.end = inputEnd; - return readBody(reader, kNodeReadFlag_AllowEscape, -2, 0, -2); + return readBody<false>(reader, kNodeReadFlag_AllowEscape, -2, 0, -2); } void emitRaw(FILE* stream, char const* begin, char const* end) |
