diff --git a/CHANGES.md b/CHANGES.md index 1f5817824..4c35ec270 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -37,6 +37,10 @@ OSL Language and oslc compiler: * A shader input parameter marked with metadata `[[ int allowconnect = 0 ]]` will disallow runtime connections via `ConnectShaders()`, resulting in an error. #857 (1.10.0) +* oslc command-line argument `-Werror` will treat all warnings as hard + errors (failed compilation). (1.10.0) +* `#pragma nowarn` will suppress any warnings arising from code on the + immediately following line of that source file. (1.10.0) OSL Standard library: diff --git a/CMakeLists.txt b/CMakeLists.txt index 5555b42df..e1c6402c2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -283,6 +283,7 @@ TESTSUITE ( aastep allowconnect-err and-or-not-synonyms arithmetic oslinfo-metadata oslinfo-noparams osl-imageio paramval-floatpromotion + pragma-nowarn printf-whole-array raytype raytype-specialized reparam render-background render-bumptest diff --git a/src/liboslcomp/oslcomp_pvt.h b/src/liboslcomp/oslcomp_pvt.h index 0b3e73105..acff5a4b7 100644 --- a/src/liboslcomp/oslcomp_pvt.h +++ b/src/liboslcomp/oslcomp_pvt.h @@ -100,7 +100,7 @@ class OSLCompilerImpl { /// Error reporting template - void error (string_view filename, int line, + void error (ustring filename, int line, string_view format, const Args&... args) const { ASSERT (format.size()); @@ -116,10 +116,12 @@ class OSLCompilerImpl { /// Warning reporting template - void warning (string_view filename, int line, + void warning (ustring filename, int line, string_view format, const Args&... args) const { ASSERT (format.size()); + if (nowarn(filename, line)) + return; // skip if the filename/line is on the nowarn list std::string msg = OIIO::Strutil::format (format, args...); if (msg.size() && msg.back() == '\n') // trim extra newline msg.pop_back(); @@ -135,7 +137,7 @@ class OSLCompilerImpl { /// Info reporting template - void info (string_view filename, int line, + void info (ustring filename, int line, string_view format, const Args&... args) const { ASSERT (format.size()); @@ -150,7 +152,7 @@ class OSLCompilerImpl { /// message reporting template - void message (string_view filename, int line, + void message (ustring filename, int line, string_view format, const Args&... args) const { ASSERT (format.size()); @@ -379,6 +381,16 @@ class OSLCompilerImpl { m_func_decls.emplace_back (f); } + // Add a pragma nowarn for the following line + void pragma_nowarn () { + m_nowarn_lines.insert ({filename(), lineno()+1}); + } + + // Is the line amont + bool nowarn (ustring filename, int line) const { + return m_nowarn_lines.find({filename, line}) != m_nowarn_lines.end(); + } + private: void initialize_globals (); void initialize_builtin_funcs (); @@ -477,6 +489,7 @@ class OSLCompilerImpl { Symbol *m_derivsym; ///< Pseudo-symbol to track deriv dependencies int m_main_method_start; ///< Instruction where 'main' starts bool m_declaring_shader_formals; ///< Are we declaring shader formals? + std::set> m_nowarn_lines; ///< Lines for 'nowarn' }; diff --git a/src/liboslcomp/osllex.l b/src/liboslcomp/osllex.l index 5f4ab1eaf..df93dfaad 100644 --- a/src/liboslcomp/osllex.l +++ b/src/liboslcomp/osllex.l @@ -306,8 +306,18 @@ preprocess (const char *yytext) p++; if (! strncmp (p, "pragma", 6)) { // pragma - oslcompiler->error (oslcompiler->filename(), oslcompiler->lineno(), - "Unknown pragma '%s'", p); + OIIO::string_view line (p+6); + string_view pragmatype = OIIO::Strutil::parse_word (line); + if (OIIO::Strutil::iequals (pragmatype, "osl")) { + string_view pragmaname = OIIO::Strutil::parse_word (line); + if (pragmaname == "nowarn") { + oslcompiler->pragma_nowarn (); + } else { + oslcompiler->warning (oslcompiler->filename(), oslcompiler->lineno(), + "Unknown pragma '%s'", pragmaname); + } + } + // N.B. Pragmas that don't start with "osl" are ignored oslcompiler->incr_lineno(); // the pragma ends with an EOLN } else { /* probably the line number and filename */ if (! strncmp (p, "line", 4)) diff --git a/testsuite/pragma-nowarn/ref/out.txt b/testsuite/pragma-nowarn/ref/out.txt new file mode 100644 index 000000000..fbc6d98a9 --- /dev/null +++ b/testsuite/pragma-nowarn/ref/out.txt @@ -0,0 +1,2 @@ +Compiled test.osl -> test.oso + diff --git a/testsuite/pragma-nowarn/run.py b/testsuite/pragma-nowarn/run.py new file mode 100755 index 000000000..cf6a7c29a --- /dev/null +++ b/testsuite/pragma-nowarn/run.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python + +# This shader would ordinarily issue a warning. +# With -Werror, it should be upgraded to an error. +oslcargs = "-Werror" + +# BUT... the shader carefully uses #pragma nowarn to disable the warning. +# Which should cause the test to pass. + +command = testshade("test") + diff --git a/testsuite/pragma-nowarn/test.osl b/testsuite/pragma-nowarn/test.osl new file mode 100644 index 000000000..f80811306 --- /dev/null +++ b/testsuite/pragma-nowarn/test.osl @@ -0,0 +1,10 @@ +// Engineer an ambiguous case that should be a warning + +normal func () { return 1; } +vector func () { return 2; } + +shader test () +{ + #pragma osl nowarn + point p = func(); +}