[clang] 5616c5b - [clang] Tweaked fixit for static assert with no message
Nathan James via cfe-commits
cfe-commits at lists.llvm.org
Mon Feb 22 09:44:00 PST 2021
Author: Nathan James
Date: 2021-02-22T17:43:53Z
New Revision: 5616c5b8664b54671e699e5c45178f11cbb680b3
URL: https://github.com/llvm/llvm-project/commit/5616c5b8664b54671e699e5c45178f11cbb680b3
DIFF: https://github.com/llvm/llvm-project/commit/5616c5b8664b54671e699e5c45178f11cbb680b3.diff
LOG: [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
Added:
clang/test/FixIt/fixit-static-assert.cpp
Modified:
clang/lib/Parse/ParseDeclCXX.cpp
Removed:
################################################################################
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index 811a999418a0..44c072b8987f 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -856,6 +856,16 @@ Decl *Parser::ParseAliasDeclarationAfterDeclarator(
DeclFromDeclSpec);
}
+static FixItHint getStaticAssertNoMessageFixIt(const Expr *AssertExpr,
+ SourceLocation EndExprLoc) {
+ if (const auto *BO = dyn_cast_or_null<BinaryOperator>(AssertExpr)) {
+ if (BO->getOpcode() == BO_LAnd &&
+ isa<StringLiteral>(BO->getRHS()->IgnoreImpCasts()))
+ return FixItHint::CreateReplacement(BO->getOperatorLoc(), ",");
+ }
+ return FixItHint::CreateInsertion(EndExprLoc, ", \"\"");
+}
+
/// ParseStaticAssertDeclaration - Parse C++0x or C11 static_assert-declaration.
///
/// [C++0x] static_assert-declaration:
@@ -892,12 +902,11 @@ Decl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd){
ExprResult AssertMessage;
if (Tok.is(tok::r_paren)) {
- Diag(Tok, getLangOpts().CPlusPlus17
- ? diag::warn_cxx14_compat_static_assert_no_message
- : diag::ext_static_assert_no_message)
- << (getLangOpts().CPlusPlus17
- ? FixItHint()
- : FixItHint::CreateInsertion(Tok.getLocation(), ", \"\""));
+ if (getLangOpts().CPlusPlus17)
+ Diag(Tok, diag::warn_cxx14_compat_static_assert_no_message);
+ else
+ Diag(Tok, diag::ext_static_assert_no_message)
+ << getStaticAssertNoMessageFixIt(AssertExpr.get(), Tok.getLocation());
} else {
if (ExpectAndConsume(tok::comma)) {
SkipUntil(tok::semi);
diff --git a/clang/test/FixIt/fixit-static-assert.cpp b/clang/test/FixIt/fixit-static-assert.cpp
new file mode 100644
index 000000000000..ac07df4d1a58
--- /dev/null
+++ b/clang/test/FixIt/fixit-static-assert.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -std=c++14 %s -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
+// Ensure no warnings are emitted in c++17.
+// RUN: %clang_cc1 -std=c++17 %s -verify=cxx17
+// RUN: %clang_cc1 -std=c++14 %s -fixit-recompile -fixit-to-temporary -Werror
+
+// cxx17-no-diagnostics
+
+static_assert(true && "String");
+// CHECK-DAG: {[[@LINE-1]]:20-[[@LINE-1]]:22}:","
+
+// String literal prefixes are good.
+static_assert(true && R"(RawString)");
+// CHECK-DAG: {[[@LINE-1]]:20-[[@LINE-1]]:22}:","
+static_assert(true && L"RawString");
+// CHECK-DAG: {[[@LINE-1]]:20-[[@LINE-1]]:22}:","
+
+static_assert(true);
+// CHECK-DAG: {[[@LINE-1]]:19-[[@LINE-1]]:19}:", \"\""
+
+// While its technically possible to transform this to
+// static_assert(true, "String") we don't attempt this fix.
+static_assert("String" && true);
+// CHECK-DAG: {[[@LINE-1]]:31-[[@LINE-1]]:31}:", \"\""
+
+// Don't be smart and look in parentheses.
+static_assert((true && "String"));
+// CHECK-DAG: {[[@LINE-1]]:33-[[@LINE-1]]:33}:", \"\""
More information about the cfe-commits
mailing list