From cdd1da209dfc542b69ab7db539688c2ed7bc00d7 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Mon, 1 Oct 2012 20:36:17 +0000 Subject: [PATCH] Fix treatment of case which came up on std-proposals@: 'void' is permitted in core constant expressions, despite not being a literal type. llvm-svn: 164968 --- clang/lib/AST/ExprConstant.cpp | 4 +--- .../test/SemaCXX/constant-expression-cxx11.cpp | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index c4fd70a8c8bd..05912fc1c5a9 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -6196,11 +6196,9 @@ static bool Evaluate(APValue &Result, EvalInfo &Info, const Expr *E) { return false; Result = Info.CurrentCall->Temporaries[E]; } else if (E->getType()->isVoidType()) { - if (Info.getLangOpts().CPlusPlus0x) + if (!Info.getLangOpts().CPlusPlus0x) Info.CCEDiag(E, diag::note_constexpr_nonliteral) << E->getType(); - else - Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr); if (!EvaluateVoid(E, Info)) return false; } else if (Info.getLangOpts().CPlusPlus0x) { diff --git a/clang/test/SemaCXX/constant-expression-cxx11.cpp b/clang/test/SemaCXX/constant-expression-cxx11.cpp index 930e70d4f36f..065e396b1527 100644 --- a/clang/test/SemaCXX/constant-expression-cxx11.cpp +++ b/clang/test/SemaCXX/constant-expression-cxx11.cpp @@ -1390,3 +1390,21 @@ namespace TLS { constexpr int *g() { return &m; } constexpr int *r = g(); } + +namespace Void { + constexpr void f() { return; } // expected-error{{constexpr function's return type 'void' is not a literal type}} + + void assert_failed(const char *msg, const char *file, int line); // expected-note {{declared here}} +#define ASSERT(expr) ((expr) ? static_cast(0) : assert_failed(#expr, __FILE__, __LINE__)) + template + constexpr T get(T (&a)[S], size_t k) { + return ASSERT(k > 0 && k < S), a[k]; // expected-note{{non-constexpr function 'assert_failed'}} + } +#undef ASSERT + template int get(int (&a)[4], size_t); + constexpr int arr[] = { 4, 1, 2, 3, 4 }; + static_assert(get(arr, 1) == 1, ""); + static_assert(get(arr, 4) == 4, ""); + static_assert(get(arr, 0) == 4, ""); // expected-error{{not an integral constant expression}} \ + // expected-note{{in call to 'get(arr, 0)'}} +}