From cdfea42f1b28c6ec7b13500a64be823f67bf8e0a Mon Sep 17 00:00:00 2001 From: Ellie Hermaszewska Date: Fri, 7 Jul 2023 03:52:00 +0800 Subject: Fix erroneous error claiming variable is being used before its declaration (#2958) * Simplify type of diagnoseImpl * Show source line for Note diagnostics, opting out of this where appropriate * Make declared after use diagnostic clearer * Fix erroneous error claiming variable is being used before its declaration Closes https://github.com/shader-slang/slang/issues/2936 * Fix build on msvc --------- Co-authored-by: jsmall-nvidia --- source/compiler-core/slang-diagnostic-sink.cpp | 12 +++----- source/compiler-core/slang-diagnostic-sink.h | 42 +++++++++++--------------- 2 files changed, 22 insertions(+), 32 deletions(-) (limited to 'source/compiler-core') diff --git a/source/compiler-core/slang-diagnostic-sink.cpp b/source/compiler-core/slang-diagnostic-sink.cpp index f360d3cc6..197e9bb64 100644 --- a/source/compiler-core/slang-diagnostic-sink.cpp +++ b/source/compiler-core/slang-diagnostic-sink.cpp @@ -75,7 +75,7 @@ SourceLoc getDiagnosticPos(Token const& token) } // Take the format string for a diagnostic message, along with its arguments, and turn it into a -static void formatDiagnosticMessage(StringBuilder& sb, char const* format, int argCount, DiagnosticArg const* const* args) +static void formatDiagnosticMessage(StringBuilder& sb, char const* format, int argCount, DiagnosticArg const* args) { char const* spanBegin = format; for(;;) @@ -116,8 +116,8 @@ static void formatDiagnosticMessage(StringBuilder& sb, char const* format, int a } else { - DiagnosticArg const* arg = args[index]; - arg->printFunc(sb, arg->data); + DiagnosticArg const& arg = args[index]; + arg.printFunc(sb, arg.data); } } break; @@ -459,9 +459,7 @@ static void formatDiagnostic( _tokenLengthNoteDiagnostic(sink, sourceView, sourceLoc, sb); } - // We don't don't output source line information if this is a 'note' as a note is extra information for one - // of the other main severity types, and so the information should already be output on the initial line - if (sourceView && sink->isFlagSet(DiagnosticSink::Flag::SourceLocationLine) && diagnostic.severity != Severity::Note) + if (sourceView && sink->isFlagSet(DiagnosticSink::Flag::SourceLocationLine) && diagnostic.loc.isValid()) { _sourceLocationNoteDiagnostic(sink, sourceView, sourceLoc, sb); } @@ -600,7 +598,7 @@ Severity DiagnosticSink::getEffectiveMessageSeverity(DiagnosticInfo const& info) return effectiveSeverity; } -void DiagnosticSink::diagnoseImpl(SourceLoc const& pos, DiagnosticInfo info, int argCount, DiagnosticArg const* const* args) +void DiagnosticSink::diagnoseImpl(SourceLoc const& pos, DiagnosticInfo info, int argCount, DiagnosticArg const* args) { // Override the severity in the 'info' structure to pass it further into formatDiagnostics info.severity = getEffectiveMessageSeverity(info); diff --git a/source/compiler-core/slang-diagnostic-sink.h b/source/compiler-core/slang-diagnostic-sink.h index ebd43b456..c150de900 100644 --- a/source/compiler-core/slang-diagnostic-sink.h +++ b/source/compiler-core/slang-diagnostic-sink.h @@ -162,39 +162,31 @@ public: /// Get the total amount of errors that have taken place on this DiagnosticSink SLANG_FORCE_INLINE int getErrorCount() { return m_errorCount; } - void diagnoseDispatch(SourceLoc const& pos, DiagnosticInfo const& info) - { - diagnoseImpl(pos, info, 0, nullptr); - } - - void diagnoseDispatch(SourceLoc const& pos, DiagnosticInfo const& info, DiagnosticArg const& arg0) + template + void diagnose(P const& pos, DiagnosticInfo const& info, Args const&... args ) { - DiagnosticArg const* args[] = { &arg0 }; - diagnoseImpl(pos, info, 1, args); + DiagnosticArg as[] = { DiagnosticArg(args)... }; + diagnoseImpl(getDiagnosticPos(pos), info, sizeof...(args), as); } - void diagnoseDispatch(SourceLoc const& pos, DiagnosticInfo const& info, DiagnosticArg const& arg0, DiagnosticArg const& arg1) + template + void diagnose(P const& pos, DiagnosticInfo const& info) { - DiagnosticArg const* args[] = { &arg0, &arg1 }; - diagnoseImpl(pos, info, 2, args); + // MSVC gets upset with the zero sized array above, so overload that case here + diagnoseImpl(getDiagnosticPos(pos), info, 0, nullptr); } - void diagnoseDispatch(SourceLoc const& pos, DiagnosticInfo const& info, DiagnosticArg const& arg0, DiagnosticArg const& arg1, DiagnosticArg const& arg2) + // Useful for notes on existing diagnostics, where it would be redundant to display the same line again. + // (Ideally we would print the error/warning and notes in one call...) + template + void diagnoseWithoutSourceView(P const& pos, DiagnosticInfo const& info, Args const&... args ) { - DiagnosticArg const* args[] = { &arg0, &arg1, &arg2 }; - diagnoseImpl(pos, info, 3, args); - } + const auto fs = this->getFlags(); + this->resetFlag(Flag::SourceLocationLine); - void diagnoseDispatch(SourceLoc const& pos, DiagnosticInfo const& info, DiagnosticArg const& arg0, DiagnosticArg const& arg1, DiagnosticArg const& arg2, DiagnosticArg const& arg3) - { - DiagnosticArg const* args[] = { &arg0, &arg1, &arg2, &arg3 }; - diagnoseImpl(pos, info, 4, args); - } + diagnose(pos, info, args...); - template - void diagnose(P const& pos, DiagnosticInfo const& info, Args const&... args ) - { - diagnoseDispatch(getDiagnosticPos(pos), info, args...); + this->setFlags(fs); } // Add a diagnostic with raw text @@ -267,7 +259,7 @@ public: ISlangWriter* writer = nullptr; protected: - void diagnoseImpl(SourceLoc const& pos, DiagnosticInfo info, int argCount, DiagnosticArg const* const* args); + void diagnoseImpl(SourceLoc const& pos, DiagnosticInfo info, int argCount, DiagnosticArg const* args); void diagnoseImpl(DiagnosticInfo const& info, const UnownedStringSlice& formattedMessage); Severity getEffectiveMessageSeverity(DiagnosticInfo const& info); -- cgit v1.2.3