summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2014-06-20 19:57:12 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2014-06-20 19:57:12 +0000
commit085a64ffc5d447a6a967bb1267396d7b6ee030e2 (patch)
tree02cf6883f80bdc6f0c8415fa6263d0a36ce3bb0b
parent7c8d13911a311019e2b56da8682fb41217072fd9 (diff)
downloadbcm5719-llvm-085a64ffc5d447a6a967bb1267396d7b6ee030e2.tar.gz
bcm5719-llvm-085a64ffc5d447a6a967bb1267396d7b6ee030e2.zip
[C++1z] Implement N3928: message in static_assert is optional.
llvm-svn: 211394
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td7
-rw-r--r--clang/lib/Parse/ParseDeclCXX.cpp38
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp11
-rw-r--r--clang/test/SemaCXX/cxx0x-compat.cpp3
-rw-r--r--clang/test/SemaCXX/static-assert.cpp3
5 files changed, 41 insertions, 21 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index f7f08fc4cbb..035a7377e18 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -931,7 +931,12 @@ def warning_multiple_selectors: Warning<
// C++ declarations
def err_static_assert_expression_is_not_constant : Error<
"static_assert expression is not an integral constant expression">;
-def err_static_assert_failed : Error<"static_assert failed %0">;
+def err_static_assert_failed : Error<"static_assert failed%select{ %1|}0">;
+def ext_static_assert_no_message : ExtWarn<
+ "static_assert with no message is a C++1z extension">, InGroup<CXX1z>;
+def warn_cxx1y_compat_static_assert_no_message : Warning<
+ "static_assert with no message is incompatible with C++ standards before C++1z">,
+ DefaultIgnore, InGroup<CXXPre1zCompat>;
def warn_inline_namespace_reopened_noninline : Warning<
"inline namespace cannot be reopened as a non-inline namespace">;
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index 33e3cab8671..cd2e3971884 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -689,22 +689,32 @@ Decl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd){
return nullptr;
}
- if (ExpectAndConsume(tok::comma)) {
- SkipUntil(tok::semi);
- return nullptr;
- }
+ ExprResult AssertMessage;
+ if (Tok.is(tok::r_paren)) {
+ Diag(Tok, getLangOpts().CPlusPlus1z
+ ? diag::warn_cxx1y_compat_static_assert_no_message
+ : diag::ext_static_assert_no_message)
+ << (getLangOpts().CPlusPlus1z
+ ? FixItHint()
+ : FixItHint::CreateInsertion(Tok.getLocation(), ", \"\""));
+ } else {
+ if (ExpectAndConsume(tok::comma)) {
+ SkipUntil(tok::semi);
+ return nullptr;
+ }
- if (!isTokenStringLiteral()) {
- Diag(Tok, diag::err_expected_string_literal)
- << /*Source='static_assert'*/1;
- SkipMalformedDecl();
- return nullptr;
- }
+ if (!isTokenStringLiteral()) {
+ Diag(Tok, diag::err_expected_string_literal)
+ << /*Source='static_assert'*/1;
+ SkipMalformedDecl();
+ return nullptr;
+ }
- ExprResult AssertMessage(ParseStringLiteralExpression());
- if (AssertMessage.isInvalid()) {
- SkipMalformedDecl();
- return nullptr;
+ AssertMessage = ParseStringLiteralExpression();
+ if (AssertMessage.isInvalid()) {
+ SkipMalformedDecl();
+ return nullptr;
+ }
}
T.consumeClose();
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 85394bb4de7..5ca53b0a08a 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -11405,7 +11405,8 @@ Decl *Sema::ActOnStaticAssertDeclaration(SourceLocation StaticAssertLoc,
Expr *AssertExpr,
Expr *AssertMessageExpr,
SourceLocation RParenLoc) {
- StringLiteral *AssertMessage = cast<StringLiteral>(AssertMessageExpr);
+ StringLiteral *AssertMessage =
+ AssertMessageExpr ? cast<StringLiteral>(AssertMessageExpr) : nullptr;
if (DiagnoseUnexpandedParameterPack(AssertExpr, UPPC_StaticAssertExpression))
return nullptr;
@@ -11419,8 +11420,7 @@ Decl *Sema::BuildStaticAssertDeclaration(SourceLocation StaticAssertLoc,
StringLiteral *AssertMessage,
SourceLocation RParenLoc,
bool Failed) {
- assert(AssertExpr != nullptr && AssertMessage != nullptr &&
- "Expected non-null Expr's");
+ assert(AssertExpr != nullptr && "Expected non-null condition");
if (!AssertExpr->isTypeDependent() && !AssertExpr->isValueDependent() &&
!Failed) {
// In a static_assert-declaration, the constant-expression shall be a
@@ -11438,9 +11438,10 @@ Decl *Sema::BuildStaticAssertDeclaration(SourceLocation StaticAssertLoc,
if (!Failed && !Cond) {
SmallString<256> MsgBuffer;
llvm::raw_svector_ostream Msg(MsgBuffer);
- AssertMessage->printPretty(Msg, nullptr, getPrintingPolicy());
+ if (AssertMessage)
+ AssertMessage->printPretty(Msg, nullptr, getPrintingPolicy());
Diag(StaticAssertLoc, diag::err_static_assert_failed)
- << Msg.str() << AssertExpr->getSourceRange();
+ << !AssertMessage << Msg.str() << AssertExpr->getSourceRange();
Failed = true;
}
}
diff --git a/clang/test/SemaCXX/cxx0x-compat.cpp b/clang/test/SemaCXX/cxx0x-compat.cpp
index ffbd20fda37..a58a7f875cd 100644
--- a/clang/test/SemaCXX/cxx0x-compat.cpp
+++ b/clang/test/SemaCXX/cxx0x-compat.cpp
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -std=c++98 -Wc++11-compat -verify %s
-// RUN: %clang_cc1 -fsyntax-only -std=c++1y -Wc++11-compat -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++1z -Wc++11-compat -verify %s
#if __cplusplus < 201103L
@@ -44,5 +44,6 @@ char c = 'x'_x; // expected-warning {{will be treated as a user-defined literal
#else
auto init_capture = [a(0)] {}; // expected-warning {{initialized lambda captures are incompatible with C++ standards before C++1y}}
+static_assert(true); // expected-warning {{incompatible with C++ standards before C++1z}}
#endif
diff --git a/clang/test/SemaCXX/static-assert.cpp b/clang/test/SemaCXX/static-assert.cpp
index 4a7560ba5b6..c9d93843536 100644
--- a/clang/test/SemaCXX/static-assert.cpp
+++ b/clang/test/SemaCXX/static-assert.cpp
@@ -48,3 +48,6 @@ template<typename T> struct StaticAssertProtected {
struct X { ~X(); };
StaticAssertProtected<int> sap1;
StaticAssertProtected<X> sap2; // expected-note {{instantiation}}
+
+static_assert(true); // expected-warning {{C++1z extension}}
+static_assert(false); // expected-error-re {{failed$}} expected-warning {{extension}}
OpenPOWER on IntegriCloud