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 | 764d2fe6668d66d82dcd412463432d0f87420455 (patch) | |
| tree | cf51ebff7ca8270d59a1006a058fbe42e43e2466 /clang/lib/Sema/TreeTransform.h | |
| parent | 50660440a192a5769e63ff41bff27423c374c98f (diff) | |
| download | bcm5719-llvm-764d2fe6668d66d82dcd412463432d0f87420455.tar.gz bcm5719-llvm-764d2fe6668d66d82dcd412463432d0f87420455.zip | |
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.
llvm-svn: 146955
Diffstat (limited to 'clang/lib/Sema/TreeTransform.h')
| -rw-r--r-- | clang/lib/Sema/TreeTransform.h | 28 |
1 files changed, 14 insertions, 14 deletions
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index a30a0d036af..7995b0ba77c 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -2898,7 +2898,7 @@ bool TreeTransform<Derived>::TransformTemplateArgument( Expr *SourceExpr = Input.getSourceDeclExpression(); if (SourceExpr) { EnterExpressionEvaluationContext Unevaluated(getSema(), - Sema::Unevaluated); + Sema::ConstantEvaluated); ExprResult E = getDerived().TransformExpr(SourceExpr); SourceExpr = (E.isInvalid() ? 0 : E.take()); } @@ -2932,9 +2932,9 @@ bool TreeTransform<Derived>::TransformTemplateArgument( llvm_unreachable("Caller should expand pack expansions"); case TemplateArgument::Expression: { - // Template argument expressions are not potentially evaluated. + // Template argument expressions are constant expressions. EnterExpressionEvaluationContext Unevaluated(getSema(), - Sema::Unevaluated); + Sema::ConstantEvaluated); Expr *InputExpr = Input.getSourceExpression(); if (!InputExpr) InputExpr = Input.getArgument().getAsExpr(); @@ -3182,6 +3182,9 @@ QualType TreeTransform<Derived>::TransformType(QualType T) { template<typename Derived> TypeSourceInfo *TreeTransform<Derived>::TransformType(TypeSourceInfo *DI) { + // Refine the base location to the type's location. + TemporaryBase Rebase(*this, DI->getTypeLoc().getBeginLoc(), + getDerived().getBaseEntity()); if (getDerived().AlreadyTransformed(DI->getType())) return DI; @@ -3595,7 +3598,8 @@ TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB, Expr *Size = TL.getSizeExpr(); if (Size) { - EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated); + EnterExpressionEvaluationContext Unevaluated(SemaRef, + Sema::ConstantEvaluated); Size = getDerived().TransformExpr(Size).template takeAs<Expr>(); } NewTL.setSizeExpr(Size); @@ -3640,9 +3644,6 @@ TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB, if (ElementType.isNull()) return QualType(); - // Array bounds are not potentially evaluated contexts - EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated); - ExprResult SizeResult = getDerived().TransformExpr(T->getSizeExpr()); if (SizeResult.isInvalid()) @@ -3680,8 +3681,9 @@ TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB, if (ElementType.isNull()) return QualType(); - // Array bounds are not potentially evaluated contexts - EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated); + // Array bounds are constant expressions. + EnterExpressionEvaluationContext Unevaluated(SemaRef, + Sema::ConstantEvaluated); // Prefer the expression from the TypeLoc; the other may have been uniqued. Expr *origSize = TL.getSizeExpr(); @@ -3728,8 +3730,9 @@ QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType( if (ElementType.isNull()) return QualType(); - // Vector sizes are not potentially evaluated contexts - EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated); + // Vector sizes are constant expressions. + EnterExpressionEvaluationContext Unevaluated(SemaRef, + Sema::ConstantEvaluated); ExprResult Size = getDerived().TransformExpr(T->getSizeExpr()); if (Size.isInvalid()) @@ -6913,9 +6916,6 @@ TreeTransform<Derived>::TransformCXXUuidofExpr(CXXUuidofExpr *E) { E->getLocEnd()); } - // We don't know whether the expression is potentially evaluated until - // after we perform semantic analysis, so the expression is potentially - // potentially evaluated. EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated); ExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand()); |

