From fc7676769251a27cbbc6d40d68f04bfe38511a5b Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 22 Sep 2022 11:39:44 +0200 Subject: Long live Q_UNREACHABLE_RETURN()! This is a combination of Q_UNREACHABLE() with a return statement. ATM, the return statement is unconditionally included. If we notice that some compilers warn about return after __builtin_unreachable(), then we can map Q_UNREACHABLE_RETURN(...) to Q_UNREACHABLE() without having to touch all the code that uses explicit Q_UNREACHABLE() + return. The fact that Boost has BOOST_UNREACHABLE_RETURN() indicates that there are compilers that complain about a lack of return after Q_UNREACHABLE (we know that MSVC, ICC, and GHS are among them), as well as compilers that complained about a return being present (Coverity). Take this opportunity to properly adapt to Coverity, by leaving out the return statement on this compiler. Apply the macro around the code base, using a clang-tidy transformer rule: const std::string unr = "unr", val = "val", ret = "ret"; auto makeUnreachableReturn = cat("Q_UNREACHABLE_RETURN(", ifBound(val, cat(node(val)), cat("")), ")"); auto ignoringSwitchCases = [](auto stmt) { return anyOf(stmt, switchCase(subStmt(stmt))); }; makeRule( stmt(ignoringSwitchCases(stmt(isExpandedFromMacro("Q_UNREACHABLE")).bind(unr)), nextStmt(returnStmt(optionally(hasReturnValue(expr().bind(val)))).bind(ret))), {changeTo(node(unr), cat(makeUnreachableReturn, ";")), // TODO: why is the ; lost w/o this? changeTo(node(ret), cat(""))}, cat("use ", makeUnreachableReturn)) ); where nextStmt() is copied from some upstream clang-tidy check's private implementation and subStmt() is a private matcher that gives access to SwitchCase's SubStmt. A.k.a. qt-use-unreachable-return. There were some false positives, suppressed them with NOLINTNEXTLINE. They're not really false positiives, it's just that Clang sees the world in one way and if conditonal compilation (#if) differs for other compilers, Clang doesn't know better. This is an artifact of matching two consecutive statements. I haven't figured out how to remove the empty line left by the deletion of the return statement, if it, indeed, was on a separate line, so post-processed the patch to remove all the lines matching ^\+ *$ from the diff: git commit -am meep git reset --hard HEAD^ git diff HEAD..HEAD@{1} | sed '/^\+ *$/d' | recountdiff - | patch -p1 [ChangeLog][QtCore][QtAssert] Added Q_UNREACHABLE_RETURN() macro. Change-Id: I9782939f16091c964f25b7826e1c0dbd13a71305 Reviewed-by: Marc Mutz Reviewed-by: Thiago Macieira --- src/gui/rhi/qrhigles2.cpp | 51 ++++++++++++++++------------------------------- 1 file changed, 17 insertions(+), 34 deletions(-) (limited to 'src/gui/rhi/qrhigles2.cpp') diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp index a45915495e..a8b7919647 100644 --- a/src/gui/rhi/qrhigles2.cpp +++ b/src/gui/rhi/qrhigles2.cpp @@ -1232,8 +1232,7 @@ bool QRhiGles2::isFeatureSupported(QRhi::Feature feature) const case QRhi::NonFillPolygonMode: return !caps.gles; default: - Q_UNREACHABLE(); - return false; + Q_UNREACHABLE_RETURN(false); } } @@ -1271,8 +1270,7 @@ int QRhiGles2::resourceLimit(QRhi::ResourceLimit limit) const case QRhi::MaxVertexOutputs: return caps.maxVertexOutputs; default: - Q_UNREACHABLE(); - return 0; + Q_UNREACHABLE_RETURN(0); } } @@ -2356,8 +2354,7 @@ static inline GLenum toGlTopology(QRhiGraphicsPipeline::Topology t) case QRhiGraphicsPipeline::Patches: return GL_PATCHES; default: - Q_UNREACHABLE(); - return GL_TRIANGLES; + Q_UNREACHABLE_RETURN(GL_TRIANGLES); } } @@ -2369,8 +2366,7 @@ static inline GLenum toGlCullMode(QRhiGraphicsPipeline::CullMode c) case QRhiGraphicsPipeline::Back: return GL_BACK; default: - Q_UNREACHABLE(); - return GL_BACK; + Q_UNREACHABLE_RETURN(GL_BACK); } } @@ -2382,8 +2378,7 @@ static inline GLenum toGlFrontFace(QRhiGraphicsPipeline::FrontFace f) case QRhiGraphicsPipeline::CW: return GL_CW; default: - Q_UNREACHABLE(); - return GL_CCW; + Q_UNREACHABLE_RETURN(GL_CCW); } } @@ -2427,8 +2422,7 @@ static inline GLenum toGlBlendFactor(QRhiGraphicsPipeline::BlendFactor f) qWarning("Unsupported blend factor %d", f); return GL_ZERO; default: - Q_UNREACHABLE(); - return GL_ZERO; + Q_UNREACHABLE_RETURN(GL_ZERO); } } @@ -2446,8 +2440,7 @@ static inline GLenum toGlBlendOp(QRhiGraphicsPipeline::BlendOp op) case QRhiGraphicsPipeline::Max: return GL_MAX; default: - Q_UNREACHABLE(); - return GL_FUNC_ADD; + Q_UNREACHABLE_RETURN(GL_FUNC_ADD); } } @@ -2471,8 +2464,7 @@ static inline GLenum toGlCompareOp(QRhiGraphicsPipeline::CompareOp op) case QRhiGraphicsPipeline::Always: return GL_ALWAYS; default: - Q_UNREACHABLE(); - return GL_ALWAYS; + Q_UNREACHABLE_RETURN(GL_ALWAYS); } } @@ -2496,8 +2488,7 @@ static inline GLenum toGlStencilOp(QRhiGraphicsPipeline::StencilOp op) case QRhiGraphicsPipeline::DecrementAndWrap: return GL_DECR_WRAP; default: - Q_UNREACHABLE(); - return GL_KEEP; + Q_UNREACHABLE_RETURN(GL_KEEP); } } @@ -2509,8 +2500,7 @@ static inline GLenum toGlPolygonMode(QRhiGraphicsPipeline::PolygonMode mode) case QRhiGraphicsPipeline::PolygonMode::Line: return GL_LINE; default: - Q_UNREACHABLE(); - return GL_FILL; + Q_UNREACHABLE_RETURN(GL_FILL); } } @@ -2528,8 +2518,7 @@ static inline GLenum toGlMinFilter(QRhiSampler::Filter f, QRhiSampler::Filter m) else return m == QRhiSampler::Nearest ? GL_LINEAR_MIPMAP_NEAREST : GL_LINEAR_MIPMAP_LINEAR; default: - Q_UNREACHABLE(); - return GL_LINEAR; + Q_UNREACHABLE_RETURN(GL_LINEAR); } } @@ -2541,8 +2530,7 @@ static inline GLenum toGlMagFilter(QRhiSampler::Filter f) case QRhiSampler::Linear: return GL_LINEAR; default: - Q_UNREACHABLE(); - return GL_LINEAR; + Q_UNREACHABLE_RETURN(GL_LINEAR); } } @@ -2556,8 +2544,7 @@ static inline GLenum toGlWrapMode(QRhiSampler::AddressMode m) case QRhiSampler::Mirror: return GL_MIRRORED_REPEAT; default: - Q_UNREACHABLE(); - return GL_CLAMP_TO_EDGE; + Q_UNREACHABLE_RETURN(GL_CLAMP_TO_EDGE); } } @@ -2581,8 +2568,7 @@ static inline GLenum toGlTextureCompareFunc(QRhiSampler::CompareOp op) case QRhiSampler::Always: return GL_ALWAYS; default: - Q_UNREACHABLE(); - return GL_NEVER; + Q_UNREACHABLE_RETURN(GL_NEVER); } } @@ -4275,8 +4261,7 @@ static inline GLenum toGlShaderType(QRhiShaderStage::Type type) case QRhiShaderStage::Compute: return GL_COMPUTE_SHADER; default: - Q_UNREACHABLE(); - return GL_VERTEX_SHADER; + Q_UNREACHABLE_RETURN(GL_VERTEX_SHADER); } } @@ -4558,8 +4543,7 @@ static inline QShader::Stage toShaderStage(QRhiShaderStage::Type type) case QRhiShaderStage::Compute: return QShader::ComputeStage; default: - Q_UNREACHABLE(); - return QShader::VertexStage; + Q_UNREACHABLE_RETURN(QShader::VertexStage); } } @@ -5526,8 +5510,7 @@ bool QGles2GraphicsPipeline::create() default: break; } - Q_UNREACHABLE(); - return VtxIdx; + Q_UNREACHABLE_RETURN(VtxIdx); }; QShaderDescription desc[LastIdx]; QShader::SeparateToCombinedImageSamplerMappingList samplerMappingList[LastIdx]; -- cgit v1.2.3