diff options
-rw-r--r-- | lib/AST/ExprConstant.cpp | 4 | ||||
-rw-r--r-- | test/CodeGenCXX/references.cpp | 13 |
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 }; + } +} |