From c780d893744e6ba5a5417f0b173dc514e9fe12d2 Mon Sep 17 00:00:00 2001 From: iakov Date: Mon, 30 Jan 2023 04:27:54 -0800 Subject: [PATCH] [Backport] Several fixes and patches (#89) (cherry-picked and adapted from MeVisLab/pythonqt@1e794e53fba336167d9d5cb542af5527974dea79) * minor improvements in code and unit tests * disable warnings for deprecated declarations * add -Wpedantic and even -Werror for src, but relax some warnings * fix undefined behavior * fix memory leaks * use QT_NO_CAST_TO_ASCII to prevent incorrect behavior on non-Latin1 input * Improvements in build and CI: ** add parallel build ** add `make check` support ** fix `debug`/`release` builds ** force C++11 ** introduce UBSan into CI ** fixes for macOS build with clang ** add pkg-config support: if PKGCONFIG is set, skip old-style lookup (useful on Linux and macOS GHA, when `python-config` returns incorrect linkage options with missing `-Ldirs`) ** add macOS GHA CI --- PythonQt.pro | 4 +- build/common.prf | 3 +- build/python.prf | 40 +++++++++--- extensions/PythonQt_QtAll/PythonQt_QtAll.cpp | 6 +- extensions/PythonQt_QtAll/PythonQt_QtAll.h | 2 +- extensions/PythonQt_QtAll/PythonQt_QtAll.pro | 68 +++++++++++--------- generator/abstractmetabuilder.cpp | 11 +++- generator/abstractmetalang.cpp | 4 +- generator/generator.h | 2 +- generator/generator.pri | 12 ++-- generator/generator.pro | 4 +- generator/main.cpp | 8 +-- generator/parser/codemodel.cpp | 4 +- generator/parser/codemodel.h | 65 ++++++++----------- generator/parser/codemodel_fwd.h | 2 +- generator/parser/lexer.cpp | 3 +- generator/parser/parser.cpp | 2 - generator/parser/rpp/pp-iterator.h | 3 + generator/parser/rxx_allocator.h | 7 +- generator/shellgenerator.cpp | 3 +- generator/shellimplgenerator.cpp | 4 +- generator/typesystem.cpp | 9 ++- generator/typesystem.h | 2 +- src/PythonQt.cpp | 66 +++++++++++++------ src/PythonQtClassInfo.cpp | 7 +- src/PythonQtClassWrapper.cpp | 17 ++--- src/PythonQtConversion.cpp | 2 +- src/PythonQtCppWrapperFactory.h | 6 +- src/PythonQtImportFileInterface.h | 5 +- src/PythonQtImporter.cpp | 14 +++- src/PythonQtProperty.cpp | 1 + src/PythonQtPythonInclude.h | 21 ++++++ src/PythonQtSignal.cpp | 4 ++ src/PythonQtSignalReceiver.cpp | 2 +- src/PythonQtSlot.cpp | 8 ++- src/PythonQtSlotDecorator.cpp | 1 + src/PythonQtStdIn.cpp | 2 +- src/PythonQtThreadSupport.h | 3 +- src/src.pri | 9 ++- src/src.pro | 8 ++- tests/PythonQtTestMain.cpp | 4 +- tests/PythonQtTests.h | 22 +++---- tests/tests.pro | 9 +++ 43 files changed, 294 insertions(+), 185 deletions(-) diff --git a/PythonQt.pro b/PythonQt.pro index fb297153..819e6f39 100644 --- a/PythonQt.pro +++ b/PythonQt.pro @@ -1,4 +1,6 @@ TEMPLATE = subdirs -CONFIG += ordered SUBDIRS = generator src extensions tests examples +tests.depends += src extensions +extensions.depends += src +examples.depends += src extensions diff --git a/build/common.prf b/build/common.prf index 8e5101fe..e5f3ad7e 100644 --- a/build/common.prf +++ b/build/common.prf @@ -69,4 +69,5 @@ PYTHONQT_GENERATED_PATH = $$PWD/../generated_cpp VERSION = 3.2.0 win32: CONFIG += skip_target_version_ext -unix: QMAKE_CXXFLAGS += -std=c++11 +unix: CONFIG += c++11 +gcc: QMAKE_CXXFLAGS += -Wno-deprecated-declarations diff --git a/build/python.prf b/build/python.prf index 4bfcec32..aea655ca 100644 --- a/build/python.prf +++ b/build/python.prf @@ -17,9 +17,27 @@ isEmpty( PYTHON_DIR ) { PYTHON_DIR=$${PYTHON_DIR}/ } -message(Using Python version $${PYTHON_VERSION}) +PYTHON_VERSION_MAJOR=$$section(PYTHON_VERSION, ., 0, 0) +PYTHON_VERSION_MINOR=$$section(PYTHON_VERSION, ., 1, 1) -macx { +!equals(PYTHON_VERSION, $${PYTHON_VERSION_MAJOR}.$${PYTHON_VERSION_MINOR}) { + error("Failed to parse PYTHON_VERSION:\"$$PYTHON_VERSION\"") +} else { + message(Using Python version $${PYTHON_VERSION}) +} + + +# Python 2.x has problems: +# 1) https://wiki.gentoo.org/wiki/Project:Python/Strict_aliasing +# 2) deprecated implicit cast of string literals to char* +equals(PYTHON_VERSION_MAJOR, 2):gcc:QMAKE_CXXFLAGS *= -fno-strict-aliasing -Wno-error=write-strings +contains(PKGCONFIG, "python.*"){ + CONFIG += link_pkgconfig + PYTHON_PKGCONFIG = $$member($$unique($$find(PKGCONFIG, "python.*")), 1, 1) + # add rpath + PYTHON_LIBDIR = $$system($$pkgConfigExecutable() --libs-only-L $$PYTHON_PKGCONFIG) + QMAKE_RPATHDIR += $$replace(PYTHON_LIBDIR,-L,) +} else:macx:isEmpty(PYTHON_DIR){ # for macx you need to have the Python development kit installed as framework INCLUDEPATH += /System/Library/Frameworks/Python.framework/Headers LIBS += -F/System/Library/Frameworks -framework Python @@ -52,15 +70,17 @@ macx { # make sure that you have installed a matching python-dev package. PYTHON_CONFIG = $${PYTHON_DIR}/bin/python$${PYTHON_VERSION}-config - system($${PYTHON_CONFIG} --embed --libs) { - unix:LIBS += $$system($${PYTHON_CONFIG} --embed --libs) - } else: unix:LIBS += $$system($${PYTHON_CONFIG} --libs) - unix:QMAKE_CXXFLAGS += $$system($${PYTHON_CONFIG} --includes) + PYTHON_CONFIG_OPTIONS_LIBS = --libs + equals(PYTHON_VERSION_MAJOR, 3):!lessThan(PYTHON_VERSION_MINOR, 8) { + # Since 3.8 `--embed` is needed + PYTHON_CONFIG_OPTIONS_LIBS += --embed + } + LIBS += $$system($${PYTHON_CONFIG} $${PYTHON_CONFIG_OPTIONS_LIBS}) + QMAKE_CXXFLAGS += $$system($${PYTHON_CONFIG} --includes) PYTHON_LFLAGS = $$system($${PYTHON_CONFIG} --ldflags) - unix:QMAKE_LFLAGS += $${PYTHON_LFLAGS} + QMAKE_LFLAGS += $${PYTHON_LFLAGS} # add rpath PYTHON_LIBDIR = $$find(PYTHON_LFLAGS,-L.*) - RPATH = -Wl,-rpath, - PYTHON_RPATH = $$replace(PYTHON_LIBDIR,-L,$${RPATH}) - unix:QMAKE_LFLAGS += $${PYTHON_RPATH} + PYTHON_RPATH = $$replace(PYTHON_LIBDIR,-L,) + QMAKE_RPATHDIR += $$PYTHON_RPATH } diff --git a/extensions/PythonQt_QtAll/PythonQt_QtAll.cpp b/extensions/PythonQt_QtAll/PythonQt_QtAll.cpp index f6dcd17a..50a0ccec 100644 --- a/extensions/PythonQt_QtAll/PythonQt_QtAll.cpp +++ b/extensions/PythonQt_QtAll/PythonQt_QtAll.cpp @@ -117,7 +117,5 @@ namespace PythonQt_QtAll #ifdef PYTHONQT_WITH_UITOOLS PythonQt_init_QtUiTools(0); #endif - }; -}; - - + } +} diff --git a/extensions/PythonQt_QtAll/PythonQt_QtAll.h b/extensions/PythonQt_QtAll/PythonQt_QtAll.h index 7f1de8f3..689e2e83 100644 --- a/extensions/PythonQt_QtAll/PythonQt_QtAll.h +++ b/extensions/PythonQt_QtAll/PythonQt_QtAll.h @@ -47,6 +47,6 @@ namespace PythonQt_QtAll { //! initialize the Qt binding PYTHONQT_QTALL_EXPORT void init(); -}; +} #endif diff --git a/extensions/PythonQt_QtAll/PythonQt_QtAll.pro b/extensions/PythonQt_QtAll/PythonQt_QtAll.pro index 4bf5da46..ddf8e087 100644 --- a/extensions/PythonQt_QtAll/PythonQt_QtAll.pro +++ b/extensions/PythonQt_QtAll/PythonQt_QtAll.pro @@ -1,19 +1,23 @@ # get external pythonqtall config or enable all by default +isEmpty( PYTHONQTALL_CONFIG ) { + PYTHONQTALL_CONFIG = $$(PYTHONQTALL_CONFIG) +} + isEmpty( PYTHONQTALL_CONFIG ) { message("using default PythonQt_QtAll Configuration") CONFIG += PythonQtCore - CONFIG += PythonQtGui - CONFIG += PythonQtSvg - CONFIG += PythonQtSql - CONFIG += PythonQtNetwork - CONFIG += PythonQtOpengl - CONFIG += PythonQtXml - CONFIG += PythonQtXmlpatterns - CONFIG += PythonQtMultimedia - CONFIG += PythonQtQml - CONFIG += PythonQtQuick - CONFIG += PythonQtUiTools + qtHaveModule(gui):qtHaveModule(widgets):CONFIG += PythonQtGui + qtHaveModule(svg):CONFIG += PythonQtSvg + qtHaveModule(sql):CONFIG += PythonQtSql + qtHaveModule(network):CONFIG += PythonQtNetwork + qtHaveModule(opengl):CONFIG += PythonQtOpengl + qtHaveModule(xml):CONFIG += PythonQtXml + qtHaveModule(xmlpatterns):CONFIG += PythonQtXmlpatterns + qtHaveModule(multimedia):CONFIG += PythonQtMultimedia + qtHaveModule(qml):CONFIG += PythonQtQml + qtHaveModule(quick):CONFIG += PythonQtQuick + qtHaveModule(uitools):CONFIG += PythonQtUiTools qtHaveModule(webkit):CONFIG += PythonQtWebKit } else { @@ -36,10 +40,10 @@ CONFIG += dll qt DEFINES += PYTHONQT_QTALL_EXPORTS HEADERS += \ - PythonQt_QtAll.h + $$PWD/PythonQt_QtAll.h SOURCES += \ - PythonQt_QtAll.cpp + $$PWD/PythonQt_QtAll.cpp unix { CONFIG += create_pc create_prl no_install_prl @@ -60,79 +64,81 @@ headers.path = /include INSTALLS += target headers +defineTest(Xinclude) { + f=$$PYTHONQT_GENERATED_PATH/$$1/$${1}.pri + exists($$f):include($$f):export(HEADERS):export(SOURCES):export(DEFINES) + +} + + PythonQtCore { DEFINES += PYTHONQT_WITH_CORE - include ($$PYTHONQT_GENERATED_PATH/com_trolltech_qt_core/com_trolltech_qt_core.pri) + Xinclude (com_trolltech_qt_core) } PythonQtGui { DEFINES += PYTHONQT_WITH_GUI - include ($$PYTHONQT_GENERATED_PATH/com_trolltech_qt_gui/com_trolltech_qt_gui.pri) + Xinclude (com_trolltech_qt_gui) QT += gui widgets printsupport } PythonQtSvg { DEFINES += PYTHONQT_WITH_SVG - include ($$PYTHONQT_GENERATED_PATH/com_trolltech_qt_svg/com_trolltech_qt_svg.pri) + Xinclude (com_trolltech_qt_svg) QT +=svg } PythonQtSql { DEFINES += PYTHONQT_WITH_SQL - include ($$PYTHONQT_GENERATED_PATH/com_trolltech_qt_sql/com_trolltech_qt_sql.pri) + Xinclude (com_trolltech_qt_sql) QT += sql } PythonQtNetwork { DEFINES += PYTHONQT_WITH_NETWORK - include ($$PYTHONQT_GENERATED_PATH/com_trolltech_qt_network/com_trolltech_qt_network.pri) + Xinclude (com_trolltech_qt_network) QT += network } PythonQtOpengl { DEFINES += PYTHONQT_WITH_OPENGL - PythonQtCore: include ($$PYTHONQT_GENERATED_PATH/com_trolltech_qt_opengl/com_trolltech_qt_opengl.pri) QT += opengl -} - -PythonQtXml { - DEFINES += PYTHONQT_WITH_XML - include ($$PYTHONQT_GENERATED_PATH/com_trolltech_qt_xml/com_trolltech_qt_xml.pri) + PythonQtCore: Xinclude (com_trolltech_qt_opengl) QT += xml } PythonQtXmlpatterns { DEFINES += PYTHONQT_WITH_XMLPATTERNS - include ($$PYTHONQT_GENERATED_PATH/com_trolltech_qt_xmlpatterns/com_trolltech_qt_xmlpatterns.pri) + Xinclude (com_trolltech_qt_xmlpatterns) QT += xmlpatterns } PythonQtMultimedia { DEFINES += PYTHONQT_WITH_MULTIMEDIA - include ($$PYTHONQT_GENERATED_PATH/com_trolltech_qt_multimedia/com_trolltech_qt_multimedia.pri) - QT += multimedia multimediawidgets + Xinclude (com_trolltech_qt_multimedia) + QT += multimedia multimediawidgets } PythonQtQml { DEFINES += PYTHONQT_WITH_QML - include ($$PYTHONQT_GENERATED_PATH/com_trolltech_qt_qml/com_trolltech_qt_qml.pri) + Xinclude (com_trolltech_qt_qml) QT += qml } PythonQtQuick { DEFINES += PYTHONQT_WITH_QUICK - include ($$PYTHONQT_GENERATED_PATH/com_trolltech_qt_quick/com_trolltech_qt_quick.pri) + Xinclude (com_trolltech_qt_quick) QT += quick quickwidgets } PythonQtUiTools { DEFINES += PYTHONQT_WITH_UITOOLS - include ($$PYTHONQT_GENERATED_PATH/com_trolltech_qt_uitools/com_trolltech_qt_uitools.pri) + Xinclude (com_trolltech_qt_uitools) QT += uitools } PythonQtWebKit { DEFINES += PYTHONQT_WITH_WEBKIT - include ($$PYTHONQT_GENERATED_PATH/com_trolltech_qt_webkit/com_trolltech_qt_webkit.pri) + Xinclude (com_trolltech_qt_webkit) QT += webkit webkitwidgets } diff --git a/generator/abstractmetabuilder.cpp b/generator/abstractmetabuilder.cpp index ba605259..7677b158 100644 --- a/generator/abstractmetabuilder.cpp +++ b/generator/abstractmetabuilder.cpp @@ -746,6 +746,7 @@ int AbstractMetaBuilder::figureOutEnumValue(const QString &stringValue, AbstractMetaEnum *meta_enum, AbstractMetaFunction *meta_function) { + Q_UNUSED(meta_function) if (stringValue.isEmpty()) return oldValuevalue; @@ -1619,12 +1620,15 @@ AbstractMetaFunction *AbstractMetaBuilder::traverseFunction(FunctionModelItem fu // If we where not able to translate the default argument make it // reset all default arguments before this one too. - for (int i=0; isetDefaultValueExpression(QString()); + } - if (ReportHandler::debugLevel() == ReportHandler::FullDebug) - foreach(AbstractMetaArgument *arg, meta_arguments) + if (ReportHandler::debugLevel() == ReportHandler::FullDebug) { + foreach(AbstractMetaArgument *arg, meta_arguments) { ReportHandler::debugFull(" - " + arg->toString()); + } + } return meta_function; } @@ -1944,6 +1948,7 @@ QString AbstractMetaBuilder::translateDefaultValue(ArgumentModelItem item, Abstr AbstractMetaFunction *fnc, AbstractMetaClass *implementing_class, int argument_index) { + Q_UNUSED(type) QString function_name = fnc->name(); QString class_name = implementing_class->name(); diff --git a/generator/abstractmetalang.cpp b/generator/abstractmetalang.cpp index 41d1b56b..dfd831f2 100644 --- a/generator/abstractmetalang.cpp +++ b/generator/abstractmetalang.cpp @@ -1205,13 +1205,13 @@ AbstractMetaField *AbstractMetaField::copy() const return returned; } - +/* UNUSED static QString upCaseFirst(const QString &str) { Q_ASSERT(!str.isEmpty()); QString s = str; s[0] = s.at(0).toUpper(); return s; -} +} */ static AbstractMetaFunction *createXetter(const AbstractMetaField *g, const QString &name, uint type) { AbstractMetaFunction *f = new AbstractMetaFunction; diff --git a/generator/generator.h b/generator/generator.h index dfb342e8..78719296 100644 --- a/generator/generator.h +++ b/generator/generator.h @@ -54,7 +54,7 @@ class Generator : public QObject { Q_OBJECT - Q_PROPERTY(QString outputDirectory READ outputDirectory WRITE setOutputDirectory); + Q_PROPERTY(QString outputDirectory READ outputDirectory WRITE setOutputDirectory) public: enum Option { diff --git a/generator/generator.pri b/generator/generator.pri index c8a651a0..47e8eff3 100644 --- a/generator/generator.pri +++ b/generator/generator.pri @@ -2,15 +2,15 @@ isEmpty(GENERATORPATH):GENERATORPATH = $$PWD INCLUDEPATH += $$GENERATORPATH TEMPLATE = app +#CONFIG += cmdline -- does not work as expected with old Qt versions, f.e. is missing in 5.9 +CONFIG += console +CONFIG -= app_bundle + TARGET += DEPENDPATH += $$GENERATORPATH tests parser -mac:CONFIG -= app_bundle INCLUDEPATH += $$GENERATORPATH/. INCLUDEPATH += $$GENERATORPATH/../common -unix:CONFIG += debug_and_release - -CONFIG += console RESOURCES += generator.qrc include($$GENERATORPATH/parser/rxx.pri) @@ -21,6 +21,8 @@ win32-msvc2005:{ QMAKE_CXXFLAGS += -wd4996 QMAKE_CFLAGS += -wd4996 } +gcc:QMAKE_CXXFLAGS += -Wno-deprecated-declarations -Wpedantic +clang: QMAKE_CXXFLAGS += -Wno-nested-anon-types -Wno-gnu-anonymous-struct -Wno-unused-private-field # Input HEADERS += \ @@ -58,7 +60,7 @@ SOURCES += \ -QT = core xml +QT += core xml win32-msvc.net { QMAKE_CXXFLAGS += /Zm500 diff --git a/generator/generator.pro b/generator/generator.pro index 9e2ae506..c159e23b 100644 --- a/generator/generator.pro +++ b/generator/generator.pro @@ -1,10 +1,8 @@ TARGET = pythonqt_generator -CONFIG -= debug -CONFIG += release DESTDIR = . include(generator.pri) - +DEFINES += QT_NO_CAST_TO_ASCII # Input HEADERS += \ diff --git a/generator/main.cpp b/generator/main.cpp index 9961665f..a01b968a 100644 --- a/generator/main.cpp +++ b/generator/main.cpp @@ -53,7 +53,7 @@ void displayHelp(GeneratorSet *generatorSet); #include int main(int argc, char *argv[]) { - GeneratorSet *gs = GeneratorSet::getInstance(); + QScopedPointer gs(GeneratorSet::getInstance()); QString default_file = ":/trolltech/generator/qtscript_masterinclude.h"; QString default_system = ":/trolltech/generator/build_all.txt"; @@ -118,7 +118,7 @@ int main(int argc, char *argv[]) typesystemFileName = args.value("arg-2"); if (args.contains("arg-3")) - displayHelp(gs); + displayHelp(&*gs); if (fileName.isEmpty()) fileName = default_file; @@ -127,10 +127,10 @@ int main(int argc, char *argv[]) typesystemFileName = default_system; if (fileName.isEmpty() || typesystemFileName.isEmpty() ) - displayHelp(gs); + displayHelp(&*gs); if (!gs->readParameters(args)) - displayHelp(gs); + displayHelp(&*gs); printf("Please wait while source files are being generated...\n"); diff --git a/generator/parser/codemodel.cpp b/generator/parser/codemodel.cpp index f70e3085..4fafc76f 100644 --- a/generator/parser/codemodel.cpp +++ b/generator/parser/codemodel.cpp @@ -232,9 +232,9 @@ bool TypeInfo::operator==(const TypeInfo &other) } #endif - return flags == other.flags + return m_flags.equals(other.m_flags) && m_qualifiedName == other.m_qualifiedName - && (!m_functionPointer || m_arguments == other.m_arguments); + && (!m_flags.m_functionPointer || m_arguments == other.m_arguments); } // --------------------------------------------------------------------------- diff --git a/generator/parser/codemodel.h b/generator/parser/codemodel.h index 448cf719..fe24df1c 100644 --- a/generator/parser/codemodel.h +++ b/generator/parser/codemodel.h @@ -124,41 +124,28 @@ class CodeModel void operator = (const CodeModel &other); }; -class TypeInfo +struct TypeInfo { -public: - TypeInfo(const TypeInfo &other) - : flags(other.flags), - m_qualifiedName(other.m_qualifiedName), - m_arrayElements(other.m_arrayElements), - m_arguments(other.m_arguments), - m_rvalue_reference(other.m_rvalue_reference) - { - } - - TypeInfo(): - flags (0), m_rvalue_reference(false) {} - QStringList qualifiedName() const { return m_qualifiedName; } void setQualifiedName(const QStringList &qualified_name) { m_qualifiedName = qualified_name; } - bool isConstant() const { return m_constant; } - void setConstant(bool is) { m_constant = is; } + bool isConstant() const { return m_flags.m_constant; } + void setConstant(bool is) { m_flags.m_constant = is; } - bool isVolatile() const { return m_volatile; } - void setVolatile(bool is) { m_volatile = is; } + bool isVolatile() const { return m_flags.m_volatile; } + void setVolatile(bool is) { m_flags.m_volatile = is; } - bool isReference() const { return m_reference; } - void setReference(bool is) { m_reference = is; } + bool isReference() const { return m_flags.m_reference; } + void setReference(bool is) { m_flags.m_reference = is; } bool isRvalueReference() const { return m_rvalue_reference; } void setRvalueReference(bool is) { m_rvalue_reference = is; } - int indirections() const { return m_indirections; } - void setIndirections(int indirections) { m_indirections = indirections; } + int indirections() const { return m_flags.m_indirections; } + void setIndirections(int indirections) { m_flags.m_indirections = indirections; } - bool isFunctionPointer() const { return m_functionPointer; } - void setFunctionPointer(bool is) { m_functionPointer = is; } + bool isFunctionPointer() const { return m_flags.m_functionPointer; } + void setFunctionPointer(bool is) { m_flags.m_functionPointer = is; } QStringList arrayElements() const { return m_arrayElements; } void setArrayElements(const QStringList &arrayElements) { m_arrayElements = arrayElements; } @@ -178,25 +165,25 @@ class TypeInfo static TypeInfo resolveType (TypeInfo const &__type, CodeModelItem __scope); private: - union - { - uint flags; - - struct - { - uint m_constant: 1; - uint m_volatile: 1; - uint m_reference: 1; - uint m_functionPointer: 1; - uint m_indirections: 6; - uint m_padding: 22; - }; - }; + struct TypeInfo_flags { + uint m_constant: 1; + uint m_volatile: 1; + uint m_reference: 1; + uint m_functionPointer: 1; + uint m_indirections: 6; + inline bool equals(TypeInfo_flags other) { + return m_constant == other.m_constant + && m_volatile == other.m_volatile + && m_reference == other.m_reference + && m_functionPointer == other.m_functionPointer + && m_indirections == other.m_indirections; + } + } m_flags {0, 0, 0, 0, 0}; QStringList m_qualifiedName; QStringList m_arrayElements; QList m_arguments; - bool m_rvalue_reference; + bool m_rvalue_reference { false }; }; class _CodeModelItem: public QSharedData diff --git a/generator/parser/codemodel_fwd.h b/generator/parser/codemodel_fwd.h index 35e73ed0..55bf3965 100644 --- a/generator/parser/codemodel_fwd.h +++ b/generator/parser/codemodel_fwd.h @@ -62,7 +62,7 @@ class _TemplateParameterModelItem; class _TypeAliasModelItem; class _VariableModelItem; class _MemberModelItem; -class TypeInfo; +struct TypeInfo; typedef CodeModelPointer<_ArgumentModelItem> ArgumentModelItem; typedef CodeModelPointer<_ClassModelItem> ClassModelItem; diff --git a/generator/parser/lexer.cpp b/generator/parser/lexer.cpp index c5c70820..672a3206 100644 --- a/generator/parser/lexer.cpp +++ b/generator/parser/lexer.cpp @@ -774,8 +774,7 @@ void Lexer::scan_EOF() void Lexer::scan_invalid_input() { QString errmsg("invalid input: %1"); - errmsg.arg(int(*cursor)); - reportError(errmsg); + reportError(errmsg.arg(int(*cursor))); ++cursor; } diff --git a/generator/parser/parser.cpp b/generator/parser/parser.cpp index a9dc0bd8..429a02d1 100644 --- a/generator/parser/parser.cpp +++ b/generator/parser/parser.cpp @@ -2387,10 +2387,8 @@ bool Parser::parsePtrToMember(PtrToMemberAST *&node) std::size_t start = token_stream.cursor(); - std::size_t global_scope = 0; if (token_stream.lookAhead() == Token_scope) { - global_scope = token_stream.cursor(); token_stream.nextToken(); } diff --git a/generator/parser/rpp/pp-iterator.h b/generator/parser/rpp/pp-iterator.h index 90d31b0f..230e3c89 100644 --- a/generator/parser/rpp/pp-iterator.h +++ b/generator/parser/rpp/pp-iterator.h @@ -43,6 +43,7 @@ #define PP_ITERATOR_H #include +#include // Q_CC_MSVC namespace rpp { @@ -71,6 +72,7 @@ class pp_output_iterator explicit pp_output_iterator(std::string &__result): _M_result (__result) {} +#ifdef Q_CC_MSVC // this copy constructor was needed for Visual Studio 2012 release builds: inline pp_output_iterator &operator=(const pp_output_iterator& other) { @@ -78,6 +80,7 @@ class pp_output_iterator _M_result = other._M_result; return *this; } +#endif inline pp_output_iterator &operator=(typename _Container::const_reference __v) { diff --git a/generator/parser/rxx_allocator.h b/generator/parser/rxx_allocator.h index 87ec7e81..2081bfe5 100644 --- a/generator/parser/rxx_allocator.h +++ b/generator/parser/rxx_allocator.h @@ -102,11 +102,14 @@ template class rxx_allocator { (_M_current_block + _M_current_index); _M_current_index += bytes; + // Hack for modern C++ to get aligned allocations + _M_current_index += 7U; + _M_current_index &= ~(7U); return p; } - void deallocate(pointer __p, size_type __n) {} + void deallocate(pointer /*__p*/, size_type /*__n*/) {} size_type max_size() const { return size_type(-1) / sizeof(_Tp); } @@ -118,7 +121,7 @@ template class rxx_allocator { typedef rxx_allocator<_Tp1> other; }; - template rxx_allocator(const rxx_allocator<_Tp1> &__o) {} + template rxx_allocator(const rxx_allocator<_Tp1> &/*__o*/) {} private: size_type _M_block_index; diff --git a/generator/shellgenerator.cpp b/generator/shellgenerator.cpp index cad6a483..5ab4ffad 100644 --- a/generator/shellgenerator.cpp +++ b/generator/shellgenerator.cpp @@ -129,7 +129,6 @@ void ShellGenerator::writeFunctionArguments(QTextStream &s, Option option, int numArguments) { - const AbstractMetaClass* owner = meta_function->ownerClass(); const AbstractMetaArgumentList &arguments = meta_function->arguments(); if (numArguments < 0) numArguments = arguments.size(); @@ -452,4 +451,4 @@ TypeSystem::Ownership ShellGenerator::writeOwnershipTemplate(QTextStream & s, co s << "PythonQtNewOwnerOfThis<"; } return ownership; -} \ No newline at end of file +} diff --git a/generator/shellimplgenerator.cpp b/generator/shellimplgenerator.cpp index e543de47..e6f13715 100644 --- a/generator/shellimplgenerator.cpp +++ b/generator/shellimplgenerator.cpp @@ -53,12 +53,14 @@ QString ShellImplGenerator::fileNameForClass(const AbstractMetaClass *meta_class return QString("PythonQtWrapper_%1.cpp").arg(meta_class->name()); } +/* UNUSED static bool include_less_than(const Include &a, const Include &b) { return a.name < b.name; } +*/ -static void writeHelperCode(QTextStream &s, const AbstractMetaClass *) +static void writeHelperCode(QTextStream &, const AbstractMetaClass *) { } diff --git a/generator/typesystem.cpp b/generator/typesystem.cpp index 4308a7cc..c983348b 100644 --- a/generator/typesystem.cpp +++ b/generator/typesystem.cpp @@ -49,6 +49,7 @@ #include #include +#include // Q_FALLTHROUGH QString strings_Object = QLatin1String("Object"); QString strings_String = QLatin1String("String"); @@ -482,12 +483,12 @@ bool Handler::startElement(const QString &, const QString &n, case StackElement::ValueTypeEntry: attributes["force-abstract"] = QString("no"); attributes["deprecated"] = QString("no"); - // fall throooough + Q_FALLTHROUGH(); case StackElement::InterfaceTypeEntry: attributes["default-superclass"] = m_defaultSuperclass; attributes["polymorphic-id-expression"] = QString(); attributes["delete-in-main-thread"] = QString("no"); - // fall through + Q_FALLTHROUGH(); case StackElement::NamespaceTypeEntry: attributes["java-name"] = QString(); attributes["package"] = m_defaultPackage; @@ -840,9 +841,7 @@ bool Handler::startElement(const QString &, const QString &n, } QString name = attributes["name"]; - bool added = false; if (!name.isEmpty()) { - added = true; m_current_enum->addEnumValueRejection(name); } @@ -2031,4 +2030,4 @@ QByteArray TypeSystem::normalizedSignature(const char* signature) result.replace("quint64", "ulonglong"); result.replace("QStringList", "QStringList"); return result; -} \ No newline at end of file +} diff --git a/generator/typesystem.h b/generator/typesystem.h index b332bb96..56eca93a 100644 --- a/generator/typesystem.h +++ b/generator/typesystem.h @@ -133,7 +133,7 @@ namespace TypeSystem { //! A better normalized signature, which takes care of PODs with the same name QByteArray normalizedSignature(const char* signature); -}; +} struct ReferenceCount { diff --git a/src/PythonQt.cpp b/src/PythonQt.cpp index bbe6b819..a14609a8 100644 --- a/src/PythonQt.cpp +++ b/src/PythonQt.cpp @@ -58,6 +58,12 @@ #include +#if PY_MINOR_VERSION >= 10 +#include +#else +#include +#endif + #include PythonQt* PythonQt::_self = nullptr; @@ -250,12 +256,18 @@ void PythonQt::init(int flags, const QByteArray& pythonQtModuleName) PyObject* qtNamespace = PythonQt::priv()->getClassInfo("Qt")->pythonQtClassWrapper(); const char* names[16] = {"SIGNAL", "SLOT", "qAbs", "qBound","qDebug","qWarning","qCritical","qFatal" ,"qFuzzyCompare", "qMax","qMin","qRound","qRound64","qVersion","qrand","qsrand"}; - for (unsigned int i = 0;i<16; i++) { + for (unsigned int i = 0; i < sizeof(names) / sizeof(names[0]); i++) { PyObject* obj = PyObject_GetAttrString(qtNamespace, names[i]); if (obj) { - PyModule_AddObject(pack, names[i], obj); - Py_INCREF(obj); - PyModule_AddObject(pack2, names[i], obj); + if (PyModule_AddObject(pack, names[i], obj) < 0) { + std::cerr << "failed to add " << names[i] << " to QtCore\n"; + } else { + Py_INCREF(obj); + } + if(PyModule_AddObject(pack2, names[i], obj) < 0) { + Py_DECREF(obj); + std::cerr << "failed to add " << names[i] << " to Qt\n"; + } } else { std::cerr << "method not found " << names[i] << std::endl; } @@ -275,11 +287,14 @@ void PythonQt::init(int flags, const QByteArray& pythonQtModuleName) "QtSystemMsg" }; - for (auto i = 0u; ipriv()->pythonQtModule().addObject("Debug", _self->priv()->_debugAPI); @@ -400,10 +415,7 @@ PythonQtPrivate::~PythonQtPrivate() { _defaultImporter = nullptr; { - QHashIterator i(_knownClassInfos); - while (i.hasNext()) { - delete i.next().value(); - } + qDeleteAll(_knownClassInfos); } PythonQtMethodInfo::cleanupCachedMethodInfos(); @@ -441,6 +453,8 @@ PythonQtObjectPtr PythonQtPrivate::checkAndRunCoroutine(const PythonQtObjectPtr& Py_XDECREF(methodName); } Py_XDECREF(args); +#else + Q_UNUSED(object) #endif return result; } @@ -551,7 +565,9 @@ void PythonQtPrivate::registerClass(const QMetaObject* metaobject, const char* p PyObject* classWrapper = info->pythonQtClassWrapper(); // AddObject steals a reference, so we need to INCREF Py_INCREF(classWrapper); - PyModule_AddObject(module, info->className(), classWrapper); + if (PyModule_AddObject(module, info->className(), classWrapper) < 0) { + Py_DECREF(classWrapper); + } } if (first) { first = false; @@ -584,13 +600,17 @@ void PythonQtPrivate::createPythonQtClassWrapper(PythonQtClassInfo* info, const PythonQtClassInfo* outerClassInfo = lookupClassInfoAndCreateIfNotPresent(outerClass); outerClassInfo->addNestedClass(info); } else { - PyModule_AddObject(pack, info->className(), pyobj); + if (PyModule_AddObject(pack, info->className(), pyobj) == 0) { + // since PyModule_AddObject steals the reference, we need a incref once more... + Py_INCREF(pyobj); + } } if (!module && package && strncmp(package, "Qt", 2) == 0) { - // since PyModule_AddObject steals the reference, we need a incref once more... - Py_INCREF(pyobj); // put all qt objects into Qt as well - PyModule_AddObject(packageByName("Qt"), info->className(), pyobj); + if (PyModule_AddObject(packageByName("Qt"), info->className(), pyobj) == 0) { + // since PyModule_AddObject steals the reference, we need a incref once more... + Py_INCREF(pyobj); + } } info->setPythonQtClassWrapper(pyobj); } @@ -803,6 +823,7 @@ PythonQtClassWrapper* PythonQtPrivate::createNewPythonQtClassWrapper(PythonQtCla Py_DECREF(moduleName); Py_DECREF(baseClasses); Py_DECREF(typeDict); + Py_DECREF(moduleName); Py_DECREF(args); Py_DECREF(className); @@ -837,6 +858,7 @@ PyObject* PythonQtPrivate::createNewPythonQtEnumWrapper(const char* enumName, Py Py_DECREF(module); Py_DECREF(baseClasses); + Py_DECREF(module); Py_DECREF(typeDict); Py_DECREF(args); Py_DECREF(className); @@ -1110,7 +1132,10 @@ PythonQtObjectPtr PythonQt::createUniqueModule() void PythonQt::addObject(PyObject* object, const QString& name, QObject* qObject) { if (PyModule_Check(object)) { - PyModule_AddObject(object, QStringToPythonCharPointer(name), _p->wrapQObject(qObject)); + auto pyobj = _p->wrapQObject(qObject); + if (PyModule_AddObject(object, QStringToPythonCharPointer(name), pyobj) < 0) { + Py_DECREF(pyobj); + } } else if (PyDict_Check(object)) { PyDict_SetItemString(object, QStringToPythonCharPointer(name), _p->wrapQObject(qObject)); } else { @@ -1121,7 +1146,10 @@ void PythonQt::addObject(PyObject* object, const QString& name, QObject* qObject void PythonQt::addVariable(PyObject* object, const QString& name, const QVariant& v) { if (PyModule_Check(object)) { - PyModule_AddObject(object, QStringToPythonCharPointer(name), PythonQtConv::QVariantToPyObject(v)); + auto pyobj = PythonQtConv::QVariantToPyObject(v); + if (PyModule_AddObject(object, QStringToPythonCharPointer(name), pyobj) < 0) { + Py_DECREF(pyobj); + } } else if (PyDict_Check(object)) { PyDict_SetItemString(object, QStringToPythonCharPointer(name), PythonQtConv::QVariantToPyObject(v)); } else { diff --git a/src/PythonQtClassInfo.cpp b/src/PythonQtClassInfo.cpp index efd5487b..9c505ae1 100644 --- a/src/PythonQtClassInfo.cpp +++ b/src/PythonQtClassInfo.cpp @@ -131,11 +131,11 @@ bool PythonQtClassInfo::lookForPropertyAndCache(const char* memberName) if (!_meta) return false; bool found = false; - bool nameMapped = false; const char* attributeName = memberName; // look for properties int i = _meta->indexOfProperty(attributeName); #ifdef PYTHONQT_SUPPORT_NAME_PROPERTY + bool nameMapped = false; if (i==-1) { // try to map name to objectName if (qstrcmp(attributeName, "name")==0) { @@ -154,9 +154,11 @@ bool PythonQtClassInfo::lookForPropertyAndCache(const char* memberName) if (i!=-1) { PythonQtMemberInfo newInfo(_meta->property(i)); _cachedMembers.insert(attributeName, newInfo); +#ifdef PYTHONQT_SUPPORT_NAME_PROPERTY if (nameMapped) { _cachedMembers.insert(memberName, newInfo); } +#endif #ifdef PYTHONQT_DEBUG std::cout << "caching property " << memberName << " on " << _meta->className() << std::endl; #endif @@ -1073,14 +1075,13 @@ bool PythonQtClassInfo::supportsRichCompare() //------------------------------------------------------------------------- -PythonQtMemberInfo::PythonQtMemberInfo( PythonQtSlotInfo* info ) +PythonQtMemberInfo::PythonQtMemberInfo( PythonQtSlotInfo* info ) : _slot(info) { if (info->metaMethod()->methodType() == QMetaMethod::Signal) { _type = Signal; } else { _type = Slot; } - _slot = info; _enumValue = nullptr; _pythonType = nullptr; } diff --git a/src/PythonQtClassWrapper.cpp b/src/PythonQtClassWrapper.cpp index 7887538c..20533830 100644 --- a/src/PythonQtClassWrapper.cpp +++ b/src/PythonQtClassWrapper.cpp @@ -110,14 +110,11 @@ static Py_ssize_t PythonQtInstanceWrapper_length(PythonQtInstanceWrapper* wrappe static int PythonQtInstanceWrapper_setitem(PyObject* self, PyObject* index, PyObject* value) { PythonQtInstanceWrapper* wrapper = (PythonQtInstanceWrapper*)self; - PythonQtMemberInfo opSlot; - bool isSetItem = false; - if (value) { - isSetItem = true; - opSlot = wrapper->classInfo()->member("__setitem__"); - } else { - opSlot = wrapper->classInfo()->member("__delitem__"); - } + bool isSetItem = value; + PythonQtMemberInfo opSlot = isSetItem ? + wrapper->classInfo()->member("__setitem__") + : wrapper->classInfo()->member("__delitem__"); + if (opSlot._type == PythonQtMemberInfo::Slot) { PyObject* args = PyTuple_New(isSetItem?2:1); Py_INCREF(index); @@ -394,7 +391,7 @@ static PyObject *PythonQtClassWrapper_help(PythonQtClassWrapper* type) PyObject *PythonQtClassWrapper_delete(PythonQtClassWrapper *type, PyObject *args) { - Q_UNUSED(type); + Q_UNUSED(type) Py_ssize_t argc = PyTuple_Size(args); if (argc>0) { @@ -408,7 +405,7 @@ PyObject *PythonQtClassWrapper_delete(PythonQtClassWrapper *type, PyObject *args PyObject *PythonQtClassWrapper_inherits(PythonQtClassWrapper *type, PyObject *args) { - Q_UNUSED(type); + Q_UNUSED(type) PythonQtInstanceWrapper* wrapper = nullptr; char *name = nullptr; if (!PyArg_ParseTuple(args, "O!s:PythonQtClassWrapper.inherits",&PythonQtInstanceWrapper_Type, &wrapper, &name)) { diff --git a/src/PythonQtConversion.cpp b/src/PythonQtConversion.cpp index 29876a81..3c209594 100644 --- a/src/PythonQtConversion.cpp +++ b/src/PythonQtConversion.cpp @@ -627,7 +627,7 @@ void* PythonQtConv::ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& i { // check for enum case if (info.enumWrapper) { - unsigned int val; + unsigned int val = 0; ok = false; if ((PyObject*)obj->ob_type == info.enumWrapper) { // we have a exact enum type match: diff --git a/src/PythonQtCppWrapperFactory.h b/src/PythonQtCppWrapperFactory.h index e4bf2012..d3cf4f6d 100644 --- a/src/PythonQtCppWrapperFactory.h +++ b/src/PythonQtCppWrapperFactory.h @@ -55,6 +55,7 @@ A factory can be added to PythonQt by PythonQt::addCppWrapperFactory(). */ class PYTHONQT_EXPORT PythonQtCppWrapperFactory { + Q_DISABLE_COPY(PythonQtCppWrapperFactory) public: PythonQtCppWrapperFactory() {}; virtual ~PythonQtCppWrapperFactory() {}; @@ -68,9 +69,10 @@ class PYTHONQT_EXPORT PythonQtCppWrapperFactory //! Python with other means than PythonQt/QObjects. class PYTHONQT_EXPORT PythonQtForeignWrapperFactory { + Q_DISABLE_COPY(PythonQtForeignWrapperFactory) public: - PythonQtForeignWrapperFactory() {}; - virtual ~PythonQtForeignWrapperFactory() {}; + PythonQtForeignWrapperFactory() {} + virtual ~PythonQtForeignWrapperFactory() {} //! create a Python object (with new reference count), wrapping the given \p ptr as class of type \p classname //! Return NULL (and not Py_None) if the object could not be wrapped. diff --git a/src/PythonQtImportFileInterface.h b/src/PythonQtImportFileInterface.h index a6d5026d..ea8afbb1 100644 --- a/src/PythonQtImportFileInterface.h +++ b/src/PythonQtImportFileInterface.h @@ -50,10 +50,11 @@ //! Defines an abstract interface to file access for the Python import statement. //! see PythonQt::setImporter() class PythonQtImportFileInterface { - + Q_DISABLE_COPY(PythonQtImportFileInterface) public: // get rid of warnings virtual ~PythonQtImportFileInterface() {} + PythonQtImportFileInterface() {} //! read the given file as byte array, without doing any linefeed translations virtual QByteArray readFileAsBytes(const QString& filename) = 0; @@ -78,7 +79,7 @@ class PythonQtImportFileInterface { //! called by PythonQt after successful import to allow //! recording of imports - virtual void importedModule(const QString& /*module*/) {}; + virtual void importedModule(const QString& /*module*/) {} }; diff --git a/src/PythonQtImporter.cpp b/src/PythonQtImporter.cpp index 9afa3f71..dfcfcb16 100644 --- a/src/PythonQtImporter.cpp +++ b/src/PythonQtImporter.cpp @@ -579,6 +579,8 @@ void PythonQtImport::writeCompiledModule(PyCodeObject *co, const QString& filena #endif #ifdef PY3K PyMarshal_WriteLongToFile(sourceSize, fp, Py_MARSHAL_VERSION); +#else + Q_UNUSED(sourceSize) #endif #if PY_VERSION_HEX < 0x02040000 PyMarshal_WriteObjectToFile((PyObject *)co, fp); @@ -650,7 +652,7 @@ PythonQtImport::unmarshalCode(const QString& path, const QByteArray& data, time_ #ifdef PY3K // Python 3 also stores the size of the *.py file, but we ignore it for now int sourceSize = getLong((unsigned char *)buf + 8); - Q_UNUSED(sourceSize); + Q_UNUSED(sourceSize) // read the module code = PyMarshal_ReadObjectFromString(buf + 12, size - 12); #else @@ -803,6 +805,8 @@ PythonQtImport::getModuleCode(PythonQtImporter *self, const char* fullname, QStr cachemodpath = modpath; modpath = getSourceFilename(modpath); } +#else + Q_UNUSED(cachemodpath) #endif } return code; @@ -913,13 +917,17 @@ void PythonQtImport::init() Py_INCREF(PythonQtImportError); if (PyModule_AddObject(mod, "PythonQtImportError", - PythonQtImportError) < 0) + PythonQtImportError) < 0) { + Py_DECREF(PythonQtImportError); return; + } Py_INCREF(&PythonQtImporter_Type); if (PyModule_AddObject(mod, "PythonQtImporter", - (PyObject *)&PythonQtImporter_Type) < 0) + (PyObject *)&PythonQtImporter_Type) < 0) { + Py_DECREF(&PythonQtImporter_Type); return; + } // set our importer into the path_hooks to handle all path on sys.path PyObject* classobj = PyDict_GetItemString(PyModule_GetDict(mod), "PythonQtImporter"); diff --git a/src/PythonQtProperty.cpp b/src/PythonQtProperty.cpp index 09e020e3..b63ebe3b 100644 --- a/src/PythonQtProperty.cpp +++ b/src/PythonQtProperty.cpp @@ -153,6 +153,7 @@ PyObject* PythonQtProperty_getter(PyObject* object, PyObject* func) PyObject* PythonQtProperty_call(PyObject* object, PyObject* args, PyObject* kw) { + Q_UNUSED(kw) if (PyTuple_Size(args) == 1) { PyObject *func = PyTuple_GetItem(args, 0); return PythonQtProperty_getter(object, func); diff --git a/src/PythonQtPythonInclude.h b/src/PythonQtPythonInclude.h index e28b8dee..ed6c6998 100644 --- a/src/PythonQtPythonInclude.h +++ b/src/PythonQtPythonInclude.h @@ -33,12 +33,33 @@ #ifndef __PythonQtPythonInclude_h #define __PythonQtPythonInclude_h +// Undefine macros that Python.h defines to avoid redefinition warning. +#ifdef _POSIX_C_SOURCE +# undef _POSIX_C_SOURCE +#endif + +#ifdef _POSIX_THREADS +# undef _POSIX_THREADS +#endif + +#ifdef _XOPEN_SOURCE +# undef _XOPEN_SOURCE +#endif + // Undefine Qt keywords that conflict with Python headers #ifdef slots #undef slots #define PYTHONQT_RESTORE_KEYWORDS #endif +//From https://github.com/boostorg/python/pull/253 +// Python.h defines a macro with hypot name, what breaks libstdc++ math header +// that it tries to include afterwards. +# if defined(__MINGW32__) +# include +# include +# endif + // // Use the real python debugging library if it is provided. // Otherwise use the "documented" trick involving checking for _DEBUG diff --git a/src/PythonQtSignal.cpp b/src/PythonQtSignal.cpp index 87bc8a7f..16c64e1f 100644 --- a/src/PythonQtSignal.cpp +++ b/src/PythonQtSignal.cpp @@ -66,6 +66,9 @@ PyObject *PythonQtSignalFunction_Call(PyObject *func, PyObject *args, PyObject * PyObject *PythonQtSignalFunction_tpNew(PyTypeObject *subtype, PyObject *args, PyObject *kwds) { + Q_UNUSED(subtype) + Q_UNUSED(args) + Q_UNUSED(kwds) return PythonQtSignalFunction_New(nullptr, nullptr, nullptr); } @@ -181,6 +184,7 @@ static PyMemberDef meth_members[] = { int PythonQtSignalFunction_init(PyObject *object, PyObject *args, PyObject *kw) { + Q_UNUSED(kw) PythonQtSignalFunctionObject* self = (PythonQtSignalFunctionObject*)object; self->_dynamicInfo = new PythonQtDynamicSignalInfo(); diff --git a/src/PythonQtSignalReceiver.cpp b/src/PythonQtSignalReceiver.cpp index 13c3d1a2..212948da 100644 --- a/src/PythonQtSignalReceiver.cpp +++ b/src/PythonQtSignalReceiver.cpp @@ -241,7 +241,7 @@ bool PythonQtSignalReceiver::removeSignalHandler(const char* signal, PyObject* c } } } - if ((foundCount>0) && (sigId == _destroyedSignal1Id) || (sigId == _destroyedSignal2Id)) { + if ((foundCount>0) && ((sigId == _destroyedSignal1Id) || (sigId == _destroyedSignal2Id))) { _destroyedSignalCount -= foundCount; if (_destroyedSignalCount==0) { // make ourself child of QObject again, to get deleted when the object gets deleted diff --git a/src/PythonQtSlot.cpp b/src/PythonQtSlot.cpp index 045d7c2d..13d21308 100644 --- a/src/PythonQtSlot.cpp +++ b/src/PythonQtSlot.cpp @@ -490,9 +490,10 @@ PythonQtSlotFunction_GetSelf(PyObject *op) /* Methods (the standard built-in methods, that is) */ static void -meth_dealloc(PythonQtSlotFunctionObject *m) +meth_dealloc(PyObject *o) { - PyObject_GC_UnTrack(m); + PyObject_GC_UnTrack(o); + auto m = static_cast(static_cast(o)); Py_XDECREF(m->m_self); Py_XDECREF(m->m_module); m->m_self = (PyObject *)pythonqtslot_free_list; @@ -525,7 +526,7 @@ meth_get__doc__(PythonQtSlotFunctionObject * m, void * /*closure*/) if (!names.at(i - 1).isEmpty()) { doc += names.at(i - 1); } else { - doc += QString('a' + i - firstArgOffset); + doc += QString('a' + i - firstArgOffset).toLatin1(); } } doc += ")"; @@ -792,6 +793,7 @@ meth_richcompare(PythonQtSlotFunctionObject *a, PythonQtSlotFunctionObject *b, i static PyObject* meth_descr_get(PyObject *descr, PyObject *obj, PyObject* type) { + Q_UNUSED(type) if (PythonQtSlotFunction_Check(descr)) { PythonQtSlotFunctionObject *slotObj = (PythonQtSlotFunctionObject*)descr; return PythonQtSlotFunction_New(slotObj->m_ml, obj, NULL); diff --git a/src/PythonQtSlotDecorator.cpp b/src/PythonQtSlotDecorator.cpp index 8e9ea3e5..f8933b97 100644 --- a/src/PythonQtSlotDecorator.cpp +++ b/src/PythonQtSlotDecorator.cpp @@ -85,6 +85,7 @@ int PythonQtSlotDecorator_init(PyObject *object, PyObject *args, PyObject *kw) PyObject* PythonQtSlotDecorator_call(PyObject* object, PyObject* args, PyObject* kw) { + Q_UNUSED(kw) PythonQtSlotDecorator* self = (PythonQtSlotDecorator*)object; PyObject* function = PyTuple_GetItem(args, 0); diff --git a/src/PythonQtStdIn.cpp b/src/PythonQtStdIn.cpp index 8db0d252..056127b2 100644 --- a/src/PythonQtStdIn.cpp +++ b/src/PythonQtStdIn.cpp @@ -55,7 +55,7 @@ static PyObject *PythonQtStdInRedirect_new(PyTypeObject *type, PyObject * /*args static PyObject *PythonQtStdInRedirect_readline(PyObject * self, PyObject * args) { - Q_UNUSED(args); + Q_UNUSED(args) PythonQtStdInRedirect* s = (PythonQtStdInRedirect*)self; QString string; if (s->_cb) { diff --git a/src/PythonQtThreadSupport.h b/src/PythonQtThreadSupport.h index b1666ce0..f57e821d 100644 --- a/src/PythonQtThreadSupport.h +++ b/src/PythonQtThreadSupport.h @@ -39,7 +39,7 @@ */ //---------------------------------------------------------------------------------- - +#include //Q_DISABLE_COPY #include "PythonQtPythonInclude.h" #include "PythonQtSystem.h" @@ -103,6 +103,7 @@ class PythonQtGILScope //! from Python code. class PythonQtThreadStateSaver { + Q_DISABLE_COPY(PythonQtThreadStateSaver) public: PythonQtThreadStateSaver() { save(); diff --git a/src/src.pri b/src/src.pri index c3fe829e..a455a351 100644 --- a/src/src.pri +++ b/src/src.pri @@ -2,8 +2,15 @@ DEFINES += PYTHONQT_EXPORTS INCLUDEPATH += $$PWD +CONFIG += c++11 + +gcc:!no_warn { + !clang:QMAKE_CXXFLAGS += -Werror -Wno-error=missing-field-initializers + clang:QMAKE_CXXFLAGS += -Wno-error=sometimes-uninitialized +} + # This was needed to work around "number of sections exceeded object file format limit" linker error -win32-msvc*: QMAKE_CXXFLAGS += /bigobj +win32-msvc*:QMAKE_CXXFLAGS += /bigobj win32-g++: QMAKE_CXXFLAGS += -Wa,-mbig-obj HEADERS += \ diff --git a/src/src.pro b/src/src.pro index 44d96ec8..44774ec4 100644 --- a/src/src.pro +++ b/src/src.pro @@ -13,9 +13,13 @@ DESTDIR = ../lib CONFIG += qt CONFIG -= flat +mingw:QMAKE_CXXFLAGS+=-Wa,-mbig-obj # allow to choose static linking through the environment variable PYTHONQT_STATIC +isEmpty(PYTHONQT_STATIC) { PYTHONQT_STATIC = $$(PYTHONQT_STATIC) +} + isEmpty(PYTHONQT_STATIC) { CONFIG += dll } else { @@ -44,12 +48,12 @@ include($${PYTHONQT_GENERATED_PATH}/com_trolltech_qt_gui_builtin/com_trolltech_q unix { CONFIG += create_pc create_prl no_install_prl - QMAKE_PKGCONFIG_NAME = PythonQt-Qt$${QT_MAJOR_VERSION}-Python$${PYTHON_VERSION} + QMAKE_PKGCONFIG_NAME = $${TARGET} QMAKE_PKGCONFIG_DESCRIPTION = Dynamic Python binding for the Qt framework QMAKE_PKGCONFIG_PREFIX = $$INSTALLBASE QMAKE_PKGCONFIG_LIBDIR = $$target.path QMAKE_PKGCONFIG_INCDIR = $$headers.path - QMAKE_PKGCONFIG_INCDIR += $$PREFIX/include/PythonQt5 + QMAKE_PKGCONFIG_INCDIR += ${prefix}/include/PythonQt5 QMAKE_PKGCONFIG_VERSION = $$VERSION } diff --git a/tests/PythonQtTestMain.cpp b/tests/PythonQtTestMain.cpp index 8b498ab4..006d5411 100644 --- a/tests/PythonQtTestMain.cpp +++ b/tests/PythonQtTestMain.cpp @@ -69,13 +69,13 @@ int main(int argc, char *argv[]) PythonQtTestCleanup cleanup; failCount += QTest::qExec(&cleanup, argc, argv); - if (failCount>0) { + if (failCount) { std::cerr << "Tests failed: " << failCount << std::endl; } else { std::cout << "All tests passed successfully." << std::endl; } #endif - return failCount; + return failCount != 0 ? EXIT_FAILURE : EXIT_SUCCESS; } diff --git a/tests/PythonQtTests.h b/tests/PythonQtTests.h index c511fc57..d6ef486c 100644 --- a/tests/PythonQtTests.h +++ b/tests/PythonQtTests.h @@ -162,7 +162,7 @@ class PythonQtTestApiHelper : public QObject , public PythonQtImportFileInterfac virtual QDateTime lastModifiedDate(const QString& filename); - virtual bool isEggArchive(const QString& filename) { return false; } + virtual bool isEggArchive(const QString&) { return false; } public Q_SLOTS: @@ -328,13 +328,13 @@ class PQCppObjectQFlagOnlyDecorator : public QObject { class PQUnknownValueObject { public: - PQUnknownValueObject() {}; + PQUnknownValueObject() {} }; class PQUnknownButRegisteredValueObject { public: - PQUnknownButRegisteredValueObject() {}; + PQUnknownButRegisteredValueObject() {} }; //! test the calling of Q_SLOTS @@ -379,15 +379,15 @@ class PythonQtTestSlotCallingHelper : public QObject bool runScript(const char* script, int expectedOverload = -1); - Q_PROPERTY(int intProp READ intProp WRITE setIntProp); - Q_PROPERTY(float floatProp READ floatProp WRITE setFloatProp); - Q_PROPERTY(QVariantList variantListProp READ variantListProp WRITE setVariantListProp); - Q_PROPERTY(QVariantMap variantMapProp READ variantMapProp WRITE setVariantMapProp); - Q_PROPERTY(QVariant variantProp READ variantProp WRITE setVariantProp); - Q_PROPERTY(QObject* qObjectProp READ qObjectProp WRITE setQObjectProp); - Q_PROPERTY(QList qObjectListProp READ qObjectListProp WRITE setQObjectListProp); + Q_PROPERTY(int intProp READ intProp WRITE setIntProp) + Q_PROPERTY(float floatProp READ floatProp WRITE setFloatProp) + Q_PROPERTY(QVariantList variantListProp READ variantListProp WRITE setVariantListProp) + Q_PROPERTY(QVariantMap variantMapProp READ variantMapProp WRITE setVariantMapProp) + Q_PROPERTY(QVariant variantProp READ variantProp WRITE setVariantProp) + Q_PROPERTY(QObject* qObjectProp READ qObjectProp WRITE setQObjectProp) + Q_PROPERTY(QList qObjectListProp READ qObjectListProp WRITE setQObjectListProp) - Q_PROPERTY(QSize sizeProp READ sizeProp WRITE setSizeProp); + Q_PROPERTY(QSize sizeProp READ sizeProp WRITE setSizeProp) public: int intProp() const { _called = true; return _intProp; } diff --git a/tests/tests.pro b/tests/tests.pro index 1cc4e006..340423c8 100644 --- a/tests/tests.pro +++ b/tests/tests.pro @@ -7,8 +7,17 @@ TARGET = PythonQtTest TEMPLATE = app DESTDIR = ../lib +QMAKE_RPATHDIR += $$DESTDIR QT += testlib opengl +CONFIG += testcase cmdline exceptions testcase_no_bundle no_testcase_installs + +#Workaround for MinGW build. Qt incorrectly sets it to empty string on Win32 for bash +mingw: TEST_TARGET_DIR = . + +DEFINES += QT_NO_CAST_TO_ASCII + +gcc: QMAKE_CXXFLAGS += -Wpedantic contains(QT_MAJOR_VERSION, 5) { QT += widgets