Skip to content

Commit 5616c5b

Browse files
committed
[clang] Tweaked fixit for static assert with no message
If a static assert has a message as the right side of an and condition, suggest a fix it of replacing the '&&' to ','. `static_assert(cond && "Failed Cond")` -> `static_assert(cond, "Failed cond")` This use case comes up when lazily replacing asserts with static asserts. Reviewed By: aaron.ballman Differential Revision: https://reviews.llvm.org/D89065
1 parent 5e7e499 commit 5616c5b

File tree

2 files changed

+42
-6
lines changed

2 files changed

+42
-6
lines changed

clang/lib/Parse/ParseDeclCXX.cpp

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -856,6 +856,16 @@ Decl *Parser::ParseAliasDeclarationAfterDeclarator(
856856
DeclFromDeclSpec);
857857
}
858858

859+
static FixItHint getStaticAssertNoMessageFixIt(const Expr *AssertExpr,
860+
SourceLocation EndExprLoc) {
861+
if (const auto *BO = dyn_cast_or_null<BinaryOperator>(AssertExpr)) {
862+
if (BO->getOpcode() == BO_LAnd &&
863+
isa<StringLiteral>(BO->getRHS()->IgnoreImpCasts()))
864+
return FixItHint::CreateReplacement(BO->getOperatorLoc(), ",");
865+
}
866+
return FixItHint::CreateInsertion(EndExprLoc, ", \"\"");
867+
}
868+
859869
/// ParseStaticAssertDeclaration - Parse C++0x or C11 static_assert-declaration.
860870
///
861871
/// [C++0x] static_assert-declaration:
@@ -892,12 +902,11 @@ Decl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd){
892902

893903
ExprResult AssertMessage;
894904
if (Tok.is(tok::r_paren)) {
895-
Diag(Tok, getLangOpts().CPlusPlus17
896-
? diag::warn_cxx14_compat_static_assert_no_message
897-
: diag::ext_static_assert_no_message)
898-
<< (getLangOpts().CPlusPlus17
899-
? FixItHint()
900-
: FixItHint::CreateInsertion(Tok.getLocation(), ", \"\""));
905+
if (getLangOpts().CPlusPlus17)
906+
Diag(Tok, diag::warn_cxx14_compat_static_assert_no_message);
907+
else
908+
Diag(Tok, diag::ext_static_assert_no_message)
909+
<< getStaticAssertNoMessageFixIt(AssertExpr.get(), Tok.getLocation());
901910
} else {
902911
if (ExpectAndConsume(tok::comma)) {
903912
SkipUntil(tok::semi);
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// RUN: %clang_cc1 -std=c++14 %s -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
2+
// Ensure no warnings are emitted in c++17.
3+
// RUN: %clang_cc1 -std=c++17 %s -verify=cxx17
4+
// RUN: %clang_cc1 -std=c++14 %s -fixit-recompile -fixit-to-temporary -Werror
5+
6+
// cxx17-no-diagnostics
7+
8+
static_assert(true && "String");
9+
// CHECK-DAG: {[[@LINE-1]]:20-[[@LINE-1]]:22}:","
10+
11+
// String literal prefixes are good.
12+
static_assert(true && R"(RawString)");
13+
// CHECK-DAG: {[[@LINE-1]]:20-[[@LINE-1]]:22}:","
14+
static_assert(true && L"RawString");
15+
// CHECK-DAG: {[[@LINE-1]]:20-[[@LINE-1]]:22}:","
16+
17+
static_assert(true);
18+
// CHECK-DAG: {[[@LINE-1]]:19-[[@LINE-1]]:19}:", \"\""
19+
20+
// While its technically possible to transform this to
21+
// static_assert(true, "String") we don't attempt this fix.
22+
static_assert("String" && true);
23+
// CHECK-DAG: {[[@LINE-1]]:31-[[@LINE-1]]:31}:", \"\""
24+
25+
// Don't be smart and look in parentheses.
26+
static_assert((true && "String"));
27+
// CHECK-DAG: {[[@LINE-1]]:33-[[@LINE-1]]:33}:", \"\""

0 commit comments

Comments
 (0)