diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2013-11-26 23:05:57 -0800 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-11-29 08:18:46 +0100 |
commit | 612785f39e325b0578be89e09b0e32d7d08d471e (patch) | |
tree | be0dcf652f038ef92d05ca18644c5889a8e2973b /src/qml/qml | |
parent | 3a3f3db45106ba8dabc2735d7b02d39142fad054 (diff) |
Fix warnings: initialize Instruction variables created on the stack
GCC 4.7-4.9 are right that the "code" member is used uninitialized. In
fact, GCC 4.9 was quite assertive about it:
qqmlinstruction_p.h:538:102: error: ‘def.QQmlInstructionData<8>::<anonymous>.QQmlInstruction::instr_common::code’ is used uninitialized in this function [-Werror=uninitialized]
static void setData(QQmlInstruction &instr, const DataType &v) { memcpy(&instr.FMT, &v, Size); } \
^
(It says "is used uninitialized" for this particular case; the "may be
used uninitialized" appears in other places)
The analysis is as follows:
- variable declared on qqmlcompiler.cpp:1467:
Instruction::SetDefault def;
- type is POD, so no initialization is performed (def contains garbage)
- on qqmlcompiler.cpp:1468 we use the variable:
output->addInstruction(def);
- QQmlCompiledData::addInstruction is inlined and does:
QQmlInstructionMeta<Instr>::setData(genericInstr, data);
- which is the call above, doing a memcpy with a source (&v) equal to
the uninitialized "def" variable
- result: memcpy is copying uninitialized bytes
Valgrind doesn't report this because it doesn't care about copying
uninitialized data. It will only complain if a decision is made based
on it, which we don't since the first thing we do after the memcpy is
initialize the member.
The solution is simple to not copy the common part of the
instructions. This way, we save 8 bytes of unnecessary copying and we
still keep the warning if a member of an extended instruction isn't
set.
Change-Id: I940b40ea9aa61c7386e5cced4a7865be7bfddb5d
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src/qml/qml')
-rw-r--r-- | src/qml/qml/qqmlcompiler_p.h | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlinstruction_p.h | 6 |
2 files changed, 6 insertions, 2 deletions
diff --git a/src/qml/qml/qqmlcompiler_p.h b/src/qml/qml/qqmlcompiler_p.h index 3ca4566e41..05c877d98b 100644 --- a/src/qml/qml/qqmlcompiler_p.h +++ b/src/qml/qml/qqmlcompiler_p.h @@ -169,7 +169,7 @@ public: int addInstruction(const QQmlInstructionData<Instr> &data) { QQmlInstruction genericInstr; - QQmlInstructionMeta<Instr>::setData(genericInstr, data); + QQmlInstructionMeta<Instr>::setDataNoCommon(genericInstr, data); return addInstructionHelper(static_cast<QQmlInstruction::Type>(Instr), genericInstr); } int nextInstructionIndex(); diff --git a/src/qml/qml/qqmlinstruction_p.h b/src/qml/qml/qqmlinstruction_p.h index 150ee8df19..bda8c3db0d 100644 --- a/src/qml/qml/qqmlinstruction_p.h +++ b/src/qml/qml/qqmlinstruction_p.h @@ -536,7 +536,11 @@ struct QQmlInstructionMeta { typedef QQmlInstruction::instr_##FMT DataType; \ static const DataType &data(const QQmlInstruction &instr) { return instr.FMT; } \ static void setData(QQmlInstruction &instr, const DataType &v) { memcpy(&instr.FMT, &v, Size); } \ - }; + static void setDataNoCommon(QQmlInstruction &instr, const DataType &v) \ + { memcpy(reinterpret_cast<char *>(&instr.FMT) + sizeof(QQmlInstruction::instr_common), \ + reinterpret_cast<const char *>(&v) + sizeof(QQmlInstruction::instr_common), \ + Size - sizeof(QQmlInstruction::instr_common)); } \ + }; FOR_EACH_QML_INSTR(QML_INSTR_META_TEMPLATE); #undef QML_INSTR_META_TEMPLATE |