diff --git a/Universal/Docs/PHP/RequireExitDieParenthesesStandard.xml b/Universal/Docs/PHP/RequireExitDieParenthesesStandard.xml
new file mode 100644
index 0000000..677a4ce
--- /dev/null
+++ b/Universal/Docs/PHP/RequireExitDieParenthesesStandard.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+ ();
+exit($status);
+ ]]>
+
+
+ ;
+exit;
+ ]]>
+
+
+
diff --git a/Universal/Sniffs/PHP/RequireExitDieParenthesesSniff.php b/Universal/Sniffs/PHP/RequireExitDieParenthesesSniff.php
new file mode 100644
index 0000000..47ce20a
--- /dev/null
+++ b/Universal/Sniffs/PHP/RequireExitDieParenthesesSniff.php
@@ -0,0 +1,85 @@
+
+ */
+ public function register()
+ {
+ return [\T_EXIT];
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @since 1.5.0
+ *
+ * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token
+ * in the stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+ $nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true);
+ if ($nextNonEmpty === false) {
+ // Live coding. Do not flag (yet).
+ return;
+ }
+
+ if ($tokens[$nextNonEmpty]['code'] === \T_OPEN_PARENTHESIS) {
+ // Parentheses found.
+ $phpcsFile->recordMetric($stackPtr, self::METRIC_NAME, 'yes');
+ return;
+ }
+
+ $phpcsFile->recordMetric($stackPtr, self::METRIC_NAME, 'no');
+
+ $fix = $phpcsFile->addFixableError(
+ 'Parentheses required when calling %s, even if no argument is given.',
+ $stackPtr,
+ 'Missing',
+ [\strtolower(\ltrim($tokens[$stackPtr]['content'], '\\'))]
+ );
+
+ if ($fix === true) {
+ $phpcsFile->fixer->addContent($stackPtr, '()');
+ }
+ }
+}
diff --git a/Universal/Tests/PHP/RequireExitDieParenthesesUnitTest.1.inc b/Universal/Tests/PHP/RequireExitDieParenthesesUnitTest.1.inc
new file mode 100644
index 0000000..f2828c4
--- /dev/null
+++ b/Universal/Tests/PHP/RequireExitDieParenthesesUnitTest.1.inc
@@ -0,0 +1,54 @@
+exit;
+ echo $this->die;
+ echo $this->exit();
+ echo $this->die();
+ }
+}
+
+// Invalid PHP, but not our concern. Not our target.
+namespace\Sub\exit;
+Partially\Qualified\die;
+\Fully\Qualified\exit;
+
+/*
+ * OK.
+ */
+exit();
+die();
+Exit();
+DIE();
+\exit();
+\die();
+exit ($status);
+\die /*comment*/ (10);
+
+/*
+ * Bad.
+ */
+exit;
+die;
+EXIT;
+Die;
+\exit;
+\die;
diff --git a/Universal/Tests/PHP/RequireExitDieParenthesesUnitTest.1.inc.fixed b/Universal/Tests/PHP/RequireExitDieParenthesesUnitTest.1.inc.fixed
new file mode 100644
index 0000000..a00c890
--- /dev/null
+++ b/Universal/Tests/PHP/RequireExitDieParenthesesUnitTest.1.inc.fixed
@@ -0,0 +1,54 @@
+exit;
+ echo $this->die;
+ echo $this->exit();
+ echo $this->die();
+ }
+}
+
+// Invalid PHP, but not our concern. Not our target.
+namespace\Sub\exit;
+Partially\Qualified\die;
+\Fully\Qualified\exit;
+
+/*
+ * OK.
+ */
+exit();
+die();
+Exit();
+DIE();
+\exit();
+\die();
+exit ($status);
+\die /*comment*/ (10);
+
+/*
+ * Bad.
+ */
+exit();
+die();
+EXIT();
+Die();
+\exit();
+\die();
diff --git a/Universal/Tests/PHP/RequireExitDieParenthesesUnitTest.2.inc b/Universal/Tests/PHP/RequireExitDieParenthesesUnitTest.2.inc
new file mode 100644
index 0000000..33e4c94
--- /dev/null
+++ b/Universal/Tests/PHP/RequireExitDieParenthesesUnitTest.2.inc
@@ -0,0 +1,6 @@
+ Key is the line number, value is the number of expected errors.
+ */
+ public function getErrorList($testFile = '')
+ {
+ switch ($testFile) {
+ case 'RequireExitDieParenthesesUnitTest.1.inc':
+ return [
+ 49 => 1,
+ 50 => 1,
+ 51 => 1,
+ 52 => 1,
+ 53 => 1,
+ 54 => 1,
+ ];
+
+ default:
+ return [];
+ }
+ }
+
+ /**
+ * Returns the lines where warnings should occur.
+ *
+ * @return array Key is the line number, value is the number of expected warnings.
+ */
+ public function getWarningList()
+ {
+ return [];
+ }
+}