Skip to content

Commit

Permalink
Fix.
Browse files Browse the repository at this point in the history
  • Loading branch information
csyonghe committed Feb 5, 2025
1 parent c9d74ac commit d8c2eb8
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 7 deletions.
4 changes: 4 additions & 0 deletions source/slang/slang-ast-support-types.h
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,10 @@ enum class DeclCheckState : uint8_t
///
Unchecked,

/// The declaration is parsed and inserted into the initial scope,
/// ready for future lookups from within the parser for disambiguation purposes.
ReadyForParserLookup,

/// Basic checks on the modifiers of the declaration have been applied.
///
/// For example, when a declaration has attributes, the transformation
Expand Down
3 changes: 3 additions & 0 deletions source/slang/slang-check-decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10975,6 +10975,9 @@ static void _dispatchDeclCheckingVisitor(Decl* decl, DeclCheckState state, Seman
{
switch (state)
{
case DeclCheckState::ReadyForParserLookup:
// We don't need to do anything to make a decl ready for parser lookup.
break;
case DeclCheckState::ModifiersChecked:
SemanticsDeclModifiersVisitor(shared).dispatch(decl);
break;
Expand Down
29 changes: 29 additions & 0 deletions source/slang/slang-check-stmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,35 @@ void SemanticsStmtVisitor::visitBlockStmt(BlockStmt* stmt)
{
if (as<AggTypeDeclBase>(decl))
ensureAllDeclsRec(decl, DeclCheckState::DefinitionChecked);

// Consider this code:
// ```
// {
// int a = 5 + b; // should error.
// int b = 3;
// }
//
// ```
// In order to detect the error trying to use `b` before it's declared within
// a block, our lookup logic contains a condition that ignores a decl if it hasn't
// been checked yet.
// See _lookUpDirectAndTransparentMembers(), for a call to _isDeclUnchecked().
// There, we will ignore unchecked decls during lookup, and as we encounter
// DeclStmts, we will then mark the corresponding decl as Checked, which will make
// the decl discoverable again by lookup logic.
//
// However, during parsing we actually don't need this behavior, since they will
// prevent any decls from being discovered by lookup, since none of the decls will
// be in a checked state during parsing. To allow decls to be discoverable by lookup
// during parsing, we have set all decl check states to ReadyForParserLookup after it
// is parsed.
// We now reset this state to Unchecked before we start checking the block,
// so we can continue to use this lookup logic to report this kind of errors.
//
if (auto varDecl = as<VarDeclBase>(decl))
{
varDecl->checkState = DeclCheckState::Unchecked;
}
}
}
checkStmt(stmt->body);
Expand Down
13 changes: 9 additions & 4 deletions source/slang/slang-parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4862,10 +4862,15 @@ static void CompleteDecl(

if (parser->semanticsVisitor && parser->getStage() == ParsingStage::Body)
{
parser->semanticsVisitor->ensureDecl(
(Decl*)decl,
DeclCheckState::DefinitionChecked,
parser->semanticsVisitor);
// When we are in a deferred parsing stage for function bodies,
// we will mark all local var decls as `ReadyForParserLookup` so they can
// be returned via lookup.
// Note that our lookup logic will ignore all unchecked decls, but during
// parsing we don't want to ignore them, so we mark them as `ReadyForParserLookup`
// here, which is a pseudo state that is only used during parsing.
// Before checking the decl in semantic checking, we will mark them back as
// `Unchecked`.
decl->checkState = DeclCheckState::ReadyForParserLookup;
}
}

Expand Down
6 changes: 3 additions & 3 deletions tests/bugs/gh-4150.slang
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@ void main(uint3 pixel_i : SV_DispatchThreadID)
output[0] =
#ifdef ERROR1
// expect error: trying to specialize RWTex, which has two arguments, with only one argument.
// CHECK1:([[# @LINE+1]]): error 30075
// CHECK1-DAG:([[# @LINE+1]]): error 30075
RWTex<float3>::get(p.image_id);
#else
RWTex<float, 3>::get(p.image_id);
#endif
//CHECK1:([[# @LINE+1]]): error 30071
//CHECK1-DAG:([[# @LINE+1]]): error 30071
static float sa1[];

//CHECK1:([[# @LINE+1]]): error 30071
//CHECK1-DAG:([[# @LINE+1]]): error 30071
float sa2[];

//CHECK1-NOT:([[# @LINE+1]]): error
Expand Down

0 comments on commit d8c2eb8

Please sign in to comment.