From 8c68434d6fa6ff1b2e54586637869cceace9d1bb Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Fri, 25 Aug 2017 15:18:10 -0700 Subject: Fix some resources-in-structs bugs Fixes #171 Fixes #172 These two bugs related to bad logic in handling of splitting resource-containing `cbuffer` declarations. - Issue #171 was the case where a `cbuffer` *only* had resource fields, in which case we crashed whenever referencing any field (some code was assuming there had to be non-resource fields) - Issue #172 was a case where two fields were declared with a single declaration (`Texture2D a, b;`), and the logic we had for tracking resource-type fields was accidentally tagging *both* fields with a single modifier so that field `b` would get confused for `a` in some contexts, and attempts to access `b` would crash. Both issues are now fixed, and regression tests have been added. --- source/slang/parser.cpp | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'source/slang/parser.cpp') diff --git a/source/slang/parser.cpp b/source/slang/parser.cpp index 7ea3fe864..c3969be42 100644 --- a/source/slang/parser.cpp +++ b/source/slang/parser.cpp @@ -549,9 +549,30 @@ namespace Slang { RefPtr*& modifierLink = *ioModifierLink; - while(*modifierLink) + // We'd like to add the modifier to the end of the list, + // but we need to be careful, in case there is a "shared" + // section of modifiers for multiple declarations. + // + // TODO: This whole approach is a mess because we are "accidentally quadratic" + // when adding many modifiers. + for(;;) + { + // At end of the chain? Done. + if(!*modifierLink) + break; + + // About to look at shared modifiers? Done. + RefPtr linkMod = *modifierLink; + if(linkMod.As()) + break; + + // Otherwise: keep traversing the modifier list. modifierLink = &(*modifierLink)->next; + } + + // Splice the modifier into the linked list + modifier->next = *modifierLink; *modifierLink = modifier; modifierLink = &modifier->next; } -- cgit v1.2.3 From e62f90597277fba421042c6fd6e7d1be59b7da83 Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Fri, 25 Aug 2017 18:55:49 -0700 Subject: Fixup: handle splice of multiple modifiers I changed the logic so that it might splice a new modifier into the existing linked list (not just at the end), but failed to account for the case where what we are splicing in isn't just a single modifier, but a whole *list* (which occurs when splicing in the shared modifiers themselves). This change handles that case with a bit of annoying linked-list cleverness. --- source/slang/parser.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'source/slang/parser.cpp') diff --git a/source/slang/parser.cpp b/source/slang/parser.cpp index c3969be42..e232880e9 100644 --- a/source/slang/parser.cpp +++ b/source/slang/parser.cpp @@ -572,7 +572,17 @@ namespace Slang // Splice the modifier into the linked list - modifier->next = *modifierLink; + // We need to deal with the case where the modifeir to + // be spliced in might actually be a modifier *list*, + // so that we actually want to splice in at the + // end of the new list... + auto spliceLink = &modifier->next; + while(*spliceLink) + spliceLink = &(*spliceLink)->next; + + // Do the splice. + *spliceLink = *modifierLink; + *modifierLink = modifier; modifierLink = &modifier->next; } -- cgit v1.2.3