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);
}
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);
}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits