[PATCH] FixIt for constexpr initializer_list errors
Richard Smith
richard at metafoo.co.uk
Fri Feb 28 14:24:49 PST 2014
rsmith added you to the CC list for the revision "FixIt for constexpr initializer_list errors".
Hi rsmith,
This patch adds a different diagnostic for auto-deduced constexpr
std::initializer_list instances, suggesting the addition of 'static' to
the declaration. We take the form:
void foo() {
constexpr auto x = { 1, 2, 3 };
}
and suggest the FixIt:
void foo() {
static constexpr auto x = { 1, 2, 3 };
}
http://llvm-reviews.chandlerc.com/D2855
Files:
include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaDecl.cpp
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -1703,6 +1703,9 @@
"constexpr variable cannot have non-literal type %0">;
def err_constexpr_var_requires_const_init : Error<
"constexpr variable %0 must be initialized by a constant expression">;
+def err_constexpr_initializer_list_requires_static : Error<
+ "local constexpr initializer list %0 must be initialized by a constant "
+ "expression; did you intend to make it static?">;
def err_constexpr_redecl_mismatch : Error<
"%select{non-constexpr declaration of %0 follows constexpr declaration"
"|constexpr declaration of %0 follows non-constexpr declaration}1">;
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -8888,8 +8888,28 @@
DiagLoc = Notes[0].first;
Notes.clear();
}
- Diag(DiagLoc, diag::err_constexpr_var_requires_const_init)
- << var << Init->getSourceRange();
+
+ // If we're initializing a std::initializer_list we might want to also
+ // suggest making it static, because most of the time this is probably
+ // what the user wanted.
+ CXXRecordDecl *RD =
+ baseType.withoutLocalFastQualifiers()->getAsCXXRecordDecl();
+ if (RD && RD->getName().startswith("initializer_list")) {
+ SourceLocation initStart = var->getLocStart();
+ SourceLocation initEnd = Lexer::getLocForEndOfToken(
+ var->getLocEnd(), 0, getSourceManager(), LangOptions());
+ std::string expression(
+ getSourceManager().getCharacterData(initStart),
+ getSourceManager().getCharacterData(initEnd) -
+ getSourceManager().getCharacterData(initStart));
+ Diag(DiagLoc, diag::err_constexpr_initializer_list_requires_static)
+ << var << baseType << Init->getSourceRange()
+ << FixItHint::CreateReplacement(var->getSourceRange(),
+ "static " + expression);
+ } else {
+ Diag(DiagLoc, diag::err_constexpr_var_requires_const_init)
+ << var << Init->getSourceRange();
+ }
for (unsigned I = 0, N = Notes.size(); I != N; ++I)
Diag(Notes[I].first, Notes[I].second);
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D2855.1.patch
Type: text/x-patch
Size: 2306 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140228/a0ec8230/attachment.bin>
More information about the cfe-commits
mailing list