Relax valptridx<T>::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.
This commit is contained in:
Kp 2017-02-11 21:42:43 +00:00
parent ceb510566f
commit dfe827e793

View file

@ -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;