[cfe-commits] r159189 - in /cfe/trunk: lib/AST/ExprConstant.cpp test/SemaCXX/constant-expression-cxx11.cpp
Richard Smith
richard-llvm at metafoo.co.uk
Tue Jun 26 01:12:11 PDT 2012
Author: rsmith
Date: Tue Jun 26 03:12:11 2012
New Revision: 159189
URL: http://llvm.org/viewvc/llvm-project?rev=159189&view=rev
Log:
Fix lifetime issue for backing APValue of OpaqueValueExpr in recursive
constexpr function evaluation, and corresponding ASan / valgrind issue in
tests, by storing the corresponding value with the relevant stack frame. This
also prevents re-evaluation of the source of the underlying OpaqueValueExpr,
which makes a major performance difference for certain contrived code (see
testcase update).
Modified:
cfe/trunk/lib/AST/ExprConstant.cpp
cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp
Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=159189&r1=159188&r2=159189&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Tue Jun 26 03:12:11 2012
@@ -366,9 +366,6 @@
// Note that we intentionally use std::map here so that references
// to values are stable.
typedef std::map<const OpaqueValueExpr*, APValue> MapTy;
- /// OpaqueValues - Values used as the common expression in a
- /// BinaryConditionalOperator.
- MapTy OpaqueValues;
/// BottomFrame - The frame in which evaluation started. This must be
/// initialized after CurrentCall and CallStackDepth.
@@ -398,12 +395,6 @@
EvaluatingDecl(0), EvaluatingDeclValue(0), HasActiveDiagnostic(false),
CheckingPotentialConstantExpression(false) {}
- const APValue *getOpaqueValue(const OpaqueValueExpr *e) const {
- MapTy::const_iterator i = OpaqueValues.find(e);
- if (i == OpaqueValues.end()) return 0;
- return &i->second;
- }
-
void setEvaluatingDecl(const VarDecl *VD, APValue &Value) {
EvaluatingDecl = VD;
EvaluatingDeclValue = &Value;
@@ -2364,32 +2355,6 @@
bool VisitSizeOfPackExpr(const SizeOfPackExpr *) { return false; }
};
-class OpaqueValueEvaluation {
- EvalInfo &info;
- OpaqueValueExpr *opaqueValue;
-
-public:
- OpaqueValueEvaluation(EvalInfo &info, OpaqueValueExpr *opaqueValue,
- Expr *value)
- : info(info), opaqueValue(opaqueValue) {
-
- // If evaluation fails, fail immediately.
- if (!Evaluate(info.OpaqueValues[opaqueValue], info, value)) {
- this->opaqueValue = 0;
- return;
- }
- }
-
- bool hasError() const { return opaqueValue == 0; }
-
- ~OpaqueValueEvaluation() {
- // FIXME: For a recursive constexpr call, an outer stack frame might have
- // been using this opaque value too, and will now have to re-evaluate the
- // source expression.
- if (opaqueValue) info.OpaqueValues.erase(opaqueValue);
- }
-};
-
} // end anonymous namespace
//===----------------------------------------------------------------------===//
@@ -2532,9 +2497,10 @@
}
RetTy VisitBinaryConditionalOperator(const BinaryConditionalOperator *E) {
- // Cache the value of the common expression.
- OpaqueValueEvaluation opaque(Info, E->getOpaqueValue(), E->getCommon());
- if (opaque.hasError())
+ // Evaluate and cache the common expression. We treat it as a temporary,
+ // even though it's not quite the same thing.
+ if (!Evaluate(Info.CurrentCall->Temporaries[E->getOpaqueValue()],
+ Info, E->getCommon()))
return false;
return HandleConditionalOperator(E);
@@ -2568,8 +2534,8 @@
}
RetTy VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
- const APValue *Value = Info.getOpaqueValue(E);
- if (!Value) {
+ APValue &Value = Info.CurrentCall->Temporaries[E];
+ if (Value.isUninit()) {
const Expr *Source = E->getSourceExpr();
if (!Source)
return Error(E);
@@ -2579,7 +2545,7 @@
}
return StmtVisitorTy::Visit(Source);
}
- return DerivedSuccess(*Value, E);
+ return DerivedSuccess(Value, E);
}
RetTy VisitCallExpr(const CallExpr *E) {
Modified: cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp?rev=159189&r1=159188&r2=159189&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp (original)
+++ cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp Tue Jun 26 03:12:11 2012
@@ -1213,6 +1213,17 @@
constexpr int arr2[] = { 1, 0, 0, 3, 0, 2, 0, 4, 0, 5 };
static_assert(LastNonzero(begin(arr2), end(arr2)) == 5, "");
+
+ constexpr int arr3[] = {
+ 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0,
+ 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0,
+ 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0,
+ 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0,
+ 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0,
+ 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0,
+ 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0,
+ 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+ static_assert(LastNonzero(begin(arr3), end(arr3)) == 2, "");
}
namespace VLASizeof {
More information about the cfe-commits
mailing list