summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaExpr.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2011-12-20 02:08:33 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2011-12-20 02:08:33 +0000
commit764d2fe6668d66d82dcd412463432d0f87420455 (patch)
treecf51ebff7ca8270d59a1006a058fbe42e43e2466 /clang/lib/Sema/SemaExpr.cpp
parent50660440a192a5769e63ff41bff27423c374c98f (diff)
downloadbcm5719-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.cpp19
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()) {
OpenPOWER on IntegriCloud