Skip to content

Commit

Permalink
[clang] Print static_assert values of arithmetic binary operators (#7…
Browse files Browse the repository at this point in the history
…1671)

These are actually quite useful to print.
  • Loading branch information
tbaederr committed Nov 27, 2023
1 parent 2fda8ca commit 0e86d3e
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 13 deletions.
18 changes: 18 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,24 @@ Improvements to Clang's diagnostics
with GCC.
- Clang will warn on deprecated specializations used in system headers when their instantiation
is caused by user code.
- Clang will now print ``static_assert`` failure details for arithmetic binary operators.
Example:

.. code-block:: cpp
static_assert(1 << 4 == 15);
will now print:

.. code-block:: text
error: static assertion failed due to requirement '1 << 4 == 15'
48 | static_assert(1 << 4 == 15);
| ^~~~~~~~~~~~
note: expression evaluates to '16 == 15'
48 | static_assert(1 << 4 == 15);
| ~~~~~~~^~~~~
Improvements to Clang's time-trace
----------------------------------
Expand Down
8 changes: 4 additions & 4 deletions clang/lib/Sema/SemaDeclCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17218,10 +17218,10 @@ static bool UsefulToPrintExpr(const Expr *E) {
if (const auto *UnaryOp = dyn_cast<UnaryOperator>(E))
return UsefulToPrintExpr(UnaryOp->getSubExpr());

// Ignore nested binary operators. This could be a FIXME for improvements
// to the diagnostics in the future.
if (isa<BinaryOperator>(E))
return false;
// Only print nested arithmetic operators.
if (const auto *BO = dyn_cast<BinaryOperator>(E))
return (BO->isShiftOp() || BO->isAdditiveOp() || BO->isMultiplicativeOp() ||
BO->isBitwiseOp());

return true;
}
Expand Down
27 changes: 18 additions & 9 deletions clang/test/SemaCXX/complex-folding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
// Test the constant folding of builtin complex numbers.

static_assert((0.0 + 0.0j) == (0.0 + 0.0j));
static_assert((0.0 + 0.0j) != (0.0 + 0.0j)); // expected-error {{static assertion}}
static_assert((0.0 + 0.0j) != (0.0 + 0.0j)); // expected-error {{static assertion}} \
// expected-note {{evaluates to}}

static_assert((0.0 + 0.0j) == 0.0);
static_assert(0.0 == (0.0 + 0.0j));
Expand All @@ -14,21 +15,29 @@ static_assert(0.0 != 1.0j);

// Walk around the complex plane stepping between angular differences and
// equality.
static_assert((1.0 + 0.0j) == (0.0 + 0.0j)); // expected-error {{static assertion}}
static_assert((1.0 + 0.0j) == (0.0 + 0.0j)); // expected-error {{static assertion}} \
// expected-note {{evaluates to}}
static_assert((1.0 + 0.0j) == (1.0 + 0.0j));
static_assert((1.0 + 1.0j) == (1.0 + 0.0j)); // expected-error {{static assertion}}
static_assert((1.0 + 1.0j) == (1.0 + 0.0j)); // expected-error {{static assertion}} \
// expected-note {{evaluates to}}
static_assert((1.0 + 1.0j) == (1.0 + 1.0j));
static_assert((0.0 + 1.0j) == (1.0 + 1.0j)); // expected-error {{static assertion}}
static_assert((0.0 + 1.0j) == (1.0 + 1.0j)); // expected-error {{static assertion}} \
// expected-note {{evaluates to}}
static_assert((0.0 + 1.0j) == (0.0 + 1.0j));
static_assert((-1.0 + 1.0j) == (0.0 + 1.0j)); // expected-error {{static assertion}}
static_assert((-1.0 + 1.0j) == (0.0 + 1.0j)); // expected-error {{static assertion}} \
// expected-note {{evaluates to}}
static_assert((-1.0 + 1.0j) == (-1.0 + 1.0j));
static_assert((-1.0 + 0.0j) == (-1.0 + 1.0j)); // expected-error {{static assertion}}
static_assert((-1.0 + 0.0j) == (-1.0 + 1.0j)); // expected-error {{static assertion}} \
// expected-note {{evaluates to}}
static_assert((-1.0 + 0.0j) == (-1.0 + 0.0j));
static_assert((-1.0 - 1.0j) == (-1.0 + 0.0j)); // expected-error {{static assertion}}
static_assert((-1.0 - 1.0j) == (-1.0 + 0.0j)); // expected-error {{static assertion}} \
// expected-note {{evaluates to}}
static_assert((-1.0 - 1.0j) == (-1.0 - 1.0j));
static_assert((0.0 - 1.0j) == (-1.0 - 1.0j)); // expected-error {{static assertion}}
static_assert((0.0 - 1.0j) == (-1.0 - 1.0j)); // expected-error {{static assertion}} \
// expected-note {{evaluates to}}
static_assert((0.0 - 1.0j) == (0.0 - 1.0j));
static_assert((1.0 - 1.0j) == (0.0 - 1.0j)); // expected-error {{static assertion}}
static_assert((1.0 - 1.0j) == (0.0 - 1.0j)); // expected-error {{static assertion}} \
// expected-note {{evaluates to}}
static_assert((1.0 - 1.0j) == (1.0 - 1.0j));

// Test basic mathematical folding of both complex and real operands.
Expand Down
10 changes: 10 additions & 0 deletions clang/test/SemaCXX/static-assert.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -351,4 +351,14 @@ namespace Diagnostics {
""
);

static_assert(1 + 1 != 2, ""); // expected-error {{failed}} \
// expected-note {{evaluates to '2 != 2'}}
static_assert(1 - 1 == 2, ""); // expected-error {{failed}} \
// expected-note {{evaluates to '0 == 2'}}
static_assert(1 * 1 == 2, ""); // expected-error {{failed}} \
// expected-note {{evaluates to '1 == 2'}}
static_assert(1 / 1 == 2, ""); // expected-error {{failed}} \
// expected-note {{evaluates to '1 == 2'}}
static_assert(1 << 3 != 8, ""); // expected-error {{failed}} \
// expected-note {{evaluates to '8 != 8'}}
}

0 comments on commit 0e86d3e

Please sign in to comment.