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/SemaExpr.cpp | |
| 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/SemaExpr.cpp')
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index bc1e0a27b41..62ee9f554d5 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -1199,7 +1199,8 @@ diagnoseUncapturableValueReference(Sema &S, SourceLocation loc, VarDecl *var, DeclContext *DC) { switch (S.ExprEvalContexts.back().Context) { case Sema::Unevaluated: - // The argument will never be evaluated, so don't complain. + case Sema::ConstantEvaluated: + // The argument will never be evaluated at runtime, so don't complain. return CR_NoCapture; case Sema::PotentiallyEvaluated: @@ -9330,7 +9331,7 @@ void Sema::PopExpressionEvaluationContext() { // temporaries that we may have created as part of the evaluation of // the expression in that context: they aren't relevant because they // will never be constructed. - if (Rec.Context == Unevaluated) { + if (Rec.Context == Unevaluated || Rec.Context == ConstantEvaluated) { ExprCleanupObjects.erase(ExprCleanupObjects.begin() + Rec.NumCleanupObjects, ExprCleanupObjects.end()); ExprNeedsCleanups = Rec.ParentNeedsCleanups; @@ -9392,6 +9393,16 @@ void Sema::MarkDeclarationReferenced(SourceLocation Loc, Decl *D) { // We are in an expression that is not potentially evaluated; do nothing. return; + case ConstantEvaluated: + // We are in an expression that will be evaluated during translation; in + // C++11, we need to define any functions which are used in case they're + // constexpr, whereas in C++98, we only need to define static data members + // of class templates. + if (!getLangOptions().CPlusPlus || + (!getLangOptions().CPlusPlus0x && !isa<VarDecl>(D))) + return; + break; + case PotentiallyEvaluated: // We are in a potentially-evaluated expression, so this declaration is // "used"; handle this below. @@ -9663,6 +9674,10 @@ bool Sema::DiagRuntimeBehavior(SourceLocation Loc, const Stmt *Statement, // The argument will never be evaluated, so don't complain. break; + case ConstantEvaluated: + // Relevant diagnostics should be produced by constant evaluation. + break; + case PotentiallyEvaluated: case PotentiallyEvaluatedIfUsed: if (Statement && getCurFunctionOrMethodDecl()) { |

