Fix warning about type-punned pointers

The d->buffer array was 2x the required size and every other void*
actually stored a DBINT (int) indicating the binding status of the
null. The qIsNull function checked that value, but got the warning
printed.

Instead, let's just do the right thing and have a struct for each
column. Solves the problem more neatly.

Change-Id: I2daaf05c876da7e0e13fb983c58916d946518846
Reviewed-by: Robin Burchell <robin+qt@viroteck.net>
Reviewed-by: Mark Brand <mabrand@mabrand.nl>
This commit is contained in:
Thiago Macieira 2013-01-24 16:14:59 -08:00 committed by The Qt Project
parent 4bb5566632
commit 5544208e22

View File

@ -145,6 +145,12 @@ public:
bool initialized; bool initialized;
}; };
struct QTDSColumnData
{
void *data;
DBINT nullbind;
};
Q_DECLARE_TYPEINFO(QTDSColumnData, Q_MOVABLE_TYPE);
class QTDSResultPrivate class QTDSResultPrivate
{ {
@ -156,7 +162,7 @@ public:
void addErrorMsg(QString& errMsg) { errorMsgs.append(errMsg); } void addErrorMsg(QString& errMsg) { errorMsgs.append(errMsg); }
QString getErrorMsgs() { return errorMsgs.join(QLatin1String("\n")); } QString getErrorMsgs() { return errorMsgs.join(QLatin1String("\n")); }
void clearErrorMsgs() { errorMsgs.clear(); } void clearErrorMsgs() { errorMsgs.clear(); }
QVector<void *> buffer; QVector<QTDSColumnData> buffer;
QSqlRecord rec; QSqlRecord rec;
private: private:
@ -325,8 +331,8 @@ void QTDSResult::cleanup()
{ {
d->clearErrorMsgs(); d->clearErrorMsgs();
d->rec.clear(); d->rec.clear();
for (int i = 0; i < d->buffer.size() / 2; ++i) for (int i = 0; i < d->buffer.size(); ++i)
free(d->buffer.at(i * 2)); free(d->buffer.at(i * 2).data);
d->buffer.clear(); d->buffer.clear();
// "can" stands for "cancel"... very clever. // "can" stands for "cancel"... very clever.
dbcanquery(d->dbproc); dbcanquery(d->dbproc);
@ -340,9 +346,9 @@ QVariant QTDSResult::handle() const
return QVariant(qRegisterMetaType<DBPROCESS *>("DBPROCESS*"), &d->dbproc); return QVariant(qRegisterMetaType<DBPROCESS *>("DBPROCESS*"), &d->dbproc);
} }
static inline bool qIsNull(const void *ind) static inline bool qIsNull(const QTDSColumnData &p)
{ {
return *reinterpret_cast<const DBINT *>(&ind) == -1; return p.nullbind == -1;
} }
bool QTDSResult::gotoNext(QSqlCachedResult::ValueCache &values, int index) bool QTDSResult::gotoNext(QSqlCachedResult::ValueCache &values, int index)
@ -364,33 +370,33 @@ bool QTDSResult::gotoNext(QSqlCachedResult::ValueCache &values, int index)
int idx = index + i; int idx = index + i;
switch (d->rec.field(i).type()) { switch (d->rec.field(i).type()) {
case QVariant::DateTime: case QVariant::DateTime:
if (qIsNull(d->buffer.at(i * 2 + 1))) { if (qIsNull(d->buffer.at(i))) {
values[idx] = QVariant(QVariant::DateTime); values[idx] = QVariant(QVariant::DateTime);
} else { } else {
DBDATETIME *bdt = (DBDATETIME*) d->buffer.at(i * 2); DBDATETIME *bdt = (DBDATETIME*) d->buffer.at(i).data;
QDate date = QDate::fromString(QLatin1String("1900-01-01"), Qt::ISODate); QDate date = QDate::fromString(QLatin1String("1900-01-01"), Qt::ISODate);
QTime time = QTime::fromString(QLatin1String("00:00:00"), Qt::ISODate); QTime time = QTime::fromString(QLatin1String("00:00:00"), Qt::ISODate);
values[idx] = QDateTime(date.addDays(bdt->dtdays), time.addMSecs(int(bdt->dttime / 0.3))); values[idx] = QDateTime(date.addDays(bdt->dtdays), time.addMSecs(int(bdt->dttime / 0.3)));
} }
break; break;
case QVariant::Int: case QVariant::Int:
if (qIsNull(d->buffer.at(i * 2 + 1))) if (qIsNull(d->buffer.at(i)))
values[idx] = QVariant(QVariant::Int); values[idx] = QVariant(QVariant::Int);
else else
values[idx] = *((int*)d->buffer.at(i * 2)); values[idx] = *((int*)d->buffer.at(i).data);
break; break;
case QVariant::Double: case QVariant::Double:
case QVariant::String: case QVariant::String:
if (qIsNull(d->buffer.at(i * 2 + 1))) if (qIsNull(d->buffer.at(i)))
values[idx] = QVariant(QVariant::String); values[idx] = QVariant(QVariant::String);
else else
values[idx] = QString::fromLocal8Bit((const char*)d->buffer.at(i * 2)).trimmed(); values[idx] = QString::fromLocal8Bit((const char*)d->buffer.at(i).data).trimmed();
break; break;
case QVariant::ByteArray: { case QVariant::ByteArray: {
if (qIsNull(d->buffer.at(i * 2 + 1))) if (qIsNull(d->buffer.at(i)))
values[idx] = QVariant(QVariant::ByteArray); values[idx] = QVariant(QVariant::ByteArray);
else else
values[idx] = QByteArray((const char*)d->buffer.at(i * 2)); values[idx] = QByteArray((const char*)d->buffer.at(i).data);
break; break;
} }
default: default:
@ -430,7 +436,7 @@ bool QTDSResult::reset (const QString& query)
setSelect((DBCMDROW(d->dbproc) == SUCCEED)); // decide whether or not we are dealing with a SELECT query setSelect((DBCMDROW(d->dbproc) == SUCCEED)); // decide whether or not we are dealing with a SELECT query
int numCols = dbnumcols(d->dbproc); int numCols = dbnumcols(d->dbproc);
if (numCols > 0) { if (numCols > 0) {
d->buffer.resize(numCols * 2); d->buffer.resize(numCols);
init(numCols); init(numCols);
} }
for (int i = 0; i < numCols; ++i) { for (int i = 0; i < numCols; ++i) {
@ -470,11 +476,11 @@ bool QTDSResult::reset (const QString& query)
break; break;
} }
if (ret == SUCCEED) { if (ret == SUCCEED) {
d->buffer[i * 2] = p; d->buffer[i].data = p;
ret = dbnullbind(d->dbproc, i+1, (DBINT*)(&d->buffer[i * 2 + 1])); ret = dbnullbind(d->dbproc, i+1, &d->buffer[i].nullbind);
} else { } else {
d->buffer[i * 2] = 0; d->buffer[i].data = 0;
d->buffer[i * 2 + 1] = 0; d->buffer[i].nullbind = 0;
free(p); free(p);
} }
if ((ret != SUCCEED) && (ret != -1)) { if ((ret != SUCCEED) && (ret != -1)) {