aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4value_p.h
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2015-09-22 22:46:08 -0700
committerThiago Macieira <thiago.macieira@intel.com>2015-09-24 02:35:06 +0000
commit0e90fac4afeda889c38a8c1998fdba92e9138559 (patch)
tree04584b8cdfbe4ffa357859daa7b8dd271eedfa86 /src/qml/jsruntime/qv4value_p.h
parentd272582379b9f73f283bbc98177ed9b02af48367 (diff)
Fix read of uninitialized value (undefined behavior)
Commit 92836d052efb6d8073136e8507083f93fb60bb80 fixed the type punning but introduced undefined behavior on 32-bit systems. Detected by GCC 5.2 qv4value_p.h:96:55: error: ‘v.Qti386::QV4::Value::_val’ may be used uninitialized in this function [-Werror=maybe-uninitialized] qv4scopedvalue_p.h:199:15: note: ‘v.Qti386::QV4::Value::_val’ was declared here Trace: starting at qv4scopedvalue_p.h:199 Value v; v = o; => Value &operator=(Heap::Base *o) { setM(o); => Q_ALWAYS_INLINE void setM(Heap::Base *b) { quint32 v; memcpy(&v, &b, 4); setValue(v); } => Q_ALWAYS_INLINE void setValue(quint32 v) { setTagValue(tag(), v); } => Q_ALWAYS_INLINE quint32 tag() const { return _val >> 32; } The call to tag() reads from _val before it is initialized. Up until C++11, uninitialized variables simply had an indeterminate value. Starting with C++14 (see N3914, resolution of DR1787), reading that variable not as an unsigned char has undefined behavior. See 8.5 [dcl.init] p12: ... When storage for an object with automatic or dynamic storage duration is obtained, the object has an indeterminate value, and if no initialization is performed for the object, that object retains an indeterminate value until that value is replaced (5.18). [...] If an indeterminate value is produced by an evaluation, the behavior is undefined except in the following cases: [list of cases that use unsigned char] Change-Id: I42e7ef1a481840699a8dffff1406852f2badabca Reviewed-by: Ulf Hermann <ulf.hermann@theqtcompany.com>
Diffstat (limited to 'src/qml/jsruntime/qv4value_p.h')
-rw-r--r--src/qml/jsruntime/qv4value_p.h4
1 files changed, 2 insertions, 2 deletions
diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h
index 6305e6dfbb..14094878d8 100644
--- a/src/qml/jsruntime/qv4value_p.h
+++ b/src/qml/jsruntime/qv4value_p.h
@@ -85,8 +85,8 @@ struct Q_QML_PRIVATE_EXPORT Value
Q_ALWAYS_INLINE quint64 val() const { return _val; }
Q_ALWAYS_INLINE void setVal(quint64 v) { _val = v; }
- Q_ALWAYS_INLINE void setValue(quint32 v) { setTagValue(tag(), v); }
- Q_ALWAYS_INLINE void setTag(quint32 t) { setTagValue(t, value()); }
+ Q_ALWAYS_INLINE void setValue(quint32 v) { memcpy(&_val, &v, 4); }
+ Q_ALWAYS_INLINE void setTag(quint32 t) { memcpy(4 + (quint8 *)&_val, &t, 4); }
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
static inline int valueOffset() { return 0; }