[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