aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/AST/ExprConstant.cpp4
-rw-r--r--test/CodeGenCXX/references.cpp13
2 files changed, 17 insertions, 0 deletions
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index f903035d22..dc614018ec 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -355,6 +355,10 @@ bool LValueExprEvaluator::VisitDeclRefExpr(DeclRefExpr *E) {
} else if (VarDecl* VD = dyn_cast<VarDecl>(E->getDecl())) {
if (!VD->getType()->isReferenceType())
return Success(E);
+ // Reference parameters can refer to anything even if they have an
+ // "initializer" in the form of a default argument.
+ if (isa<ParmVarDecl>(VD))
+ return false;
// FIXME: Check whether VD might be overridden!
if (const Expr *Init = VD->getAnyInitializer())
return Visit(const_cast<Expr *>(Init));
diff --git a/test/CodeGenCXX/references.cpp b/test/CodeGenCXX/references.cpp
index 5a5947dd81..3ae1e474f8 100644
--- a/test/CodeGenCXX/references.cpp
+++ b/test/CodeGenCXX/references.cpp
@@ -155,3 +155,16 @@ void f0(s1 a) { s1 b = a; }
// CHECK: load
// CHECK: ret
const int &f2() { return 0; }
+
+// Don't constant fold const reference parameters with default arguments to
+// their default arguments.
+namespace N1 {
+ const int foo = 1;
+ // CHECK: @_ZN2N14test
+ int test(const int& arg = foo) {
+ // Ensure this array is on the stack where we can set values instead of
+ // being a global constant.
+ // CHECK: %args_array = alloca
+ const int* const args_array[] = { &arg };
+ }
+}