diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2015-09-22 22:46:08 -0700 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2015-09-24 02:35:06 +0000 |
commit | 0e90fac4afeda889c38a8c1998fdba92e9138559 (patch) | |
tree | 04584b8cdfbe4ffa357859daa7b8dd271eedfa86 /src/qml/jsruntime/qv4value_p.h | |
parent | d272582379b9f73f283bbc98177ed9b02af48367 (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.h | 4 |
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; } |