Просмотр исходного кода

Help: Clarify precedence of AND and OR in 'if' conditions

The wording update in commit b74819e4fe (Help: Format 'if' command
documentation, 2013-12-18, v3.0.0-rc1~227^2~1) incorrectly implied that
`AND` has higher precedence than `OR`.  Although this is common in many
languages, it has never been true in CMake's implementation.  Revise
the wording to clarify the precedence.

Add a test case demonstrating the order.

Fixes: #23207
Brad King 3 лет назад
Родитель
Сommit
41adfc6b04

+ 15 - 8
Help/command/if.rst

@@ -38,14 +38,21 @@ The following syntax applies to the ``condition`` argument of
 the ``if``, ``elseif`` and :command:`while` clauses.
 
 Compound conditions are evaluated in the following order of precedence:
-Innermost parentheses are evaluated first. Next come unary tests such
-as `EXISTS`_, `COMMAND`_, and `DEFINED`_.  Then binary tests such as
-`EQUAL`_, `LESS`_, `LESS_EQUAL`_, `GREATER`_, `GREATER_EQUAL`_,
-`STREQUAL`_, `STRLESS`_, `STRLESS_EQUAL`_, `STRGREATER`_,
-`STRGREATER_EQUAL`_, `VERSION_EQUAL`_, `VERSION_LESS`_,
-`VERSION_LESS_EQUAL`_, `VERSION_GREATER`_, `VERSION_GREATER_EQUAL`_,
-and `MATCHES`_.  Then the boolean operators in the order `NOT`_,  `AND`_,
-and finally `OR`_.
+
+1. Parentheses.
+
+2. Unary tests such as `EXISTS`_, `COMMAND`_, and `DEFINED`_.
+
+3. Binary tests such as `EQUAL`_, `LESS`_, `LESS_EQUAL`_, `GREATER`_,
+   `GREATER_EQUAL`_, `STREQUAL`_, `STRLESS`_, `STRLESS_EQUAL`_,
+   `STRGREATER`_, `STRGREATER_EQUAL`_, `VERSION_EQUAL`_, `VERSION_LESS`_,
+   `VERSION_LESS_EQUAL`_, `VERSION_GREATER`_, `VERSION_GREATER_EQUAL`_,
+   and `MATCHES`_.
+
+4. Unary logical operator `NOT`_.
+
+5. Binary logical operators `AND`_ and `OR`_, from left to right,
+   without any short-circuit.
 
 Basic Expressions
 """""""""""""""""

+ 1 - 0
Tests/RunCMake/if/AndOr-stdout.txt

@@ -0,0 +1 @@
+-- OR and AND correctly evaluated left to right

+ 6 - 0
Tests/RunCMake/if/AndOr.cmake

@@ -0,0 +1,6 @@
+# AND and OR are the same precedence
+if(1 OR 0 AND 0) # equivalent to ((1 OR 0) AND 0)
+  message(FATAL_ERROR "AND incorrectly evaluated before OR")
+else()
+  message(STATUS "OR and AND correctly evaluated left to right")
+endif()

+ 2 - 0
Tests/RunCMake/if/RunCMakeTest.cmake

@@ -17,3 +17,5 @@ run_cmake(IncompleteMatchesFail)
 
 run_cmake(TestNameThatExists)
 run_cmake(TestNameThatDoesNotExist)
+
+run_cmake_script(AndOr)