diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-07-11 22:37:56 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-07-11 22:37:56 +0000 |
commit | ded9c2ee92f6d9b65ed211070c0c34119bd30969 (patch) | |
tree | 72e8f0cb06fd781c66126d73b87013413ce38ec2 /clang/lib/Sema | |
parent | 3d46052d90dc5f9a0e145c0531b0a74a845c39e4 (diff) | |
download | bcm5719-llvm-ded9c2ee92f6d9b65ed211070c0c34119bd30969.tar.gz bcm5719-llvm-ded9c2ee92f6d9b65ed211070c0c34119bd30969.zip |
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.
llvm-svn: 160088
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 34 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiate.cpp | 9 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 9 |
3 files changed, 35 insertions, 17 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index fa42fdd827c..ebd9180ec64 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/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/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 239a0d73ebc..0a0016c50b3 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/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/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index cce0b0d0930..0d3e8a0ba8e 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/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) { |