summaryrefslogtreecommitdiffstats
path: root/src/tools
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@qt.io>2024-02-28 14:32:26 +0100
committerMarc Mutz <marc.mutz@qt.io>2024-02-29 14:56:11 +0100
commit1c8884fc277c5916a420a3c14de68547a391f9fc (patch)
treedbf5849747870c4dc844fbcfaf84ac54b92ba9b6 /src/tools
parente60e2bf7655c12a1a923665fcb366b9f462276d3 (diff)
synqt.cpp: scan for and reject #pragma once
In 2022¹, we gave ourselves the rule to allow #pragma once only in non-installed headers (examples, tools, snippets, ...), because the same installed header may reside in different places in the filesystem and #pragma once would treat these as separate headers, causing multiple-definition errors. Recently, the question came up: "What constitutes a public header?" Non-_p.h headers in e.g. src/plugins/ muddy the waters here a bit. Since #pragma once is forbidden in installed headers, I had the idea to use it to indicate non-installed headers. This patch enables use of #pragma once as a static assertion to that effect, should we so choose. ¹ https://lists.qt-project.org/pipermail/development/2022-October/043121.html Pick-to: 6.7 6.6 6.5 Fixes: QTBUG-122813 Change-Id: I3b5beef72e154cf5bf1ccd4b6f02df9680609e43 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> Reviewed-by: Ivan Solovev <ivan.solovev@qt.io> Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/syncqt/main.cpp18
1 files changed, 15 insertions, 3 deletions
diff --git a/src/tools/syncqt/main.cpp b/src/tools/syncqt/main.cpp
index 876860a187..be6d442a6f 100644
--- a/src/tools/syncqt/main.cpp
+++ b/src/tools/syncqt/main.cpp
@@ -43,9 +43,10 @@ enum HeaderChecks {
PrivateHeaderChecks = 2, /* Checks if the public header includes a private header */
IncludeChecks = 4, /* Checks if the real header file but not an alias is included */
WeMeantItChecks = 8, /* Checks if private header files contains 'We meant it' disclaimer */
- CriticalChecks = PrivateHeaderChecks, /* Checks that lead to the fatal error of the sync
- process */
- AllChecks = NamespaceChecks | PrivateHeaderChecks | IncludeChecks | WeMeantItChecks,
+ PragmaOnceChecks = 16,
+ /* Checks that lead to the fatal error of the sync process: */
+ CriticalChecks = PrivateHeaderChecks | PragmaOnceChecks,
+ AllChecks = NamespaceChecks | CriticalChecks | IncludeChecks | WeMeantItChecks,
};
constexpr int LinkerScriptCommentAlignment = 55;
@@ -1084,6 +1085,9 @@ public:
static const std::regex MacroRegex("^\\s*#.*");
// The regex's bellow check line for known pragmas:
+ //
+ // - 'once' is not allowed in installed headers, so error out.
+ //
// - 'qt_sync_skip_header_check' avoid any header checks.
//
// - 'qt_sync_stop_processing' stops the header proccesing from a moment when pragma is
@@ -1111,6 +1115,7 @@ public:
//
// - 'qt_no_master_include' indicates that syncqt should avoid including this header
// files into the module master header file.
+ static const std::regex OnceRegex(R"(^#\s*pragma\s+once$)");
static const std::regex SkipHeaderCheckRegex("^#\\s*pragma qt_sync_skip_header_check$");
static const std::regex StopProcessingRegex("^#\\s*pragma qt_sync_stop_processing$");
static const std::regex SuspendProcessingRegex("^#\\s*pragma qt_sync_suspend_processing$");
@@ -1298,6 +1303,13 @@ public:
} else if (std::regex_match(buffer, match, DeprecatesPragmaRegex)) {
m_deprecatedHeaders[match[1].str()] =
m_commandLineArgs->moduleName() + '/' + m_currentFilename;
+ } else if (std::regex_match(buffer, OnceRegex)) {
+ if (!(skipChecks & PragmaOnceChecks)) {
+ faults |= PragmaOnceChecks;
+ error() << "\"#pragma once\" is not allowed in installed header files: "
+ "https://lists.qt-project.org/pipermail/development/2022-October/043121.html"
+ << std::endl;
+ }
} else if (std::regex_match(buffer, match, IncludeRegex) && !isSuspended) {
if (!(skipChecks & IncludeChecks)) {
std::string includedHeader = match[1].str();