From dfe827e793c14a594a601ff727316fa064d5e445 Mon Sep 17 00:00:00 2001 From: Kp Date: Sat, 11 Feb 2017 21:42:43 +0000 Subject: [PATCH] Relax valptridx::guarded compile-time checks When using `gcc -fsanitize=undefined`, the compiler proves trivial results, so `DXX_CONSTANT_TRUE` is defined. It then fails to prove that `DXX_CONSTANT_TRUE(m_state == checked)` is false, causing a compile-time error. Relax the check to occur only when it can prove `m_state` equal to a disallowed value, rather than when it cannot prove `m_state` equal to an allowed value. Move the preprocessor guard so that the runtime check is always visible. Optimizing compilers can still eliminate that check at compile-time when it provably never fails. --- common/include/valptridx.h | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/common/include/valptridx.h b/common/include/valptridx.h index 32d056cac..b5b933e6e 100644 --- a/common/include/valptridx.h +++ b/common/include/valptridx.h @@ -683,11 +683,10 @@ public: #define DXX_VALPTRIDX_GUARDED_OBJECT_NO "access to guarded object that does not exist" #define DXX_VALPTRIDX_GUARDED_OBJECT_MAYBE "access to guarded object that may not exist" #ifdef DXX_CONSTANT_TRUE - /* If the contained object might not exist: */ - if (!DXX_CONSTANT_TRUE(m_state == checked)) { /* - * Always fail. Choose an error message and function name + * If the validity has not been verified by the caller, then + * fail. Choose an error message and function name * based on whether the contained type provably does not * exist. It provably does not exist if this call is on a * path where operator bool() returned false. It @@ -696,10 +695,11 @@ public: */ if (DXX_CONSTANT_TRUE(m_state == empty)) DXX_ALWAYS_ERROR_FUNCTION(guarded_accessed_empty, DXX_VALPTRIDX_GUARDED_OBJECT_NO); - else + /* If the contained object might not exist: */ + if (DXX_CONSTANT_TRUE(m_state == initialized)) DXX_ALWAYS_ERROR_FUNCTION(guarded_accessed_unchecked, DXX_VALPTRIDX_GUARDED_OBJECT_MAYBE); } -#else +#endif /* * If the compiler does not offer constant truth analysis * (perhaps because of insufficient optimization), then emit a @@ -715,7 +715,6 @@ public: */ if (m_state != checked) throw std::logic_error(m_state == empty ? DXX_VALPTRIDX_GUARDED_OBJECT_NO : DXX_VALPTRIDX_GUARDED_OBJECT_MAYBE); -#endif #undef DXX_VALPTRIDX_GUARDED_OBJECT_MAYBE #undef DXX_VALPTRIDX_GUARDED_OBJECT_NO return m_value;