diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2011-12-20 02:08:33 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2011-12-20 02:08:33 +0000 |
commit | f6702a3927147655206ae729a84339c4fda4c651 (patch) | |
tree | 8ce5a4586e757043987e0dcf0f523cea068f4812 /lib/Sema/SemaTemplateInstantiateDecl.cpp | |
parent | 9490ab433deef70105d817616928d700f87642d9 (diff) |
Unlike in C++03, a constant-expression is not an unevaluated operand in C++11.
Split out a new ExpressionEvaluationContext flag for this case, and don't treat
it as unevaluated in C++11. This fixes some crash-on-invalids where we would
allow references to class members in potentially-evaluated constant expressions
in static member functions, and also fixes half of PR10177.
The fix to PR10177 exposed a case where template instantiation failed to provide
a source location for a diagnostic, so TreeTransform has been tweaked to supply
source locations when transforming a type. The source location is still not very
good, but MarkDeclarationsReferencedInType would need to operate on a TypeLoc to
improve it further.
Also fix MarkDeclarationReferenced in C++98 mode to trigger instantiation for
static data members of class templates which are used in constant expressions.
This fixes a link-time problem, but we still incorrectly treat the member as
non-constant. The rest of the fix for that issue is blocked on PCH support for
early-instantiated static data members, which will be added in a subsequent
patch.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@146955 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiateDecl.cpp')
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateDecl.cpp | 32 |
1 files changed, 17 insertions, 15 deletions
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 123548e656..b2208b63c8 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -66,17 +66,16 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs, // FIXME: This should be generalized to more than just the AlignedAttr. if (const AlignedAttr *Aligned = dyn_cast<AlignedAttr>(TmplAttr)) { if (Aligned->isAlignmentDependent()) { - // The alignment expression is not potentially evaluated. - EnterExpressionEvaluationContext Unevaluated(*this, - Sema::Unevaluated); - if (Aligned->isAlignmentExpr()) { + // The alignment expression is a constant expression. + EnterExpressionEvaluationContext Unevaluated(*this, + Sema::ConstantEvaluated); + ExprResult Result = SubstExpr(Aligned->getAlignmentExpr(), TemplateArgs); if (!Result.isInvalid()) AddAlignedAttr(Aligned->getLocation(), New, Result.takeAs<Expr>()); - } - else { + } else { TypeSourceInfo *Result = SubstType(Aligned->getAlignmentType(), TemplateArgs, Aligned->getLocation(), @@ -380,7 +379,7 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) { // We already have an initializer in the class. } else if (D->getInit()) { if (Var->isStaticDataMember() && !D->isOutOfLine()) - SemaRef.PushExpressionEvaluationContext(Sema::Unevaluated); + SemaRef.PushExpressionEvaluationContext(Sema::ConstantEvaluated); else SemaRef.PushExpressionEvaluationContext(Sema::PotentiallyEvaluated); @@ -462,8 +461,9 @@ Decl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) { if (Invalid) BitWidth = 0; else if (BitWidth) { - // The bit-width expression is not potentially evaluated. - EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated); + // The bit-width expression is a constant expression. + EnterExpressionEvaluationContext Unevaluated(SemaRef, + Sema::ConstantEvaluated); ExprResult InstantiatedBitWidth = SemaRef.SubstExpr(BitWidth, TemplateArgs); @@ -591,8 +591,9 @@ Decl *TemplateDeclInstantiator::VisitFriendDecl(FriendDecl *D) { Decl *TemplateDeclInstantiator::VisitStaticAssertDecl(StaticAssertDecl *D) { Expr *AssertExpr = D->getAssertExpr(); - // The expression in a static assertion is not potentially evaluated. - EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated); + // The expression in a static assertion is a constant expression. + EnterExpressionEvaluationContext Unevaluated(SemaRef, + Sema::ConstantEvaluated); ExprResult InstantiatedAssertExpr = SemaRef.SubstExpr(AssertExpr, TemplateArgs); @@ -653,9 +654,9 @@ Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) { // The specified value for the enumerator. ExprResult Value = SemaRef.Owned((Expr *)0); if (Expr *UninstValue = EC->getInitExpr()) { - // The enumerator's value expression is not potentially evaluated. + // The enumerator's value expression is a constant expression. EnterExpressionEvaluationContext Unevaluated(SemaRef, - Sema::Unevaluated); + Sema::ConstantEvaluated); Value = SemaRef.SubstExpr(UninstValue, TemplateArgs); } @@ -2321,11 +2322,12 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New, } Expr *NoexceptExpr = 0; if (Expr *OldNoexceptExpr = Proto->getNoexceptExpr()) { - EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated); + EnterExpressionEvaluationContext Unevaluated(SemaRef, + Sema::ConstantEvaluated); ExprResult E = SemaRef.SubstExpr(OldNoexceptExpr, TemplateArgs); if (E.isUsable()) E = SemaRef.CheckBooleanCondition(E.get(), E.get()->getLocStart()); - + if (E.isUsable()) { SourceLocation ErrLoc; llvm::APSInt NoexceptVal; |