aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2012-07-11 22:37:56 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2012-07-11 22:37:56 +0000
commite3f470a718ec00eb8b546e405fa59bc2df2d7c46 (patch)
treeda7223195380885f10c3fb658c4320a8667787e3 /lib/Sema
parent18b7f95bdbfbd90c1f8e027225fb2cb8fca7134a (diff)
Stop instantiating a class if we hit a static_assert failure. Also, if the
static_assert fails when parsing the template, don't diagnose it again on every instantiation. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@160088 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema')
-rw-r--r--lib/Sema/SemaDeclCXX.cpp34
-rw-r--r--lib/Sema/SemaTemplateInstantiate.cpp9
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp9
3 files changed, 35 insertions, 17 deletions
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index fa42fdd827..ebd9180ec6 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -9736,37 +9736,49 @@ Decl *Sema::ActOnExceptionDeclarator(Scope *S, Declarator &D) {
Decl *Sema::ActOnStaticAssertDeclaration(SourceLocation StaticAssertLoc,
Expr *AssertExpr,
- Expr *AssertMessageExpr_,
+ Expr *AssertMessageExpr,
SourceLocation RParenLoc) {
- StringLiteral *AssertMessage = cast<StringLiteral>(AssertMessageExpr_);
+ StringLiteral *AssertMessage = cast<StringLiteral>(AssertMessageExpr);
- if (!AssertExpr->isTypeDependent() && !AssertExpr->isValueDependent()) {
+ if (DiagnoseUnexpandedParameterPack(AssertExpr, UPPC_StaticAssertExpression))
+ return 0;
+
+ return BuildStaticAssertDeclaration(StaticAssertLoc, AssertExpr,
+ AssertMessage, RParenLoc, false);
+}
+
+Decl *Sema::BuildStaticAssertDeclaration(SourceLocation StaticAssertLoc,
+ Expr *AssertExpr,
+ StringLiteral *AssertMessage,
+ SourceLocation RParenLoc,
+ bool Failed) {
+ if (!AssertExpr->isTypeDependent() && !AssertExpr->isValueDependent() &&
+ !Failed) {
// In a static_assert-declaration, the constant-expression shall be a
// constant expression that can be contextually converted to bool.
ExprResult Converted = PerformContextuallyConvertToBool(AssertExpr);
if (Converted.isInvalid())
- return 0;
+ Failed = true;
llvm::APSInt Cond;
- if (VerifyIntegerConstantExpression(Converted.get(), &Cond,
+ if (!Failed && VerifyIntegerConstantExpression(Converted.get(), &Cond,
diag::err_static_assert_expression_is_not_constant,
/*AllowFold=*/false).isInvalid())
- return 0;
+ Failed = true;
- if (!Cond) {
+ if (!Failed && !Cond) {
llvm::SmallString<256> MsgBuffer;
llvm::raw_svector_ostream Msg(MsgBuffer);
AssertMessage->printPretty(Msg, Context, 0, getPrintingPolicy());
Diag(StaticAssertLoc, diag::err_static_assert_failed)
<< Msg.str() << AssertExpr->getSourceRange();
+ Failed = true;
}
}
- if (DiagnoseUnexpandedParameterPack(AssertExpr, UPPC_StaticAssertExpression))
- return 0;
-
Decl *Decl = StaticAssertDecl::Create(Context, CurContext, StaticAssertLoc,
- AssertExpr, AssertMessage, RParenLoc);
+ AssertExpr, AssertMessage, RParenLoc,
+ Failed);
CurContext->addDecl(Decl);
return Decl;
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index 239a0d73eb..0a0016c50b 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1904,7 +1904,7 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
continue;
if ((*Member)->isInvalidDecl()) {
- Instantiation->setInvalidDecl();
+ Instantiation->setInvalidDecl();
continue;
}
@@ -1928,6 +1928,13 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
MSInfo->setTemplateSpecializationKind(TSK_ImplicitInstantiation);
MSInfo->setPointOfInstantiation(PointOfInstantiation);
}
+ } else if (StaticAssertDecl *SA = dyn_cast<StaticAssertDecl>(NewMember)) {
+ if (SA->isFailed()) {
+ // A static_assert failed. Bail out; instantiating this
+ // class is probably not meaningful.
+ Instantiation->setInvalidDecl();
+ break;
+ }
}
if (NewMember->isInvalidDecl())
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index cce0b0d093..0d3e8a0ba8 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -552,12 +552,11 @@ Decl *TemplateDeclInstantiator::VisitStaticAssertDecl(StaticAssertDecl *D) {
if (InstantiatedAssertExpr.isInvalid())
return 0;
- ExprResult Message(D->getMessage());
- D->getMessage();
- return SemaRef.ActOnStaticAssertDeclaration(D->getLocation(),
+ return SemaRef.BuildStaticAssertDeclaration(D->getLocation(),
InstantiatedAssertExpr.get(),
- Message.get(),
- D->getRParenLoc());
+ D->getMessage(),
+ D->getRParenLoc(),
+ D->isFailed());
}
Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) {